Skip to content

Commit

Permalink
improve
Browse files Browse the repository at this point in the history
  • Loading branch information
Uzlopak committed Sep 19, 2024
1 parent f951577 commit d0b4dd2
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 17 deletions.
36 changes: 23 additions & 13 deletions lib/web/fetch/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2060,7 +2060,7 @@ async function httpNetworkFetch (

function dispatch ({ body }) {
const url = requestCurrentURL(request)
/** @type {import('../..').Agent} */
/** @type {import('../../..').Agent} */
const agent = fetchParams.controller.dispatcher

return new Promise((resolve, reject) => agent.dispatch(
Expand All @@ -2074,6 +2074,9 @@ async function httpNetworkFetch (
upgrade: request.mode === 'websocket' ? 'websocket' : undefined
},
{
/**
* @type {import('node:stream').Readable|null}
*/
body: null,
abort: null,

Expand Down Expand Up @@ -2114,35 +2117,37 @@ async function httpNetworkFetch (

/** @type {string[]} */
let codings = []
let location = ''

const headersList = new HeadersList()

for (let i = 0; i < rawHeaders.length; i += 2) {
headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString('latin1'), true)
}

const contentEncoding = headersList.get('content-encoding', true)
if (contentEncoding) {
// https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1
// "All content-coding values are case-insensitive..."
codings = contentEncoding.toLowerCase().split(',').map((x) => x.trim())
}
location = headersList.get('location', true)

this.body = new Readable({ read: resume })

const decoders = []
/** @type {[src: import('node:stream').Readable, ...target: import('node:stream').Writable[]]} */
let streams

const willFollow = location && request.redirect === 'follow' &&
redirectStatusSet.has(status)
const willFollow = request.redirect === 'follow' &&
redirectStatusSet.has(status) &&
headersList.get('location', true)

// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding
if (codings.length !== 0 && request.method !== 'HEAD' && request.method !== 'CONNECT' && !nullBodyStatus.includes(status) && !willFollow) {
streams = [this.body]
for (let i = codings.length - 1; i >= 0; --i) {
const coding = codings[i]
// https://www.rfc-editor.org/rfc/rfc9112.html#section-7.2
if (coding === 'x-gzip' || coding === 'gzip') {
decoders.push(zlib.createGunzip({
streams.push(zlib.createGunzip({
// Be less strict when decoding compressed responses, since sometimes
// servers send slightly invalid responses that are still accepted
// by common browsers.
Expand All @@ -2151,14 +2156,19 @@ async function httpNetworkFetch (
finishFlush: zlib.constants.Z_SYNC_FLUSH
}))
} else if (coding === 'deflate') {
decoders.push(createInflate())
streams.push(createInflate({
flush: zlib.constants.Z_SYNC_FLUSH,
finishFlush: zlib.constants.Z_SYNC_FLUSH
}))
} else if (coding === 'br') {
decoders.push(zlib.createBrotliDecompress({
streams.push(zlib.createBrotliDecompress({
flush: zlib.constants.BROTLI_OPERATION_FLUSH,
finishFlush: zlib.constants.BROTLI_OPERATION_FLUSH
}))
} else {
decoders.length = 0
// If the server sends the payload with a coding which his not
// supported, the body will be passed through without decoding.
streams = undefined
break
}
}
Expand All @@ -2168,9 +2178,9 @@ async function httpNetworkFetch (
status,
statusText,
headersList,
body: decoders.length
? pipeline(this.body, ...decoders, noop)
: this.body.on('error', noop)
body: streams === undefined
? this.body.on('error', noop)
: pipeline(streams, noop)
})

return true
Expand Down
20 changes: 16 additions & 4 deletions lib/web/fetch/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -1338,15 +1338,23 @@ function buildContentRange (rangeStart, rangeEnd, fullLength) {
// interpreted as a zlib stream, otherwise it's interpreted as a
// raw deflate stream.
class InflateStream extends Transform {
#zlibOptions

/** @param {zlib.ZlibOptions} [zlibOptions] */
constructor (zlibOptions) {
super()
this.#zlibOptions = zlibOptions
}

_transform (chunk, encoding, callback) {
if (!this._inflateStream) {
if (chunk.length === 0) {
callback()
return
}
this._inflateStream = (chunk[0] & 0x0F) === 0x08
? zlib.createInflate()
: zlib.createInflateRaw()
? zlib.createInflate(this.#zlibOptions)
: zlib.createInflateRaw(this.#zlibOptions)

this._inflateStream.on('data', this.push.bind(this))
this._inflateStream.on('end', () => this.push(null))
Expand All @@ -1365,8 +1373,12 @@ class InflateStream extends Transform {
}
}

function createInflate () {
return new InflateStream()
/**
* @param {zlib.ZlibOptions} [zlibOptions]
* @returns {InflateStream}
*/
function createInflate (zlibOptions) {
return new InflateStream(zlibOptions)
}

/**
Expand Down

0 comments on commit d0b4dd2

Please sign in to comment.