Transfer-Encoding: chunked-- браузер не отвечает
Я сделал очень простой веб-сервер на моей машине LINUX, используя программирование сокетов TCP на языке C. Я посылаю ему HTTP-запрос GET из браузера (как chrome, так и mozilla) с локальной машины. Эта проблема в том, что, когда я не устанавливаю заголовок
Transfer-Encoding: фрагмент в ответе, браузер успешно отображает веб-страницу. Но когда я сохраняю этот заголовок, браузер не отвечает, он говорит, что никаких данных нет.
РЕДАКТИРОВАТЬ: Теперь он работает для Firefox после того, как я добавил размер чанка (446 байт), как указано @RomanK. Но хром перестает отвечать.
Вот код
responseIndex = add(response,"HTTP/1.1 200 OK",responseIndex);
responseIndex = add(response,"Transfer-Encoding: chunked",responseIndex);
responseIndex = add(response,"Content-Type: text/html",responseIndex);
response[responseIndex++]='\r';
response[responseIndex++]='\n';
updateIndex = add(response,"446",updateIndex);
responseIndex = add(response,filebuffer,responseIndex);
response[responseIndex++]='\0';
send(clntSock, response, strlen(response), 0) ;
close(clntSock);
exit(0);
Здесь add - это функция, которая добавляет второй аргумент к ответу, а затем добавляет "/r/n".
ответ является строкой.
responseIndex - это просто int для отслеживания текущей длины ответа.
filebuffer - это строка, которая содержит весь текст HTML-файла для отправки.
Отклик:
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Content-Type: text/html
446 (or 1EB)
<html>
BODY
</html>
Код ошибки, заданный Chrome: ERR_INVALID_CHUNKED_ENCODING
2 ответа
Content-Length
и фрагментированное кодирование передачи является взаимоисключающим.
Вы должны опустить Content-Length
и скорее добавьте размер куска в начале каждого куска согласно статье в Википедии.
Или, другими словами, вам нужно вывести размер куска в шестнадцатеричном виде перед этой строкой
responseIndex = add(response,filebuffer,responseIndex);
РЕДАКТИРОВАТЬ: Обратите внимание, что вам нужно указать только размер фрагмента, а не всего HTTP-ответа. В вашем случае это должен быть размер только тела HTML; например, похоже, что ваше тело образца будет иметь размер 30 или 31 в шестнадцатеричном формате (не уверен насчет пробела).
Итак, 3 балла: а) Используйте гекс б) Используйте строчные буквы в) Используйте размер чанка (в вашем случае, тело, так как у вас есть один чанк). Не включайте размер метаданных HTTP.
Также немного сомнительно, что вы используете чанки в первую очередь; они должны использоваться только в тех случаях, когда вы не знаете размер ответа, когда вы начинаете генерировать ответ. Здесь вы знаете размер ответа в начале и можете использовать Content-Length
без Transfer-Encoding: chunked
,
Смысл чанкованной передачи (извините за тавтологию) заключается в отправке данных в чанках. Браузер не знает, сколько кусков ожидать, поэтому вы должны сказать ему, что какой-то кусок является последним. Протокол указывает, что последний кусок должен иметь размер 0:
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Content-Type: text/html
446\r\n
Precisely 446 bytes of data
0\r\n