diff --git a/src/util/url-add.js b/src/util/url-add.js index 7a394e42d..3ecc691d6 100644 --- a/src/util/url-add.js +++ b/src/util/url-add.js @@ -25,28 +25,41 @@ module.exports = (arg) => { opts = {} } - if (typeof url !== 'string' || - !url.startsWith('http')) { + if (!validUrl(url)) { return callback(new Error('"url" param must be an http(s) url')) } callback = once(callback) - request(parseUrl(url).protocol)(url, (res) => { - res.once('error', callback) - if (res.statusCode >= 400) { - return callback(new Error(`Failed to download with ${res.statusCode}`)) - } + requestWithRedirect(url, opts, send, callback) + }) +} + +const validUrl = (url) => typeof url === 'string' && url.startsWith('http') + +const requestWithRedirect = (url, opts, send, callback) => { + request(parseUrl(url).protocol)(url, (res) => { + res.once('error', callback) + if (res.statusCode >= 400) { + return callback(new Error(`Failed to download with ${res.statusCode}`)) + } + const redirection = res.headers.location + + if (res.statusCode >= 300 && res.statusCode < 400 && redirection) { + if (!validUrl(redirection)) { + return callback(new Error('redirection url must be an http(s) url')) + } + requestWithRedirect(redirection, opts, send, callback) + } else { const params = { path: 'add', qs: opts, files: res } - // Transform the response stream to DAGNode values const transform = (res, callback) => DAGNodeStream.streamToValue(send, res, callback) send.andTransform(params, transform, callback) - }).end() - }) + } + }).end() } diff --git a/test/util.spec.js b/test/util.spec.js index dadd2b4ee..20743057f 100644 --- a/test/util.spec.js +++ b/test/util.spec.js @@ -107,6 +107,14 @@ describe('.util', () => { done() }) }) + + it('.urlAdd http with redirection', (done) => { + ipfs.util.addFromURL('http://covers.openlibrary.org/book/id/969165.jpg', (err, result) => { + expect(err).to.not.exist() + expect(result[0].hash).to.equal('QmaL9zy7YUfvWmtD5ZXp42buP7P4xmZJWFkm78p8FJqgjg') + done() + }) + }) }) describe('Promise API', () => {})