Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: replace into-stream to Readable.from #290

Merged
merged 14 commits into from
Mar 29, 2024
11 changes: 6 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ const fp = require('fastify-plugin')
const encodingNegotiator = require('@fastify/accept-negotiator')
const pump = require('pump')
const mimedb = require('mime-db')
const intoStream = require('into-stream')
const peek = require('peek-stream')
const { Minipass } = require('minipass')
const pumpify = require('pumpify')
const { Readable } = require('readable-stream')

const { isStream, isGzip, isDeflate } = require('./lib/utils')

const { isStream, isGzip, isDeflate, intoAsyncIterator } = require('./lib/utils')

const InvalidRequestEncodingError = createError('FST_CP_ERR_INVALID_CONTENT_ENCODING', 'Unsupported Content-Encoding: %s', 415)
const InvalidRequestCompressedPayloadError = createError('FST_CP_ERR_INVALID_CONTENT', 'Could not decompress the request payload using the provided encoding', 400)
Expand Down Expand Up @@ -276,7 +277,7 @@ function buildRouteCompress (fastify, params, routeOptions, decorateOnly) {
if (Buffer.byteLength(payload) < params.threshold) {
return next()
}
payload = intoStream(payload)
payload = Readable.from(intoAsyncIterator(payload))
}

setVaryHeader(reply)
Expand Down Expand Up @@ -400,7 +401,7 @@ function compress (params) {
if (Buffer.byteLength(payload) < params.threshold) {
return this.send(payload)
}
payload = intoStream(payload)
payload = Readable.from(intoAsyncIterator(payload))
}

setVaryHeader(this)
Expand Down Expand Up @@ -509,7 +510,7 @@ function maybeUnzip (payload, serialize) {
// handle case where serialize doesn't return a string or Buffer
if (!Buffer.isBuffer(buf)) return result
if (isCompressed(buf) === 0) return result
return intoStream(result)
return Readable.from(intoAsyncIterator(result))
Uzlopak marked this conversation as resolved.
Show resolved Hide resolved
}

function zipStream (deflate, encoding) {
Expand Down
10 changes: 9 additions & 1 deletion lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,12 @@ function isStream (stream) {
return stream !== null && typeof stream === 'object' && typeof stream.pipe === 'function'
}

module.exports = { isGzip, isDeflate, isStream }
// It is a helper used to provide a async iteratable for
// Readable.from
async function *intoAsyncIterator (payload) {
// string | Buffer
yield payload
climba03003 marked this conversation as resolved.
Show resolved Hide resolved
}


module.exports = { isGzip, isDeflate, isStream, intoAsyncIterator }
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@
"dependencies": {
"@fastify/accept-negotiator": "^1.1.0",
"fastify-plugin": "^4.5.0",
"into-stream": "^6.0.0",
"mime-db": "^1.52.0",
"minipass": "^7.0.2",
"peek-stream": "^1.1.3",
"pump": "^3.0.0",
"pumpify": "^2.0.1"
"pumpify": "^2.0.1",
"readable-stream": "^4.5.2",
gurgunday marked this conversation as resolved.
Show resolved Hide resolved
"undici": "^5.28.3"
climba03003 marked this conversation as resolved.
Show resolved Hide resolved
},
"devDependencies": {
"@fastify/pre-commit": "^2.0.2",
Expand Down
42 changes: 42 additions & 0 deletions test/issue-288.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
'use strict'

const { test } = require('tap')
const Fastify = require('fastify')
const fastifyCompress = require('..')
const { fetch } = require('undici')

test('should not corrupt the file content', async (t) => {
// provide 2 byte unicode content
const twoByteUnicodeContent = new Array(5_000)
.fill('0')
.map(() => {
const random = new Array(10).fill('A').join('🍃')
return random + '- FASTIFY COMPRESS,🍃 FASTIFY COMPRESS'
})
.join('\n')
const fastify = new Fastify()
t.teardown(() => fastify.close())

fastify.register(async (instance, opts) => {
await fastify.register(fastifyCompress)
// compression
instance.get('/issue', async (req, reply) => {
return twoByteUnicodeContent
})
})

// no compression
fastify.get('/good', async (req, reply) => {
return twoByteUnicodeContent
})

await fastify.listen({ port: 0 })

const { port } = fastify.server.address()
const url = `http://localhost:${port}`
const response = await fetch(`${url}/issue`)
const response2 = await fetch(`${url}/good`)
const body = await response.text()
const body2 = await response2.text()
t.equal(body, body2)
})
Loading