From 636493b80e373c22d3df4c2e4bd8f7a1711059ad Mon Sep 17 00:00:00 2001 From: Carsten Rohrbach Date: Wed, 3 Jul 2024 08:54:31 +0200 Subject: [PATCH] fix: agent cookie host assignment --- src/node/agent.js | 4 ++-- src/node/index.js | 9 +++++++++ test/agent-base.js | 20 ++++++++++++++++++++ test/support/server.js | 25 +++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/node/agent.js b/src/node/agent.js index 88030d776..a794d13cb 100644 --- a/src/node/agent.js +++ b/src/node/agent.js @@ -54,7 +54,7 @@ class Agent extends AgentBase { const cookies = res.headers['set-cookie']; if (cookies) { const url = new URL(res.request?.url || ''); - this.jar.setCookies(cookies, url.hostname, url.pathname); + this.jar.setCookies(cookies, url.hostname, null); } } @@ -82,7 +82,7 @@ for (const name of methods) { const request_ = new request.Request(method, url); request_.on('response', this._saveCookies.bind(this)); - request_.on('redirect', this._saveCookies.bind(this)); + request_.on('pre-redirect', this._saveCookies.bind(this)); request_.on('redirect', this._attachCookies.bind(this, request_)); this._setDefaults(request_); this._attachCookies(request_); diff --git a/src/node/index.js b/src/node/index.js index 75217c8bd..7c7fa55bc 100644 --- a/src/node/index.js +++ b/src/node/index.js @@ -504,6 +504,8 @@ Request.prototype._redirect = function (res) { // this is required for Node v0.10+ res.resume(); + this._emitPreRedirect(res); + let headers = this.req.getHeaders ? this.req.getHeaders() : this.req._headers; const changesOrigin = new URL(url).host !== new URL(this.url).host; @@ -956,6 +958,13 @@ Request.prototype._emitRedirect = function () { this.emit('redirect', response); }; +Request.prototype._emitPreRedirect = function (res) { + this.res = res; + const response = new Response(this); + response.redirects = this._redirectList; + this.emit('pre-redirect', response); +}; + Request.prototype.end = function (fn) { this.request(); debug('%s %s', this.method, this.url); diff --git a/test/agent-base.js b/test/agent-base.js index 592f996e8..a3b3c0b69 100644 --- a/test/agent-base.js +++ b/test/agent-base.js @@ -49,4 +49,24 @@ describe('Agent', () => { assert.deepEqual({ hello: 'world' }, res.body); }); }); + + it('should assign cookies without domains correctly when following redirects', () => { + const agent = request.agent(); + + const firstUrl = new URL(base) + firstUrl.hostname = 'first.local' + const first = firstUrl.toString().slice(0, -1) + + const secondUrl = new URL(base) + secondUrl.hostname = "second.local" + const second = secondUrl.toString().slice(0, -1) + + return agent + .get(`${first}/cookie-cross-domain-redirect`) + .query({ first, second }) + .connect('127.0.0.1') + .then((res) => { + assert.equal(res.text, 'first.local=true') + }) + }) }); diff --git a/test/support/server.js b/test/support/server.js index a219c0d15..4e676862e 100644 --- a/test/support/server.js +++ b/test/support/server.js @@ -441,6 +441,31 @@ app.put('/redirect-308', (request, res) => { res.redirect(308, '/reply-method'); }); +app.get('/cookie-cross-domain-redirect', (request, res) => { + const { first, second } = request.query + const hostname = new URL(`http://${request.headers.host ?? request.headers[':authority']}`).hostname + res.cookie(hostname, 'true', { + path: '/', + sameSite: 'lax', + secure: false, + maxAge: 1000 + }); + + res.redirect(303, `${second}/cookie-cross-domain-second-redirect?first=${encodeURIComponent(first)}`); +}); + +app.get('/cookie-cross-domain-second-redirect', (request, res) => { + const first = request.query.first + const hostname = new URL(`http://${request.headers.host ?? request.headers[':authority']}`).hostname + res.cookie(hostname, 'true', { + path: '/', + sameSite: 'lax', + secure: false, + maxAge: 1000 + }); + res.redirect(303, `${first}/show-cookies`); +}); + app.all('/reply-method', (request, res) => { res.send(`method=${request.method.toLowerCase()}`); });