Skip to content

Commit 8e30a85

Browse files
authored
fix(#4451): implement http2 cookie support (#4453)
1 parent 4210b31 commit 8e30a85

2 files changed

Lines changed: 93 additions & 0 deletions

File tree

lib/dispatcher/client-h2.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,16 @@ function writeH2 (client, request) {
292292
const key = reqHeaders[n + 0]
293293
const val = reqHeaders[n + 1]
294294

295+
if (key === 'cookie') {
296+
if (headers[key] != null) {
297+
headers[key] = Array.isArray(headers[key]) ? (headers[key].push(val), headers[key]) : [headers[key], val]
298+
} else {
299+
headers[key] = val
300+
}
301+
302+
continue
303+
}
304+
295305
if (Array.isArray(val)) {
296306
for (let i = 0; i < val.length; i++) {
297307
if (headers[key]) {

test/http2.js

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,89 @@ test('Should support H2 connection (headers as array)', async t => {
173173
t.strictEqual(Buffer.concat(body).toString('utf8'), 'hello h2!')
174174
})
175175

176+
test('Should support multiple header values with semicolon separator', async t => {
177+
const body = []
178+
const body2 = []
179+
const expectedCookieHeaders = ['a=b', 'c=d', 'e=f']
180+
const server = createSecureServer(await pem.generate({ opts: { keySize: 2048 } }))
181+
182+
server.on('stream', (stream, headers) => {
183+
t.strictEqual(headers['x-my-header'], 'foo, bar')
184+
t.strictEqual(headers['x-my-drink'], 'coffee, tea, water')
185+
t.strictEqual(headers['x-other'], 'value')
186+
t.strictEqual(headers['cookie'], expectedCookieHeaders.join('; '))
187+
t.strictEqual(headers[':method'], 'GET')
188+
stream.respond({
189+
'content-type': 'text/plain; charset=utf-8',
190+
'x-custom-h2': 'hello',
191+
':status': 200
192+
})
193+
stream.end('hello h2!')
194+
})
195+
196+
server.listen(0)
197+
await once(server, 'listening')
198+
199+
const client = new Client(`https://localhost:${server.address().port}`, {
200+
connect: {
201+
rejectUnauthorized: false
202+
},
203+
allowH2: true
204+
})
205+
206+
t = tspl(t, { plan: 9 * 2 })
207+
after(() => server.close())
208+
after(() => client.close())
209+
210+
const response = await client.request({
211+
path: '/',
212+
method: 'GET',
213+
headers: [
214+
'x-my-header', 'foo',
215+
'x-my-drink', ['coffee', 'tea'],
216+
'x-my-drink', 'water',
217+
'X-My-Header', 'bar',
218+
'x-other', 'value',
219+
'cookie', expectedCookieHeaders
220+
]
221+
})
222+
223+
response.body.on('data', chunk => {
224+
body.push(chunk)
225+
})
226+
227+
await once(response.body, 'end')
228+
t.strictEqual(response.statusCode, 200)
229+
t.strictEqual(response.headers['content-type'], 'text/plain; charset=utf-8')
230+
t.strictEqual(response.headers['x-custom-h2'], 'hello')
231+
t.strictEqual(Buffer.concat(body).toString('utf8'), 'hello h2!')
232+
233+
const response2 = await client.request({
234+
path: '/',
235+
method: 'GET',
236+
headers: [
237+
'x-my-header', 'foo',
238+
'x-my-drink', ['coffee', 'tea'],
239+
'cookie', 'a=b',
240+
'x-my-drink', 'water',
241+
'X-My-Header', 'bar',
242+
'cookie', 'c=d',
243+
'x-other', 'value',
244+
'cookie', 'e=f'
245+
]
246+
})
247+
248+
response2.body.on('data', chunk => {
249+
body2.push(chunk)
250+
})
251+
252+
await once(response2.body, 'end')
253+
t.strictEqual(response2.statusCode, 200)
254+
t.strictEqual(response2.headers['content-type'], 'text/plain; charset=utf-8')
255+
t.strictEqual(response2.headers['x-custom-h2'], 'hello')
256+
t.strictEqual(Buffer.concat(body).toString('utf8'), 'hello h2!')
257+
})
258+
176259
test('Should support H2 connection(POST Buffer)', async t => {
177260
const server = createSecureServer({ ...await pem.generate({ opts: { keySize: 2048 } }), allowHTTP1: false })
178261

0 commit comments

Comments
 (0)