Skip to content

Commit

Permalink
fetch: treat content-encoding as case-insensitive & remove x-deflate (n…
Browse files Browse the repository at this point in the history
  • Loading branch information
KhafraDev authored and crysmags committed Feb 27, 2024
1 parent 6a36532 commit d3548ff
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 3 deletions.
9 changes: 6 additions & 3 deletions lib/fetch/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1984,7 +1984,9 @@ async function httpNetworkFetch (
const val = headersList[n + 1].toString('latin1')

if (key.toLowerCase() === 'content-encoding') {
codings = val.split(',').map((x) => x.trim())
// https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1
// "All content-coding values are case-insensitive..."
codings = val.toLowerCase().split(',').map((x) => x.trim())
} else if (key.toLowerCase() === 'location') {
location = val
}
Expand All @@ -2003,9 +2005,10 @@ async function httpNetworkFetch (
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding
if (request.method !== 'HEAD' && request.method !== 'CONNECT' && !nullBodyStatus.includes(status) && !willFollow) {
for (const coding of codings) {
if (/(x-)?gzip/.test(coding)) {
// https://www.rfc-editor.org/rfc/rfc9112.html#section-7.2
if (coding === 'x-gzip' || coding === 'gzip') {
decoders.push(zlib.createGunzip())
} else if (/(x-)?deflate/.test(coding)) {
} else if (coding === 'deflate') {
decoders.push(zlib.createInflate())
} else if (coding === 'br') {
decoders.push(zlib.createBrotliDecompress())
Expand Down
33 changes: 33 additions & 0 deletions test/fetch/encoding.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use strict'

const { test } = require('tap')
const { createServer } = require('http')
const { once } = require('events')
const { fetch } = require('../..')
const { createBrotliCompress, createGzip } = require('zlib')

test('content-encoding header is case-iNsENsITIve', async (t) => {
const contentCodings = 'GZiP, bR'
const text = 'Hello, World!'

const server = createServer((req, res) => {
const gzip = createGzip()
const brotli = createBrotliCompress()

res.setHeader('Content-Encoding', contentCodings)
res.setHeader('Content-Type', 'text/plain')

brotli.pipe(gzip).pipe(res)

brotli.write(text)
brotli.end()
}).listen(0)

t.teardown(server.close.bind(server))
await once(server, 'listening')

const response = await fetch(`http://localhost:${server.address().port}`)

t.equal(await response.text(), text)
t.equal(response.headers.get('content-encoding'), contentCodings)
})

0 comments on commit d3548ff

Please sign in to comment.