Обслуживание ответов HTTP/1.0 с Node.JS (неизвестная длина контента, кодировка передачи по частям)

Эта проблема

Я обслуживаю ресурс неизвестной длины через Node.JS. Из-за этого Content-Length заголовок не может быть установлен. Для HTTP 1.1 требуется, чтобы кодирование по частям использовалось для ресурсов такого рода. Node.JS знает об этом и отправляет мои данные с частичной кодировкой передачи самостоятельно, со следующими заголовками:

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

Это все хорошо и хорошо для хороших клиентов. Тем не менее, у меня есть клиенты с плохим поведением (а именно Android 2.2 и более ранние версии), которые я должен поддерживать. Эти клиенты не поддерживают правильное кодирование передачи по частям.

Исправить попытку № 1

Моя первоначальная мысль была установлена ​​кодировка none вот так:

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

Это отключает автоматическое частичное кодирование Node.JS и поддерживает совместимость с большинством клиентов. Однако теперь я сломал клиенты Android 2.3+, поскольку они просто кашляют и задыхаются, когда видят такой поддельный заголовок кодировки передачи.

Исправить попытку № 2 (где мне нужна помощь)

Когда я делаю запросы с HTTP/1.0сервер правильно возвращает ответ без чанкованной кодировки:

HTTP/1.1 200 OK
Connection: close
...

Это решает мою проблему и позволяет мне обслуживать поток, который работает для всех моих проблемных клиентов. Мне не нужно отправлять фиктивный заголовок для Transfer-Encodingи мне все еще не нужно указывать, как долго контент.

Как заставить HTTP-сервер Node.JS всегда работать в режиме HTTP/1.0?

3 ответа

Решение

Форсировать не разделенные на части ответы, правильный путь

Существует поддерживаемый способ отключения чанкованного кодирования: вам просто нужно удалить Transfer-Encoding заголовок с использованием request.removeHeader (name):

response.removeHeader('transfer-encoding');

Node.js будет уважать, несмотря ни на что. Есть даже тест, чтобы предотвратить случайное изменение этого поведения, так что я думаю, что это довольно безопасно для использования.

Так что вы можете просто придерживаться попытки #1, но делать это, как описано выше.

Для моих целей я нашел простой способ отключить принудительное использование chunked, используя недокументированное свойство объекта ответа:

response.useChunkedEncodingByDefault = false;

Это так просто. Конечно, полагаться на то, что это свойство будет доступно для будущих версий Node.js, не является лучшим. Возможно, есть лучшее решение, но это работает для меня сейчас.

Transfer-Encoding: identityтоже должно работать.

Другие вопросы по тегам