Skip to content

Commit

Permalink
Properly parse set-cookie header using http2 (#2886)
Browse files Browse the repository at this point in the history
* Properly parse set-cookie header using http2

* 💄

Co-authored-by: tsctx <91457664+tsctx@users.noreply.github.com>

---------

Co-authored-by: tsctx <91457664+tsctx@users.noreply.github.com>
  • Loading branch information
jeanp413 and tsctx committed Feb 29, 2024
1 parent 4106830 commit a3f494b
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 2 deletions.
10 changes: 9 additions & 1 deletion lib/web/fetch/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2145,7 +2145,15 @@ async function httpNetworkFetch (
const keys = Object.keys(rawHeaders)
for (let i = 0; i < keys.length; ++i) {
// The header names are already in lowercase.
headersList.append(keys[i], rawHeaders[keys[i]], true)
const key = keys[i]
const value = rawHeaders[key]
if (key === 'set-cookie') {
for (let j = 0; j < value.length; ++j) {
headersList.append(key, value[j], true)
}
} else {
headersList.append(key, value, true)
}
}
// For H2, The header names are already in lowercase,
// so we can avoid the `HeadersList#get` call here.
Expand Down
45 changes: 44 additions & 1 deletion test/fetch/cookies.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ const { createServer } = require('node:http')
const { test } = require('node:test')
const assert = require('node:assert')
const { tspl } = require('@matteo.collina/tspl')
const { fetch, Headers } = require('../..')
const { Client, fetch, Headers } = require('../..')
const { closeServerAsPromise } = require('../utils/node-http')
const pem = require('https-pem')
const { createSecureServer } = require('node:http2')
const { closeClientAndServerAsPromise } = require('../utils/node-http')

test('Can receive set-cookie headers from a server using fetch - issue #1262', async (t) => {
const server = createServer((req, res) => {
Expand Down Expand Up @@ -66,3 +69,43 @@ test('Cookie header is delimited with a semicolon rather than a comma - issue #1
]
})
})

test('Can receive set-cookie headers from a http2 server using fetch - issue #2885', async (t) => {
const server = createSecureServer(pem)
server.on('stream', async (stream, headers) => {
stream.respond({
'content-type': 'text/plain; charset=utf-8',
'x-method': headers[':method'],
'set-cookie': 'Space=Cat; Secure; HttpOnly',
':status': 200
})

stream.end('test')
})

server.listen()
await once(server, 'listening')

const client = new Client(`https://localhost:${server.address().port}`, {
connect: {
rejectUnauthorized: false
},
allowH2: true
})

const response = await fetch(
`https://localhost:${server.address().port}/`,
// Needs to be passed to disable the reject unauthorized
{
method: 'GET',
dispatcher: client,
headers: {
'content-type': 'text-plain'
}
}
)

t.after(closeClientAndServerAsPromise(client, server))

assert.deepStrictEqual(response.headers.getSetCookie(), ['Space=Cat; Secure; HttpOnly'])
})

0 comments on commit a3f494b

Please sign in to comment.