diff options
author | Jack Bates <jack@nottheoilrig.com> | 2016-10-13 19:45:26 +0300 |
---|---|---|
committer | Joseph Frazier <1212jtraceur@gmail.com> | 2016-10-13 19:45:26 +0300 |
commit | 1072de214598e191be7e41c40d8c5b245cc2a249 (patch) | |
tree | 3dd19b75f23eb8e497f57444f6a52032028d7256 /lib | |
parent | ea87d783a7116bd8d961b2125b41dc89b8d02b50 (diff) |
Cross-origin HTTP redirect workaround (#909)
Diffstat (limited to 'lib')
-rw-r--r-- | lib/webconn.js | 52 |
1 files changed, 46 insertions, 6 deletions
diff --git a/lib/webconn.js b/lib/webconn.js index c52dad6..133f738 100644 --- a/lib/webconn.js +++ b/lib/webconn.js @@ -124,12 +124,7 @@ WebConn.prototype.httpRequest = function (pieceIndex, offset, length, cb) { range: 'bytes=' + start + '-' + end } } - get.concat(opts, function (err, res, data) { - if (hasError) return - if (err) { - hasError = true - return cb(err) - } + function onResponse (res, data) { if (res.statusCode < 200 || res.statusCode >= 300) { hasError = true return cb(new Error('Unexpected HTTP status code ' + res.statusCode)) @@ -147,6 +142,51 @@ WebConn.prototype.httpRequest = function (pieceIndex, offset, length, cb) { cb(null, ret) } } + } + get.concat(opts, function (err, res, data) { + if (hasError) return + if (err) { + // Browsers allow HTTP redirects for simple cross-origin + // requests but not for requests that require preflight. + // Use a simple request to unravel any redirects and get the + // final URL. Retry the original request with the new URL if + // it's different. + // + // This test is imperfect but it's simple and good for common + // cases. It catches all cross-origin cases but matches a few + // same-origin cases too. + if (typeof window === 'undefined' || url.startsWith(window.location.origin + '/')) { + hasError = true + return cb(err) + } + + return get.head(url, function (errHead, res) { + if (hasError) return + if (errHead) { + hasError = true + return cb(errHead) + } + if (res.statusCode < 200 || res.statusCode >= 300) { + hasError = true + return cb(new Error('Unexpected HTTP status code ' + res.statusCode)) + } + if (res.url === url) { + hasError = true + return cb(err) + } + + opts.url = res.url + get.concat(opts, function (err, res, data) { + if (hasError) return + if (err) { + hasError = true + return cb(err) + } + onResponse(res, data) + }) + }) + } + onResponse(res, data) }) }) } |