Неработающий HTML - браузеры не загружают полный HTTP-ответ с моего веб-сервера, CURL делает
симптом
Думаю, я что-то напутал, потому что и Mozilla Firefox, и Google Chrome выдают одну и ту же ошибку: они не получают полного ответа, отправляемого им веб-сервером. CURL никогда не пропускает, последняя строка ответа быстрой прокрутки всегда " html>".
причина
Причина в том, что я отправляю ответ в большей части:
sendHeaders(); // is calls sendResponse with a fix header
sendResponse(html_opening_part);
for ( ...scan some data... ) {
sendResponse(the_data);
} // for
sendResponse(html_closing_part)
Браузеры перестают получать данные между вызовами sendResponse (). Кроме того, веб-сервер не закрывает () сокет, только в конце.
(Почему я так поступаю: программа, которую я пишу, предназначена для не Linux-системы, она будет работать на встроенном компьютере. У нее не слишком много памяти, которая в основном занята стеком lwIP. Поэтому избегайте сбора - Относительно - огромная веб-страница, я отправляю ее по частям. Браузерам нравится, не было сломанного HTML, как в Linux.)
Среда
Платформа - GNU / Linux (32-битная Ubuntu с ядром 3.0). Мой маленький веб-сервер отправляет данные обратно клиенту стандартным способом:
int sendResponse(char* data,int length) {
int x = send(fd,data,length,MSG_NOSIGNAL);
if (x == -1) {
perror("this message never printed, so there's no error \n");
if (errno == EPIPE) return 0;
if (errno == ECONNRESET) return 0;
... panic() ... (never happened) ...
} // if send()
} // sendResponse()
А вот фиксированный заголовок, который я использую:
sendResponse(
"HTTP/1.0 200 OK\n"
"Server: MyTinyWebServer\n"
"Content-Type: text/html; charset=UTF-8\n"
"Cache-Control: no-store, no-cache\n"
"Pragma: no-cache\n"
"Connection: close\n"
"\n"
);
Вопрос
Это нормально? Нужно ли отправлять весь ответ одним send ()? (Над которой я сейчас работаю, пока не появится быстрое решение.)
2 ответа
Попался!
Как советовал @Jim, я попытался отправить те же заголовки с помощью CURL, что и Mozilla: сбой, сломанный канал и т. Д. Я удалил половину заголовков: хорошо. Я добавил обратно один за другим: провал. Удалил еще одну половину заголовков: хорошо... Итак, есть ошибка, только если заголовок слишком длинный. Бинго.
Как я уже сказал, во встроенном устройстве очень мало памяти. Итак, я не читаю весь заголовок запроса, только 256 байт. Мне нужны только параметры GET и заголовок "Host" (даже мне это не нужно, просто для выполнения перенаправлений с тем же "Host" вместо IP-адреса).
Таким образом, если я не recv() весь заголовок запроса, я не могу отправить () обратно весь ответ.
Спасибо за советы, парни!
Если вы прочитаете RFC 2616, вы увидите, что вы должны использовать CR+LF
для концов линий.
Кроме того, откройте инструменты разработчика браузера, чтобы увидеть точные запросы, которые они делают. Используйте такой инструмент, как Netcat, для дублирования запросов, затем по очереди удаляйте каждый заголовок, пока он не начнет работать.