Обслуживание ответов 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, не является лучшим. Возможно, есть лучшее решение, но это работает для меня сейчас.