fastify-reply-from: Header encoding changes, leading to `ERR_INVALID_CHAR`

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Fastify version

4.12.0

Plugin version

8.3.1

Node.js version

16.19.0

Operating system

macOS

Operating system version (i.e. 20.04, 11.3, 10)

13.1

Description

When a header is set using a character like å (Norwegian character) its encoding gets messed up. A fastify server serving it serializes correctly, but if reply-from is used, the encoding changes. If another server with reply-from is chained, the app crashes with TypeError [ERR_INVALID_CHAR]: Invalid character in header content ["content-disposition"].

Steps to Reproduce

const replyFrom = require('@fastify/reply-from');
const fastify = require('fastify');

const app = fastify();

app.get('/', (_request, reply) => {
  reply.header('content-disposition', 'år.pdf').send('OK');
});

app.listen({ port: 6666 });

const proxy = fastify();

proxy.register(replyFrom);

proxy.get('/', (_request, reply) => {
  return reply.from('http://localhost:6666');
});

proxy.listen({ port: 7777 });

const secondProxy = fastify();

secondProxy.register(replyFrom);

secondProxy.get('/', (_request, reply) => {
  return reply.from('http://localhost:7777');
});

secondProxy.listen({ port: 8888 });
$ curl -i http://localhost:6666
HTTP/1.1 200 OK
content-disposition: år.pdf
content-type: text/plain; charset=utf-8
content-length: 2
Date: Fri, 27 Jan 2023 15:47:49 GMT
Connection: keep-alive
Keep-Alive: timeout=72


$ curl -i http://localhost:7777
HTTP/1.1 200 OK
content-disposition: r.pdf
content-type: text/plain; charset=utf-8
content-length: 2
date: Fri, 27 Jan 2023 15:47:52 GMT
connection: keep-alive
keep-alive: timeout=72


$ curl -i http://localhost:8888
curl: (52) Empty reply from server

Expected Behavior

The header should be correctly encoded and decoded (i.e. 7777 and 8888 should have the same result as 6666).

If that’s not possible I expect the first server to complain when the header is added.

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 16 (16 by maintainers)

Most upvoted comments

I still see it as a upstream bug from node.js. It treats the header differently when there is a header of Transfer-Encoding or not.

It should throw no matter the header Transfer-Encoding exists.

This issue https://github.com/fastify/fastify/issues/3808 just pop up in my memory when seeing non-ASCII string in header.

the first server actually sending this header out without throwing. I guess we bypass this check in Fastify for throughput reasons… we might rethink it.

According to the research from that issue https://github.com/nodejs/node/issues/42579 If there is “Transfer-Encoding: chunked” header (exactly chunked) setHeader works properly, it sets the input header (ByteString) as is.

I assume we are not bypass anything in fastify but node.js just serialize the header as-is from the above statement.

the second server should definitely catch the error while it validates this.

We need to think why only chaining will set Transfer-Encoding: chunked.