From d1901535fe1d36c3621af819e73a97e0afafec49 Mon Sep 17 00:00:00 2001 From: Francisco Baio Dias Date: Sat, 27 Feb 2016 20:22:17 +0000 Subject: [PATCH 1/2] Add /api/v0/config/replace endpoint --- package.json | 2 + src/http-api/resources/config.js | 41 ++++++++++++++ src/http-api/routes/config.js | 11 ++++ tests/badconfig | 3 ++ tests/otherconfig | 87 ++++++++++++++++++++++++++++++ tests/test-http-api/test-config.js | 80 +++++++++++++++++++++++++++ 6 files changed, 224 insertions(+) create mode 100644 tests/badconfig create mode 100644 tests/otherconfig diff --git a/package.json b/package.json index 2af6d922b9..4006aa72fa 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "buffer-loader": "0.0.1", "chai": "^3.4.1", "expose-loader": "^0.7.1", + "form-data": "^1.0.0-rc3", "fs-blob-store": "^5.2.1", "idb-plus-blob-store": "^1.0.0", "istanbul": "^0.4.1", @@ -61,6 +62,7 @@ "pre-commit": "^1.1.2", "rimraf": "^2.4.4", "standard": "^5.4.1", + "stream-to-promise": "^1.1.0", "transform-loader": "^0.2.3", "webpack": "^2.0.7-beta" }, diff --git a/src/http-api/resources/config.js b/src/http-api/resources/config.js index e3e0691f2d..40efb46c51 100644 --- a/src/http-api/resources/config.js +++ b/src/http-api/resources/config.js @@ -1,3 +1,5 @@ +'use strict' + const ipfs = require('./../index.js').ipfs const debug = require('debug') const get = require('lodash.get') @@ -124,3 +126,42 @@ exports.show = (request, reply) => { return reply(config) }) } + +exports.replace = { + // pre request handler that parses the args and returns `config` which is assigned to `request.pre.args` + parseArgs: (request, reply) => { + if (!request.payload || !request.payload.file) { + return reply({ + Message: "Argument 'file' is required", + Code: 1123 + + }).code(400).takeover() + } + + try { + return reply({ + config: JSON.parse(request.payload.file.toString()) + }) + } catch (err) { + return reply({ + Message: 'Failed to decode file as config: ' + err, + Code: 0 + }).code(500).takeover() + } + }, + + // main route handler which is called after the above `parseArgs`, but only if the args were valid + handler: (request, reply) => { + return ipfs.config.replace(request.pre.args.config, (err) => { + if (err) { + log.error(err) + return reply({ + Message: 'Failed to save config: ' + err, + Code: 0 + }).code(500) + } + + return reply() + }) + } +} diff --git a/src/http-api/routes/config.js b/src/http-api/routes/config.js index cd2314a0ae..0b6c246d52 100644 --- a/src/http-api/routes/config.js +++ b/src/http-api/routes/config.js @@ -17,3 +17,14 @@ api.route({ path: '/api/v0/config/show', handler: resources.config.show }) + +api.route({ + method: '*', + path: '/api/v0/config/replace', + config: { + pre: [ + { method: resources.config.replace.parseArgs, assign: 'args' } + ], + handler: resources.config.replace.handler + } +}) diff --git a/tests/badconfig b/tests/badconfig new file mode 100644 index 0000000000..b55c646210 --- /dev/null +++ b/tests/badconfig @@ -0,0 +1,3 @@ +{ + bad config +} diff --git a/tests/otherconfig b/tests/otherconfig new file mode 100644 index 0000000000..42dc118c7d --- /dev/null +++ b/tests/otherconfig @@ -0,0 +1,87 @@ +{ + "API": { + "HTTPHeaders": { + "Access-Control-Allow-Origin": [ + "http://example.com" + ] + } + }, + "Addresses": { + "API": "/ip4/127.0.0.1/tcp/5001", + "Gateway": "/ip4/127.0.0.1/tcp/8080", + "Swarm": [ + "/ip4/0.0.0.0/tcp/4001", + "/ip6/::/tcp/4001" + ] + }, + "Bootstrap": [ + "/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", + "/ip4/104.236.176.52/tcp/4001/ipfs/QmSoLnSGccFuZQJzRadHn95W2CrSFmZuTdDWP8HXaHca9z", + "/ip4/104.236.179.241/tcp/4001/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM", + "/ip4/162.243.248.213/tcp/4001/ipfs/QmSoLueR4xBeUbY9WZ9xGUUxunbKWcrNFTDAadQJmocnWm", + "/ip4/128.199.219.111/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu", + "/ip4/104.236.76.40/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64", + "/ip4/178.62.158.247/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd", + "/ip4/178.62.61.185/tcp/4001/ipfs/QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3", + "/ip4/104.236.151.122/tcp/4001/ipfs/QmSoLju6m7xTh3DuokvT3886QRYqxAzb1kShaanJgW36yx" + ], + "Datastore": { + "GCPeriod": "", + "NoSync": false, + "Params": null, + "Path": "", + "StorageGCWatermark": 0, + "StorageMax": "", + "Type": "" + }, + "Discovery": { + "MDNS": { + "Enabled": true, + "Interval": 10 + } + }, + "Gateway": { + "HTTPHeaders": null, + "RootRedirect": "", + "Writable": false + }, + "Identity": { + "PeerID": "QmWTNDWjxEaLoaQSuotpM1gxvH9xixqFMCGt2ZPDLkL3rK", + "PrivKey": "CAASpwkwggSjAgEAAoIBAQCv0SnHZQhxaXyjX4RnuaHJB1wtlfW02aGMArfDuRIub1mjCgWoeszaaui5H7E8RPQWTfILiOKKd0JnKxdmDO3K0L87KPXqux0GnFGlz8ggxH/wyA7ej7+r//L0Y44H6PoPaP9zTO37zIBEjs/ssL0ZV5dmHiFCk20roGskcdJAgJyrScojLZGjEEK2BuH4+WZkeqJ1tyl1ukWseRKED3ROppY9G4fs+PbfNlybWuAZpe8QAs07zlX06py8I09lP0hcj8MwrXM8BqOPTSaJSldWIhSprziqwYJD6YDKZcCFEWvIO1a3yYS6Y0UuFohwzr8v8Wah67p/xxiVhFFDUd4fAgMBAAECggEAdZSnoS8jX12Rulzl2sydsyjV77KreQBW9qDWrvF1hFJ5mvzX3d4KZEQ9UZktWcYviz8jka1A/CNX6FE8O8aHvSyvx2vUUuBCQCqIvCBike94NNpGf3eZUvlATUrLMOURXv70X/Lh8ZTJb5Am4/8q5+jZWrTpv3GDADsvjFcGqpV77i3RQU9rVU1DkrVoqPGiEwIGOAIHeIgPX9n0ckhzHnMEHaaOdFnXy2YVl/iBEjxE2EAqQ+sUZX7odefew+kzu1gdWSxmeQ5U4dSmpC7UKYV2uUNE7OgoKadQ/EdKjwVTW664M76jUGj0yZcPOa1BKR6MoB3JKBJMvZ4/22QCgQKBgQDmrrKLVzhMb1upjOF8wAWrO/SJ/VSAMX5281v8uwxF7l2Pp0scB4FPx9KUmxeQmh380cp9vfHHH2HfSqXim5Qtn8VXI7mHdG4wNW3BmfktfS46+6juKr7clzXg21bWEZGa+Ed4hqe4xmbSH9ErsK9cQZzM7i4isKiZ6UcoXA/fwQKBgQDDHPTjvhID8AYP0YJ0vVh6+Bc0gxuZJfUNNxf6ekolQNTRbeZECGrguk9ohpFNt91Gda3X86EVkXZ1U7kOcnbWI5LXj+CtaHdZxdyQhTzwuLsHXmbW9eV4t+zPH+pmSyaxe1XWdLTDvZIma5F4Vqgm0f4BRkqwiMrQSDa/4us13wKBgGSqQaHKyveX9MEViGS/CvpBbKI22YQjlRNleXPdUCrILS3+DCnMIKLnCT7uOydQCdwE1L9wfyysxjIBykgMKmqKeTxgi5rPtTH2btH4ViOCqAT3Qy3Dm4x5s/pO3SMHganFxLKU2GYqtj3lwoq1TKEOxNUs7xcWTkzz3qh/HDJBAoGANBdSBk+jjauSYrzDwJkgu0vrHhj20E+C+jFAVJ47l3CUoQlfVcCNkEwNkVGED6TMDdizPhmMYy6/2pksqf/DXG6I8MY37PQcETqzJV59I6OeQ1xfxnpF9pHcRnw133Om8/GCvEvSSwQctec4IlG4eQzNbNewbytGQo9VFqvlsi8CgYEA5UEbCke1KKpzzuDxPWDgscbXQRGsXoWYWKIwiH7PSeEBCmcXm5aU/pkcBO/qudhOkTatgXFRARyq6loWXWFH703kgO+Voc2Cuh5ociWT65xquVyPDzO54PMGcwumefofLevvE+enNWTuuPljYFxeasD9Gyv1l7/ZDamcSM0n+uw=" + }, + "Ipns": { + "RecordLifetime": "", + "RepublishPeriod": "", + "ResolveCacheSize": 128 + }, + "Mounts": { + "FuseAllowOther": false, + "IPFS": "/ipfs", + "IPNS": "/ipns" + }, + "SupernodeRouting": { + "Servers": [ + "/ip4/104.236.176.52/tcp/4002/ipfs/QmXdb7tWTxdFEQEFgWBqkuYSrZd3mXrC7HxkD4krGNYx2U", + "/ip4/104.236.179.241/tcp/4002/ipfs/QmVRqViDByUxjUMoPnjurjKvZhaEMFDtK35FJXHAM4Lkj6", + "/ip4/104.236.151.122/tcp/4002/ipfs/QmSZwGx8Tn8tmcM4PtDJaMeUQNRhNFdBLVGPzRiNaRJtFH", + "/ip4/162.243.248.213/tcp/4002/ipfs/QmbHVEEepCi7rn7VL7Exxpd2Ci9NNB6ifvqwhsrbRMgQFP", + "/ip4/128.199.219.111/tcp/4002/ipfs/Qmb3brdCYmKG1ycwqCbo6LUwWxTuo3FisnJV2yir7oN92R", + "/ip4/104.236.76.40/tcp/4002/ipfs/QmdRBCV8Cz2dGhoKLkD3YjPwVFECmqADQkx5ZteF2c6Fy4", + "/ip4/178.62.158.247/tcp/4002/ipfs/QmUdiMPci7YoEUBkyFZAh2pAbjqcPr7LezyiPD2artLw3v", + "/ip4/178.62.61.185/tcp/4002/ipfs/QmVw6fGNqBixZE4bewRLT2VXX7fAHUHs8JyidDiJ1P7RUN" + ] + }, + "Swarm": { + "AddrFilters": null + }, + "Tour": { + "Last": "" + }, + "Version": { + "AutoUpdate": "minor", + "Check": "error", + "CheckDate": "0001-01-01T00:00:00Z", + "CheckPeriod": "172800000000000", + "Current": "0.4.0-dev" + } +} diff --git a/tests/test-http-api/test-config.js b/tests/test-http-api/test-config.js index 4e1f0ee25c..2860cb3d4b 100644 --- a/tests/test-http-api/test-config.js +++ b/tests/test-http-api/test-config.js @@ -1,12 +1,17 @@ /* eslint-env mocha */ +'use strict' const expect = require('chai').expect const fs = require('fs') const APIctl = require('ipfs-api') +const FormData = require('form-data') +const streamToPromise = require('stream-to-promise') describe('config', () => { const configPath = process.cwd() + '/tests/repo-tests-run/config' + const originalConfigPath = process.cwd() + '/tests/repo-example/config' const updatedConfig = () => JSON.parse(fs.readFileSync(configPath, 'utf8')) + const restoreConfig = () => fs.writeFileSync(configPath, fs.readFileSync(originalConfigPath, 'utf8'), 'utf8') describe('api', () => { var api @@ -143,6 +148,69 @@ describe('config', () => { done() }) }) + + describe('/config/replace', () => { + it('returns 400 if no config is provided', (done) => { + const form = new FormData() + const headers = form.getHeaders() + + streamToPromise(form).then(payload => { + api.inject({ + method: 'POST', + url: '/api/v0/config/replace', + headers: headers, + payload: payload + }, res => { + expect(res.statusCode).to.equal(400) + done() + }) + }) + }) + + it('returns 500 if the config is invalid', (done) => { + const form = new FormData() + const filePath = 'tests/badconfig' + form.append('file', fs.createReadStream(filePath)) + const headers = form.getHeaders() + + streamToPromise(form).then(payload => { + api.inject({ + method: 'POST', + url: '/api/v0/config/replace', + headers: headers, + payload: payload + }, res => { + expect(res.statusCode).to.equal(500) + done() + }) + }) + }) + + it('updates value', (done) => { + const form = new FormData() + const filePath = 'tests/otherconfig' + form.append('file', fs.createReadStream(filePath)) + const headers = form.getHeaders() + const expectedConfig = JSON.parse(fs.readFileSync(filePath, 'utf8')) + + streamToPromise(form).then(payload => { + api.inject({ + method: 'POST', + url: '/api/v0/config/replace', + headers: headers, + payload: payload + }, res => { + expect(res.statusCode).to.equal(200) + expect(updatedConfig()).to.deep.equal(expectedConfig) + done() + }) + }) + }) + + after(() => { + restoreConfig() + }) + }) }) describe('using js-ipfs-api', () => { @@ -240,5 +308,17 @@ describe('config', () => { done() }) }) + + describe('ipfs.config.replace', () => { + it.skip('updates value', (done) => { + const file = 'tests/otherconfig' + ctl.config.replace(file, (err, res) => { + console.log(err, res) + expect(err).not.to.exist + expect(res).to.deep.equal(updatedConfig()) + done() + }) + }) + }) }) }) From 6b0838b9ebd995247792af8b72a9ebe4233cae9a Mon Sep 17 00:00:00 2001 From: Francisco Baio Dias Date: Thu, 3 Mar 2016 17:50:55 +0000 Subject: [PATCH 2/2] Use ipfs-multipart to parse the payload --- package.json | 1 + src/http-api/resources/config.js | 40 ++++++++--- src/http-api/routes/config.js | 4 ++ tests/otherconfig | 109 ++++++++++++----------------- tests/test-http-api/test-config.js | 20 ++++-- 5 files changed, 96 insertions(+), 78 deletions(-) diff --git a/package.json b/package.json index 4006aa72fa..c2d48f9342 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "ipfs-api": "^2.13.1", "ipfs-blocks": "^0.1.0", "ipfs-merkle-dag": "^0.2.1", + "ipfs-multipart": "0.0.1", "ipfs-repo": "^0.5.0", "joi": "^8.0.2", "lodash.get": "^4.0.0", diff --git a/src/http-api/resources/config.js b/src/http-api/resources/config.js index 40efb46c51..4fd922e688 100644 --- a/src/http-api/resources/config.js +++ b/src/http-api/resources/config.js @@ -6,6 +6,7 @@ const get = require('lodash.get') const set = require('lodash.set') const log = debug('http-api:config') log.error = debug('http-api:config:error') +const multipart = require('ipfs-multipart') exports = module.exports @@ -130,7 +131,7 @@ exports.show = (request, reply) => { exports.replace = { // pre request handler that parses the args and returns `config` which is assigned to `request.pre.args` parseArgs: (request, reply) => { - if (!request.payload || !request.payload.file) { + if (!request.payload) { return reply({ Message: "Argument 'file' is required", Code: 1123 @@ -138,16 +139,35 @@ exports.replace = { }).code(400).takeover() } - try { - return reply({ - config: JSON.parse(request.payload.file.toString()) + const parser = multipart.reqParser(request.payload) + let file + + parser.on('file', (fileName, fileStream) => { + fileStream.on('data', (data) => { + file = data }) - } catch (err) { - return reply({ - Message: 'Failed to decode file as config: ' + err, - Code: 0 - }).code(500).takeover() - } + }) + + parser.on('end', () => { + if (!file) { + return reply({ + Message: "Argument 'file' is required", + Code: 1123 + + }).code(400).takeover() + } + + try { + return reply({ + config: JSON.parse(file.toString()) + }) + } catch (err) { + return reply({ + Message: 'Failed to decode file as config: ' + err, + Code: 0 + }).code(500).takeover() + } + }) }, // main route handler which is called after the above `parseArgs`, but only if the args were valid diff --git a/src/http-api/routes/config.js b/src/http-api/routes/config.js index 0b6c246d52..8ea51c2251 100644 --- a/src/http-api/routes/config.js +++ b/src/http-api/routes/config.js @@ -22,6 +22,10 @@ api.route({ method: '*', path: '/api/v0/config/replace', config: { + payload: { + parse: false, + output: 'stream' + }, pre: [ { method: resources.config.replace.parseArgs, assign: 'args' } ], diff --git a/tests/otherconfig b/tests/otherconfig index 42dc118c7d..40abcaf546 100644 --- a/tests/otherconfig +++ b/tests/otherconfig @@ -1,38 +1,33 @@ { - "API": { - "HTTPHeaders": { - "Access-Control-Allow-Origin": [ - "http://example.com" - ] - } - }, - "Addresses": { - "API": "/ip4/127.0.0.1/tcp/5001", - "Gateway": "/ip4/127.0.0.1/tcp/8080", - "Swarm": [ - "/ip4/0.0.0.0/tcp/4001", - "/ip6/::/tcp/4001" - ] + "Identity": { + "PeerID": "QmQ2zigjQikYnyYUSXZydNXrDRhBut2mubwJBaLXobMt3A", + "PrivKey": "CAASpgkwggSiAgEAAoIBAQC2SKo/HMFZeBml1AF3XijzrxrfQXdJzjePBZAbdxqKR1Mc6juRHXij6HXYPjlAk01BhF1S3Ll4Lwi0cAHhggf457sMg55UWyeGKeUv0ucgvCpBwlR5cQ020i0MgzjPWOLWq1rtvSbNcAi2ZEVn6+Q2EcHo3wUvWRtLeKz+DZSZfw2PEDC+DGPJPl7f8g7zl56YymmmzH9liZLNrzg/qidokUv5u1pdGrcpLuPNeTODk0cqKB+OUbuKj9GShYECCEjaybJDl9276oalL9ghBtSeEv20kugatTvYy590wFlJkkvyl+nPxIH0EEYMKK9XRWlu9XYnoSfboiwcv8M3SlsjAgMBAAECggEAZtju/bcKvKFPz0mkHiaJcpycy9STKphorpCT83srBVQi59CdFU6Mj+aL/xt0kCPMVigJw8P3/YCEJ9J+rS8BsoWE+xWUEsJvtXoT7vzPHaAtM3ci1HZd302Mz1+GgS8Epdx+7F5p80XAFLDUnELzOzKftvWGZmWfSeDnslwVONkL/1VAzwKy7Ce6hk4SxRE7l2NE2OklSHOzCGU1f78ZzVYKSnS5Ag9YrGjOAmTOXDbKNKN/qIorAQ1bovzGoCwx3iGIatQKFOxyVCyO1PsJYT7JO+kZbhBWRRE+L7l+ppPER9bdLFxs1t5CrKc078h+wuUr05S1P1JjXk68pk3+kQKBgQDeK8AR11373Mzib6uzpjGzgNRMzdYNuExWjxyxAzz53NAR7zrPHvXvfIqjDScLJ4NcRO2TddhXAfZoOPVH5k4PJHKLBPKuXZpWlookCAyENY7+Pd55S8r+a+MusrMagYNljb5WbVTgN8cgdpim9lbbIFlpN6SZaVjLQL3J8TWH6wKBgQDSChzItkqWX11CNstJ9zJyUE20I7LrpyBJNgG1gtvz3ZMUQCn3PxxHtQzN9n1P0mSSYs+jBKPuoSyYLt1wwe10/lpgL4rkKWU3/m1Myt0tveJ9WcqHh6tzcAbb/fXpUFT/o4SWDimWkPkuCb+8j//2yiXk0a/T2f36zKMuZvujqQKBgC6B7BAQDG2H2B/ijofp12ejJU36nL98gAZyqOfpLJ+FeMz4TlBDQ+phIMhnHXA5UkdDapQ+zA3SrFk+6yGk9Vw4Hf46B+82SvOrSbmnMa+PYqKYIvUzR4gg34rL/7AhwnbEyD5hXq4dHwMNsIDq+l2elPjwm/U9V0gdAl2+r50HAoGALtsKqMvhv8HucAMBPrLikhXP/8um8mMKFMrzfqZ+otxfHzlhI0L08Bo3jQrb0Z7ByNY6M8epOmbCKADsbWcVre/AAY0ZkuSZK/CaOXNX/AhMKmKJh8qAOPRY02LIJRBCpfS4czEdnfUhYV/TYiFNnKRj57PPYZdTzUsxa/yVTmECgYBr7slQEjb5Onn5mZnGDh+72BxLNdgwBkhO0OCdpdISqk0F0Pxby22DFOKXZEpiyI9XYP1C8wPiJsShGm2yEwBPWXnrrZNWczaVuCbXHrZkWQogBDG3HGXNdU4MAWCyiYlyinIBpPpoAJZSzpGLmWbMWh28+RJS6AQX6KHrK1o2uw==" }, - "Bootstrap": [ - "/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", - "/ip4/104.236.176.52/tcp/4001/ipfs/QmSoLnSGccFuZQJzRadHn95W2CrSFmZuTdDWP8HXaHca9z", - "/ip4/104.236.179.241/tcp/4001/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM", - "/ip4/162.243.248.213/tcp/4001/ipfs/QmSoLueR4xBeUbY9WZ9xGUUxunbKWcrNFTDAadQJmocnWm", - "/ip4/128.199.219.111/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu", - "/ip4/104.236.76.40/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64", - "/ip4/178.62.158.247/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd", - "/ip4/178.62.61.185/tcp/4001/ipfs/QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3", - "/ip4/104.236.151.122/tcp/4001/ipfs/QmSoLju6m7xTh3DuokvT3886QRYqxAzb1kShaanJgW36yx" - ], "Datastore": { - "GCPeriod": "", - "NoSync": false, - "Params": null, + "Type": "", "Path": "", - "StorageGCWatermark": 0, "StorageMax": "", - "Type": "" + "StorageGCWatermark": 0, + "GCPeriod": "", + "Params": null, + "NoSync": false + }, + "Addresses": { + "Swarm": ["/ip4/0.0.0.0/tcp/4001", "/ip6/::/tcp/4001"], + "API": "/ip4/127.0.0.1/tcp/6001", + "Gateway": "/ip4/127.0.0.1/tcp/9090" + }, + "Mounts": { + "IPFS": "/ipfs", + "IPNS": "/ipns", + "FuseAllowOther": false + }, + "Version": { + "Current": "0.4.0-dev", + "Check": "error", + "CheckDate": "0001-01-01T00:00:00Z", + "CheckPeriod": "172800000000000", + "AutoUpdate": "minor" }, "Discovery": { "MDNS": { @@ -40,48 +35,36 @@ "Interval": 10 } }, - "Gateway": { - "HTTPHeaders": null, - "RootRedirect": "", - "Writable": false - }, - "Identity": { - "PeerID": "QmWTNDWjxEaLoaQSuotpM1gxvH9xixqFMCGt2ZPDLkL3rK", - "PrivKey": "CAASpwkwggSjAgEAAoIBAQCv0SnHZQhxaXyjX4RnuaHJB1wtlfW02aGMArfDuRIub1mjCgWoeszaaui5H7E8RPQWTfILiOKKd0JnKxdmDO3K0L87KPXqux0GnFGlz8ggxH/wyA7ej7+r//L0Y44H6PoPaP9zTO37zIBEjs/ssL0ZV5dmHiFCk20roGskcdJAgJyrScojLZGjEEK2BuH4+WZkeqJ1tyl1ukWseRKED3ROppY9G4fs+PbfNlybWuAZpe8QAs07zlX06py8I09lP0hcj8MwrXM8BqOPTSaJSldWIhSprziqwYJD6YDKZcCFEWvIO1a3yYS6Y0UuFohwzr8v8Wah67p/xxiVhFFDUd4fAgMBAAECggEAdZSnoS8jX12Rulzl2sydsyjV77KreQBW9qDWrvF1hFJ5mvzX3d4KZEQ9UZktWcYviz8jka1A/CNX6FE8O8aHvSyvx2vUUuBCQCqIvCBike94NNpGf3eZUvlATUrLMOURXv70X/Lh8ZTJb5Am4/8q5+jZWrTpv3GDADsvjFcGqpV77i3RQU9rVU1DkrVoqPGiEwIGOAIHeIgPX9n0ckhzHnMEHaaOdFnXy2YVl/iBEjxE2EAqQ+sUZX7odefew+kzu1gdWSxmeQ5U4dSmpC7UKYV2uUNE7OgoKadQ/EdKjwVTW664M76jUGj0yZcPOa1BKR6MoB3JKBJMvZ4/22QCgQKBgQDmrrKLVzhMb1upjOF8wAWrO/SJ/VSAMX5281v8uwxF7l2Pp0scB4FPx9KUmxeQmh380cp9vfHHH2HfSqXim5Qtn8VXI7mHdG4wNW3BmfktfS46+6juKr7clzXg21bWEZGa+Ed4hqe4xmbSH9ErsK9cQZzM7i4isKiZ6UcoXA/fwQKBgQDDHPTjvhID8AYP0YJ0vVh6+Bc0gxuZJfUNNxf6ekolQNTRbeZECGrguk9ohpFNt91Gda3X86EVkXZ1U7kOcnbWI5LXj+CtaHdZxdyQhTzwuLsHXmbW9eV4t+zPH+pmSyaxe1XWdLTDvZIma5F4Vqgm0f4BRkqwiMrQSDa/4us13wKBgGSqQaHKyveX9MEViGS/CvpBbKI22YQjlRNleXPdUCrILS3+DCnMIKLnCT7uOydQCdwE1L9wfyysxjIBykgMKmqKeTxgi5rPtTH2btH4ViOCqAT3Qy3Dm4x5s/pO3SMHganFxLKU2GYqtj3lwoq1TKEOxNUs7xcWTkzz3qh/HDJBAoGANBdSBk+jjauSYrzDwJkgu0vrHhj20E+C+jFAVJ47l3CUoQlfVcCNkEwNkVGED6TMDdizPhmMYy6/2pksqf/DXG6I8MY37PQcETqzJV59I6OeQ1xfxnpF9pHcRnw133Om8/GCvEvSSwQctec4IlG4eQzNbNewbytGQo9VFqvlsi8CgYEA5UEbCke1KKpzzuDxPWDgscbXQRGsXoWYWKIwiH7PSeEBCmcXm5aU/pkcBO/qudhOkTatgXFRARyq6loWXWFH703kgO+Voc2Cuh5ociWT65xquVyPDzO54PMGcwumefofLevvE+enNWTuuPljYFxeasD9Gyv1l7/ZDamcSM0n+uw=" - }, "Ipns": { - "RecordLifetime": "", "RepublishPeriod": "", + "RecordLifetime": "", "ResolveCacheSize": 128 }, - "Mounts": { - "FuseAllowOther": false, - "IPFS": "/ipfs", - "IPNS": "/ipns" + "Bootstrap": ["/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", "/ip4/104.236.176.52/tcp/4001/ipfs/QmSoLnSGccFuZQJzRadHn95W2CrSFmZuTdDWP8HXaHca9z", "/ip4/104.236.179.241/tcp/4001/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM", "/ip4/162.243.248.213/tcp/4001/ipfs/QmSoLueR4xBeUbY9WZ9xGUUxunbKWcrNFTDAadQJmocnWm", "/ip4/128.199.219.111/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu", "/ip4/104.236.76.40/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64", "/ip4/178.62.158.247/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd", "/ip4/178.62.61.185/tcp/4001/ipfs/QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3", "/ip4/104.236.151.122/tcp/4001/ipfs/QmSoLju6m7xTh3DuokvT3886QRYqxAzb1kShaanJgW36yx"], + "Tour": { + "Last": "" + }, + "Gateway": { + "HTTPHeaders": null, + "RootRedirect": "", + "Writable": false }, "SupernodeRouting": { - "Servers": [ - "/ip4/104.236.176.52/tcp/4002/ipfs/QmXdb7tWTxdFEQEFgWBqkuYSrZd3mXrC7HxkD4krGNYx2U", - "/ip4/104.236.179.241/tcp/4002/ipfs/QmVRqViDByUxjUMoPnjurjKvZhaEMFDtK35FJXHAM4Lkj6", - "/ip4/104.236.151.122/tcp/4002/ipfs/QmSZwGx8Tn8tmcM4PtDJaMeUQNRhNFdBLVGPzRiNaRJtFH", - "/ip4/162.243.248.213/tcp/4002/ipfs/QmbHVEEepCi7rn7VL7Exxpd2Ci9NNB6ifvqwhsrbRMgQFP", - "/ip4/128.199.219.111/tcp/4002/ipfs/Qmb3brdCYmKG1ycwqCbo6LUwWxTuo3FisnJV2yir7oN92R", - "/ip4/104.236.76.40/tcp/4002/ipfs/QmdRBCV8Cz2dGhoKLkD3YjPwVFECmqADQkx5ZteF2c6Fy4", - "/ip4/178.62.158.247/tcp/4002/ipfs/QmUdiMPci7YoEUBkyFZAh2pAbjqcPr7LezyiPD2artLw3v", - "/ip4/178.62.61.185/tcp/4002/ipfs/QmVw6fGNqBixZE4bewRLT2VXX7fAHUHs8JyidDiJ1P7RUN" - ] + "Servers": ["/ip4/104.236.176.52/tcp/4002/ipfs/QmXdb7tWTxdFEQEFgWBqkuYSrZd3mXrC7HxkD4krGNYx2U", "/ip4/104.236.179.241/tcp/4002/ipfs/QmVRqViDByUxjUMoPnjurjKvZhaEMFDtK35FJXHAM4Lkj6", "/ip4/104.236.151.122/tcp/4002/ipfs/QmSZwGx8Tn8tmcM4PtDJaMeUQNRhNFdBLVGPzRiNaRJtFH", "/ip4/162.243.248.213/tcp/4002/ipfs/QmbHVEEepCi7rn7VL7Exxpd2Ci9NNB6ifvqwhsrbRMgQFP", "/ip4/128.199.219.111/tcp/4002/ipfs/Qmb3brdCYmKG1ycwqCbo6LUwWxTuo3FisnJV2yir7oN92R", "/ip4/104.236.76.40/tcp/4002/ipfs/QmdRBCV8Cz2dGhoKLkD3YjPwVFECmqADQkx5ZteF2c6Fy4", "/ip4/178.62.158.247/tcp/4002/ipfs/QmUdiMPci7YoEUBkyFZAh2pAbjqcPr7LezyiPD2artLw3v", "/ip4/178.62.61.185/tcp/4002/ipfs/QmVw6fGNqBixZE4bewRLT2VXX7fAHUHs8JyidDiJ1P7RUN"] + }, + "API": { + "HTTPHeaders": { + "Access-Control-Allow-Origin": [ + "http://example.com" + ] + } }, "Swarm": { "AddrFilters": null }, - "Tour": { - "Last": "" - }, - "Version": { - "AutoUpdate": "minor", - "Check": "error", - "CheckDate": "0001-01-01T00:00:00Z", - "CheckPeriod": "172800000000000", - "Current": "0.4.0-dev" + "Log": { + "MaxSizeMB": 250, + "MaxBackups": 1, + "MaxAgeDays": 0 } } diff --git a/tests/test-http-api/test-config.js b/tests/test-http-api/test-config.js index 2860cb3d4b..fe46553bd0 100644 --- a/tests/test-http-api/test-config.js +++ b/tests/test-http-api/test-config.js @@ -310,12 +310,22 @@ describe('config', () => { }) describe('ipfs.config.replace', () => { - it.skip('updates value', (done) => { - const file = 'tests/otherconfig' - ctl.config.replace(file, (err, res) => { - console.log(err, res) + it('returns error if the config is invalid', (done) => { + const filePath = 'tests/badconfig' + + ctl.config.replace(filePath, (err) => { + expect(err).to.exist + done() + }) + }) + + it('updates value', (done) => { + const filePath = 'tests/otherconfig' + const expectedConfig = JSON.parse(fs.readFileSync(filePath, 'utf8')) + + ctl.config.replace(filePath, (err) => { expect(err).not.to.exist - expect(res).to.deep.equal(updatedConfig()) + expect(expectedConfig).to.deep.equal(updatedConfig()) done() }) })