Skip to content

Commit 9013a23

Browse files
authoredMar 31, 2023
fetch: treat content-encoding as case-insensitive & remove x-deflate (#2037)
1 parent dc8d111 commit 9013a23

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed
 

‎lib/fetch/index.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -1984,7 +1984,9 @@ async function httpNetworkFetch (
19841984
const val = headersList[n + 1].toString('latin1')
19851985

19861986
if (key.toLowerCase() === 'content-encoding') {
1987-
codings = val.split(',').map((x) => x.trim())
1987+
// https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1
1988+
// "All content-coding values are case-insensitive..."
1989+
codings = val.toLowerCase().split(',').map((x) => x.trim())
19881990
} else if (key.toLowerCase() === 'location') {
19891991
location = val
19901992
}
@@ -2003,9 +2005,10 @@ async function httpNetworkFetch (
20032005
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding
20042006
if (request.method !== 'HEAD' && request.method !== 'CONNECT' && !nullBodyStatus.includes(status) && !willFollow) {
20052007
for (const coding of codings) {
2006-
if (/(x-)?gzip/.test(coding)) {
2008+
// https://www.rfc-editor.org/rfc/rfc9112.html#section-7.2
2009+
if (coding === 'x-gzip' || coding === 'gzip') {
20072010
decoders.push(zlib.createGunzip())
2008-
} else if (/(x-)?deflate/.test(coding)) {
2011+
} else if (coding === 'deflate') {
20092012
decoders.push(zlib.createInflate())
20102013
} else if (coding === 'br') {
20112014
decoders.push(zlib.createBrotliDecompress())

‎test/fetch/encoding.js

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'use strict'
2+
3+
const { test } = require('tap')
4+
const { createServer } = require('http')
5+
const { once } = require('events')
6+
const { fetch } = require('../..')
7+
const { createBrotliCompress, createGzip } = require('zlib')
8+
9+
test('content-encoding header is case-iNsENsITIve', async (t) => {
10+
const contentCodings = 'GZiP, bR'
11+
const text = 'Hello, World!'
12+
13+
const server = createServer((req, res) => {
14+
const gzip = createGzip()
15+
const brotli = createBrotliCompress()
16+
17+
res.setHeader('Content-Encoding', contentCodings)
18+
res.setHeader('Content-Type', 'text/plain')
19+
20+
brotli.pipe(gzip).pipe(res)
21+
22+
brotli.write(text)
23+
brotli.end()
24+
}).listen(0)
25+
26+
t.teardown(server.close.bind(server))
27+
await once(server, 'listening')
28+
29+
const response = await fetch(`http://localhost:${server.address().port}`)
30+
31+
t.equal(await response.text(), text)
32+
t.equal(response.headers.get('content-encoding'), contentCodings)
33+
})

0 commit comments

Comments
 (0)
Please sign in to comment.