-
-
Notifications
You must be signed in to change notification settings - Fork 46
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
Unicode emoji converted to broken chars in certain extreme long string responses #288
Comments
Thanks for reporting! Can you provide steps to reproduce? We often need a reproducible example, e.g. some code that allows someone else to recreate your problem by just copying and pasting it. If it involves more than a couple of different file, create a new repository on GitHub and add a link to that. |
As some additional checks: can you verify that Node.js brotli compressor is not the source of the problem? |
How can I verify on Node.js side? And it's more than I am happy to verify. It's quite strange behavior. |
Take a look at the zlib module. |
Attached a minimal reproducible example. npm install
node issue-288.js Open browser and navigate to http://127.0.0.1:6789/issue |
I think you might need to specify the charset in the http header. const Fastify = require('fastify')
const fastifyCompress = require('@fastify/compress')
const fastify = new Fastify({
logger: true,
})
fastify.register(fastifyCompress)
fastify.get('/issue', async (req, reply) => {
const subscription = await require("fs")
.promises //
.readFile("./subscription.txt", "utf-8");
// await require('fs').promises
// .writeFile('/out.txt', subscription, 'utf-8') // <--- the file content is okay
//
reply.header('Content-Type', 'text/plain; charset=utf-8')
return reply.send(subscription) // <--- the file content is corrupt
})
fastify.listen({ port: 6789, host: '127.0.0.1' }) |
In my initial report, the response header already contains |
It is impossible for anyone to assist if you are unable to provide a known good input file that results in a bad output file after being compressed. const data = fs.readFileSync('/tmp/known_good.txt')
const compressedData = zlib.brotliCompressSync(data)
fs.writeFileSync('/tmp/compressed.txt.brotli', compressedData) $ brotli -d /tmp/compressed.txt.brotli |
Img 1: No broken chars appear in Img 2: See broken chars in browser (or curl), after calling @jsumners I have done the steps, brotli is fine, but final result is not good. Let me describe: Round 1
Round 2
Round 3
Current finding:
|
Somehow seeing 62484 seems oddly familiar?! As if i saw it in a different context. The char is at Position 62484 but it could be byte position 65525, as you mentioned. So very close to the default high watermark of streams? It can be, that the Buffers are not concatted properly. So basically the following classical misimplementation: toString() is called on each chunk in the stream instead of buffering the chunks into an array of Buffers, run Buffer.concat and then call .toString() once on the result. |
Can you provide your mvce as a github repo, please? |
Here we go Now, its a bit more closer to the root cause. I register routes with a route factory, If I simply define route as fastify.get(path, async (request, reply) => {
const longStringWithEmoji = readFile(...)
return reply.send(longStringWithEmoji) // <-- works, Emoji are shown
}) If I define route like this, it fails fastify.register((instance, opts, done) => {
instance.get(path, async (request, reply) => {
const longStringWithEmoji = readFile(...)
return reply.send(longStringWithEmoji) // <-- NOT work, sone Emoji are invalid
})
done()
}) |
I am sorry to bother you, but the example you shown above do not reproduce on my computer. |
@climba03003 @Uzlopak Could you pull my repo again.
|
I can reproduce. Note that |
I suspect the bug is actually cause by |
For workaround,
instance.get('/issue', async (req, reply) => {
const longStringWithEmoji = await readFile("./test.txt", "utf-8");
reply.header('content-type', 'text/plain; charset=utf-8')
return reply.send(Readable.from(longStringWithEmoji, { encoding: 'utf-8'}))
})
instance.get('/issue', async (req, reply) => {
reply.header('content-type', 'text/plain; charset=utf-8')
return reply.send(createReadStream('./test.txt', 'utf-8'))
}) |
Here is the fix: #289 |
Please reopen the issue, until #291 is tested successfully. Thanks |
Prerequisites
Fastify version
4.26.2
Plugin version
7.0.2
Node.js version
18.x
Operating system
Windows
Description
Download a 200kb yaml plain text file with
fastify/compress
. Certain lines of the yaml contains illegal chars.As you can see, on the left side (without compress), icons in the small green box are same.
But on the right side, one of the icon becomes 2 strange question marks.
The content encoding is
br
(I tried withgzip
, same error)Any thoughts, what can be the root cause?
Steps to Reproduce
Expected Behavior
Dont expect the two question marks appear in the content.
The text was updated successfully, but these errors were encountered: