Skip to content

Commit

Permalink
Don't change relative location header on manual redirect
Browse files Browse the repository at this point in the history
  • Loading branch information
tekwiz committed Feb 28, 2021
1 parent 8eeeec1 commit 09df486
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 8 deletions.
17 changes: 17 additions & 0 deletions README.md
Expand Up @@ -588,6 +588,23 @@ console.dir(result);

Passed through to the `insecureHTTPParser` option on http(s).request. See [`http.request`](https://nodejs.org/api/http.html#http_http_request_url_options_callback) for more information.

#### Manual Redirect

The `redirect: 'manual'` option for node-fetch is different from the browser & specification, which
results in an [opaque-redirect filtered response](https://fetch.spec.whatwg.org/#concept-filtered-response-opaque-redirect).
node-fetch gives you the typical [basic filtered response](https://fetch.spec.whatwg.org/#concept-filtered-response-basic) instead.

```js
const fetch = require('node-fetch');

const response = await fetch('https://httpbin.org/status/301', { redirect: 'manual' });

if (response.status === 301 || response.status === 302) {
const locationURL = new URL(response.headers.get('location'), response.url);
const response2 = await fetch(locationURL, { redirect: 'manual' });
console.dir(response2);
}
```

<a id="class-request"></a>

Expand Down
6 changes: 1 addition & 5 deletions src/index.js
Expand Up @@ -138,11 +138,7 @@ export default async function fetch(url, options_) {
finalize();
return;
case 'manual':
// Node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL.
if (locationURL !== null) {
headers.set('Location', locationURL);
}

// Nothing to do
break;
case 'follow': {
// HTTP-redirect fetch step 2
Expand Down
22 changes: 20 additions & 2 deletions test/main.js
Expand Up @@ -452,7 +452,10 @@ describe('node-fetch', () => {
return fetch(url, options).then(res => {
expect(res.url).to.equal(url);
expect(res.status).to.equal(301);
expect(res.headers.get('location')).to.equal(`${base}inspect`);
expect(res.headers.get('location')).to.equal('/inspect');

const locationURL = new URL(res.headers.get('location'), url);
expect(locationURL.href).to.equal(`${base}inspect`);
});
});

Expand All @@ -464,7 +467,22 @@ describe('node-fetch', () => {
return fetch(url, options).then(res => {
expect(res.url).to.equal(url);
expect(res.status).to.equal(301);
expect(res.headers.get('location')).to.equal(`${base}redirect/%C3%A2%C2%98%C2%83`);
expect(res.headers.get('location')).to.equal('<>');

const locationURL = new URL(res.headers.get('location'), url);
expect(locationURL.href).to.equal(`${base}redirect/%3C%3E`);
});
});

it('should support redirect mode to other host, manual flag', () => {
const url = `${base}redirect/301/otherhost`;
const options = {
redirect: 'manual'
};
return fetch(url, options).then(res => {
expect(res.url).to.equal(url);
expect(res.status).to.equal(301);
expect(res.headers.get('location')).to.equal('https://github.com/node-fetch');
});
});

Expand Down
8 changes: 7 additions & 1 deletion test/utils/server.js
Expand Up @@ -231,6 +231,12 @@ export default class TestServer {
res.end();
}

if (p === '/redirect/301/otherhost') {
res.statusCode = 301;
res.setHeader('Location', 'https://github.com/node-fetch');
res.end();
}

if (p === '/redirect/302') {
res.statusCode = 302;
res.setHeader('Location', '/inspect');
Expand Down Expand Up @@ -289,7 +295,7 @@ export default class TestServer {
}

if (p === '/redirect/bad-location') {
res.socket.write('HTTP/1.1 301\r\nLocation: \r\nContent-Length: 0\r\n');
res.socket.write('HTTP/1.1 301\r\nLocation: <>\r\nContent-Length: 0\r\n');
res.socket.end('\r\n');
}

Expand Down

0 comments on commit 09df486

Please sign in to comment.