Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serving HTTP/1.0 responses with Node.JS (unknown content length, chunked transfer encoding)

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?

like image 305
Brad Avatar asked Jul 21 '12 05:07

Brad


3 Answers

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.

like image 192
Brad Avatar answered Nov 15 '22 16:11

Brad


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.

like image 2
Lucio Paiva Avatar answered Nov 15 '22 16:11

Lucio Paiva


Transfer-Encoding: identity should also work.

like image 1
ZzZombo Avatar answered Nov 15 '22 14:11

ZzZombo