Serving HTTP/1.0 responses with Node.JS (unknown c

2019-02-16 08:49发布

问题:

The Problem

I am serving a resource of unknown length via Node.JS. Because of this, the Content-Length header cannot be set. For HTTP 1.1, it is required that chunked encoding is used for resources of this nature. Node.JS knows this and sends my data with chunked transfer encoding all on its own, with the following headers:

HTTP/1.1 200 OK
Transfer-Encoding: chunked
Connection: close
...

This is all fine and good for well-behaved clients. However, I have some not-so-well behaved clients (namely Android 2.2 and earlier) that I must support. These clients do not support chunked transfer encoding properly.

Fix Attempt #1

My initial thought was set the encoding to none like so:

response.writeHead(200, {'Transfer-Encoding': 'none'});

This disables Node.JS's automatic chunked encoding and maintains compatibility with most clients. However, now I have broken Android 2.3+ clients, as they simply cough and choke when they see such a bogus transfer encoding header.

Fix Attempt #2 (where I need help)

When I make requests with HTTP/1.0, the server properly returns the response without chunked encoding:

HTTP/1.1 200 OK
Connection: close
...

This solves my problem, and allows me to serve a stream that works for all of my troublesome clients. I don't have to send a bogus header for Transfer-Encoding, and I still don't have to specify how long the content is.

How can I force Node.JS's HTTP server to always serve in HTTP/1.0 mode?

回答1:

Forcing non-chunked responses, the right way

There's a supported way of turning off chunked encoding: you simply need to remove the Transfer-Encoding header using request.removeHeader(name):

response.removeHeader('transfer-encoding');

Node.js will respect no matter what. There's even a test to prevent someone from accidentally changing this behavior, so I think it's pretty safe to use.

So you can just stick with attempt #1, but doing it as described above.



回答2:

For my purposes, I found an easy way to disable the forced usage of chunked, using an undocumented property of the response object:

response.useChunkedEncodingByDefault = false;

It's that simple. Of course, relying on this property to be available for future versions of Node.js isn't the best. Perhaps there is a better solution, but this works for me for now.