add basic support for redirect mode

This commit is contained in:
David Frank 2016-04-06 02:47:23 +08:00
parent 2ebaee639f
commit 64d798dd83
3 changed files with 37 additions and 2 deletions

View File

@ -129,7 +129,12 @@ function Fetch(url, opts) {
clearTimeout(reqTimeout);
// handle redirect
if (self.isRedirect(res.statusCode)) {
if (self.isRedirect(res.statusCode) && options.redirect !== 'manual') {
if (options.redirect === 'error') {
reject(new FetchError('redirect mode is set to error: ' + options.url, 'no-redirect'));
return;
}
if (options.counter >= options.follow) {
reject(new FetchError('maximum redirect reached at: ' + options.url, 'max-redirect'));
return;
@ -169,6 +174,11 @@ function Fetch(url, opts) {
}
}
// normalize location header for manual redirect mode
if (options.redirect === 'manual') {
headers.set('location', resolve_url(options.url, headers.get('location')));
}
// response object
var output = new Response(body, {
url: options.url

View File

@ -44,6 +44,7 @@ function Request(input, init) {
// fetch spec options
this.method = init.method || input.method || 'GET';
this.redirect = init.redirect || input.redirect || 'follow';
this.headers = new Headers(init.headers || input.headers || {});
this.url = url;

View File

@ -89,7 +89,7 @@ describe('node-fetch', function() {
url = 'http://localhost:50000/';
return expect(fetch(url)).to.eventually.be.rejected
.and.be.an.instanceOf(FetchError)
.and.include({type: 'system', code: 'ECONNREFUSED', errno: 'ECONNREFUSED'});
.and.include({ type: 'system', code: 'ECONNREFUSED', errno: 'ECONNREFUSED' });
});
it('should resolve into response', function() {
@ -298,6 +298,28 @@ describe('node-fetch', function() {
.and.have.property('type', 'max-redirect');
});
it('should support redirect mode, manual flag', function() {
url = base + '/redirect/301';
opts = {
redirect: 'manual'
};
return fetch(url, opts).then(function(res) {
expect(res.url).to.equal(base + '/redirect/301');
expect(res.status).to.equal(301);
expect(res.headers.get('location')).to.equal(base + '/inspect');
});
});
it('should support redirect mode, error flag', function() {
url = base + '/redirect/301';
opts = {
redirect: 'error'
};
return expect(fetch(url, opts)).to.eventually.be.rejected
.and.be.an.instanceOf(FetchError)
.and.have.property('type', 'no-redirect');
});
it('should follow redirect code 301 and keep existing headers', function() {
url = base + '/redirect/301';
opts = {
@ -1145,6 +1167,7 @@ describe('node-fetch', function() {
var req = new Request(url, {
body: body
, method: 'POST'
, redirect: 'manual'
, headers: {
b: '2'
}
@ -1155,6 +1178,7 @@ describe('node-fetch', function() {
var cl = req.clone();
expect(cl.url).to.equal(url);
expect(cl.method).to.equal('POST');
expect(cl.redirect).to.equal('manual');
expect(cl.headers.get('b')).to.equal('2');
expect(cl.follow).to.equal(3);
expect(cl.compress).to.equal(false);