Skip to content

Set cookie on redirect only if domain matches #387

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ Redirect options

These options only apply if the `follow_max` (or `follow`) option is higher than 0.

- `follow_set_cookies` : Sends the cookies received in the `set-cookie` header as part of the following request. `false` by default.
- `follow_set_cookies` : Sends the cookies received in the `set-cookie` header as part of the following request, *if hosts match*. `false` by default.
- `follow_set_referer` : Sets the 'Referer' header to the requested URI when following a redirect. `false` by default.
- `follow_keep_method` : If enabled, resends the request using the original verb instead of being rewritten to `get` with no data. `false` by default.
- `follow_if_same_host` : When true, Needle will only follow redirects that point to the same host as the original request. `false` by default.
Expand Down
6 changes: 5 additions & 1 deletion lib/needle.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@ function resolve_url(href, base) {
return url.resolve(base, href);
}

function domains_match(one, two) {
return one && two && resolve_url(one).host == resolve_url(two).host;
}

function host_and_ports_match(url1, url2) {
if (url1.indexOf('http') < 0) url1 = 'http://' + url1;
if (url2.indexOf('http') < 0) url2 = 'http://' + url2;
Expand Down Expand Up @@ -615,7 +619,7 @@ Needle.prototype.send_request = function(count, method, uri, config, post_data,

// if follow_set_cookies is true, insert cookies in the next request's headers.
// we set both the original request cookies plus any response cookies we might have received.
if (config.follow_set_cookies) {
if (config.follow_set_cookies && domains_match(headers.location, uri)) {
var request_cookies = cookies.read(config.headers['cookie']);
config.previous_resp_cookies = resp.cookies;
if (Object.keys(request_cookies).length || Object.keys(resp.cookies || {}).length) {
Expand Down
81 changes: 76 additions & 5 deletions test/redirect_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ describe('redirects', function() {
spies[current_protocol].callCount.should.eql(2);
done();
})

}

function followed_other_protocol(done) {
Expand Down Expand Up @@ -193,8 +192,6 @@ describe('redirects', function() {
opts = { follow: value };
})



describe('and redirected to the same path on same host and protocol', function() {
before(function() {
location = url;
Expand Down Expand Up @@ -258,8 +255,26 @@ describe('redirects', function() {

it('sends a GET request with no data', function(done) {
send_request(opts, function(err, resp) {
spies.http.args[0][0].method.should.eql('GET');
// spy.args[0][3].should.eql(null);
spies.http.args[0][0].method.should.eql('GET');
done();
})
})

it('does not resend cookies if follow_set_cookies is false', function(done) {
opts.cookies = {foo: 'bar'};
opts.follow_set_cookies = false;
send_request(opts, function(err, resp) {
should.not.exist(spies.http.args[0][0].headers['cookie']);
done();
})
})

it('resends cookies if follow_set_cookies is true', function(done) {
opts.cookies = {foo: 'bar'};
opts.follow_set_cookies = true;
send_request(opts, function(err, resp) {
spies.http.args[0][0].headers['cookie'].should.eql('foo=bar')
done();
})
})
Expand All @@ -285,8 +300,26 @@ describe('redirects', function() {

it('sets Referer header when following redirect', function(done) {
send_request(opts, function(err, resp) {
spies.http.args[0][0].headers['referer'].should.eql("http://" + host + ":8888/hello");
// spies.http.args[0][3].should.eql({ foo: 'bar'});
spies.http.args[0][0].headers['referer'].should.eql("http://" + host + ":8888/hello");
done();
})
})

it('does not resend cookies if follow_set_cookies is false', function(done) {
opts.cookies = {foo: 'bar'};
opts.follow_set_cookies = false;
send_request(opts, function(err, resp) {
should.not.exist(spies.http.args[0][0].headers['cookie']);
done();
})
})

it('resends cookies if follow_set_cookies is true', function(done) {
opts.cookies = {foo: 'bar'};
opts.follow_set_cookies = true;
send_request(opts, function(err, resp) {
spies.http.args[0][0].headers['cookie'].should.eql('foo=bar')
done();
})
})
Expand Down Expand Up @@ -318,6 +351,24 @@ describe('redirects', function() {
})
})

it('does not resend cookies if follow_set_cookies is false', function(done) {
opts.cookies = {foo: 'bar'};
opts.follow_set_cookies = false;
send_request(opts, function(err, resp) {
should.not.exist(spies.http.args[0][0].headers['cookie']);
done();
})
})

it('resends cookies if follow_set_cookies is true', function(done) {
opts.cookies = {foo: 'bar'};
opts.follow_set_cookies = true;
send_request(opts, function(err, resp) {
spies.http.args[0][0].headers['cookie'].should.eql('foo=bar')
done();
})
})

})

})
Expand All @@ -333,7 +384,17 @@ describe('redirects', function() {
before(function() {
location = url.replace(host, hostname);
})

it('follows redirect', followed_same_protocol);

it('does not resend cookies even if follow_set_cookies is true', function(done) {
opts.cookies = {foo: 'bar'};
opts.follow_set_cookies = true;
send_request(opts, function(err, resp) {
should.not.exist(spies.http.args[0][0].headers['cookie']);
done();
})
})
})

})
Expand Down Expand Up @@ -366,7 +427,17 @@ describe('redirects', function() {
before(function() {
location = url.replace(host, hostname).replace(protocol, other_protocol).replace(ports[protocol], ports[other_protocol]);
})

it('follows redirect', followed_other_protocol);

it('does not resend cookies even if follow_set_cookies is true', function(done) {
opts.cookies = {foo: 'bar'};
opts.follow_set_cookies = true;
send_request(opts, function(err, resp) {
should.not.exist(spies.http.args[0][0].headers['cookie']);
done();
})
})
})

})
Expand Down