Skip to content

Commit

Permalink
fix: support deflate raw responses (nodejs#2650)
Browse files Browse the repository at this point in the history
  • Loading branch information
Uzlopak authored and crysmags committed Feb 27, 2024
1 parent 165ab4c commit 10be3df
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 6 deletions.
9 changes: 5 additions & 4 deletions lib/fetch/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ const {
urlHasHttpsScheme,
clampAndCoursenConnectionTimingInfo,
simpleRangeHeaderValue,
buildContentRange
buildContentRange,
createInflate
} = require('./util')
const { kState } = require('./symbols')
const assert = require('assert')
Expand Down Expand Up @@ -1089,7 +1090,7 @@ function fetchFinale (fetchParams, response) {
// 3. Set up transformStream with transformAlgorithm set to identityTransformAlgorithm and flushAlgorithm
// set to processResponseEndOfBody.
const transformStream = new TransformStream({
start () {},
start () { },
transform (chunk, controller) {
controller.enqueue(chunk)
},
Expand Down Expand Up @@ -2179,7 +2180,7 @@ async function httpNetworkFetch (
finishFlush: zlib.constants.Z_SYNC_FLUSH
}))
} else if (coding === 'deflate') {
decoders.push(zlib.createInflate())
decoders.push(createInflate())
} else if (coding === 'br') {
decoders.push(zlib.createBrotliDecompress())
} else {
Expand All @@ -2195,7 +2196,7 @@ async function httpNetworkFetch (
headersList,
body: decoders.length
? pipeline(this.body, ...decoders, () => { })
: this.body.on('error', () => {})
: this.body.on('error', () => { })
})

return true
Expand Down
42 changes: 41 additions & 1 deletion lib/fetch/util.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use strict'

const { Transform } = require('node:stream')
const zlib = require('node:zlib')
const { redirectStatusSet, referrerPolicySet: referrerPolicyTokens, badPortsSet } = require('./constants')
const { getGlobalOrigin } = require('./global')
const { performance } = require('perf_hooks')
Expand Down Expand Up @@ -1174,6 +1176,43 @@ function buildContentRange (rangeStart, rangeEnd, fullLength) {
return contentRange
}

// A Stream, which pipes the response to zlib.createInflate() or
// zlib.createInflateRaw() depending on the first byte of the Buffer.
// If the lower byte of the first byte is 0x08, then the stream is
// interpreted as a zlib stream, otherwise it's interpreted as a
// raw deflate stream.
class InflateStream extends Transform {
_transform (chunk, encoding, callback) {
if (!this._inflateStream) {
if (chunk.length === 0) {
callback()
return
}
this._inflateStream = (chunk[0] & 0x0F) === 0x08
? zlib.createInflate()
: zlib.createInflateRaw()

this._inflateStream.on('data', this.push.bind(this))
this._inflateStream.on('end', () => this.push(null))
this._inflateStream.on('error', (err) => this.destroy(err))
}

this._inflateStream.write(chunk, encoding, callback)
}

_final (callback) {
if (this._inflateStream) {
this._inflateStream.end()
this._inflateStream = null
}
callback()
}
}

function createInflate () {
return new InflateStream()
}

module.exports = {
isAborted,
isCancelled,
Expand Down Expand Up @@ -1221,5 +1260,6 @@ module.exports = {
normalizeMethodRecord,
simpleRangeHeaderValue,
buildContentRange,
parseMetadata
parseMetadata,
createInflate
}
2 changes: 1 addition & 1 deletion test/node-fetch/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,7 @@ describe('node-fetch', () => {
})
})

xit('should decompress deflate raw response from old apache server', () => {
it('should decompress deflate raw response from old apache server', () => {
const url = `${base}deflate-raw`
return fetch(url).then(res => {
expect(res.headers.get('content-type')).to.equal('text/plain')
Expand Down

0 comments on commit 10be3df

Please sign in to comment.