Назад | Перейти на главную страницу

Определить конец искаженного (неверного) HTTP-запроса

Я реализую HTTP-сервер и задаюсь вопросом, существует ли определенный способ, при котором сервер определит неверный запрос как завершенный

  1. вернуть соответствующий статус 400 и
  2. принять следующие данные как новый запрос, начиная новую попытку их синтаксического анализа.

Единственная идея, которая приходит мне в голову, была бы очень двусмысленной: поиск следующих полученных данных, подобных строке запроса, и начало новой попытки синтаксического анализа оттуда. Однако, как уже говорилось, это очень неоднозначный подход, поскольку данные неверного запроса могут, конечно, содержать упомянутые данные «типа строки запроса», не предполагая, что это будет отдельный новый запрос.

Тот же вопрос возникает, когда вы думаете о синтаксическом анализе искаженных ответов на стороне клиента, поэтому принятие этого случая во внимание будет приветствоваться.

После некоторых размышлений стало совершенно ясно, что не существует универсально применимого способа определения конца искаженного сообщения, поскольку сообщения всегда содержат некоторые самоописывающиеся биты информации (например, Content-Length поле заголовка), которое позволяет получателю действительно понять сообщение. Если, например, ответ будет выглядеть так:

HTTP/1.1 200 OK
Content-Length: [ consider correct content length here ]
Content-Type: text/html
<html>
    <head>
        <title>Title</title>
    </head>
    <body>
HTTP OK status messages look like this:
HTTP/1.1 200 OK
    </body>
</html>

Клиентский парсер, скорее всего, выйдет из строя при первом < поскольку он ожидал бы другое имя поля заголовка (из-за единственного разрыва строки после Content-Type-header), что не позволяет <. Кроме того, он тогда (вероятно) не должен «искать» другой допустимый HTTP-ответ в следующих данных, поскольку он может получать тела сообщения, подобные данному, где он говорит HTTP/1.1 200 OK, который, однако, не является новым ответом.

Таким образом, лучшая реакция на искаженное http-сообщение - это закрытие соединения, поскольку любая другая попытка интерпретировать следующие полученные данные неизбежно неоднозначна.

Однако это AFAIK никоим образом не указано в RFC. Может быть, потому что RFC больше касается определения стандартов, а не обработки нестандартного поведения.

Заголовок заканчивается на \r\n\r\n. Вы просто анализируете каждую запись, которую нужно прочитать, и разбиваете их на аргумент strtok? или strstr, или вручную.

Если вы поговорите подробнее о строке GET;

Протокол HTTP не накладывает никаких априорных ограничений на длину
URI. Серверы ДОЛЖНЫ иметь возможность обрабатывать URI любого ресурса, который они
служить, и ДОЛЖЕН иметь возможность обрабатывать URI неограниченной длины, если они
предоставить формы на основе GET, которые могут генерировать такие URI. Сервер
ДОЛЖЕН вернуть статус 414 (Request-URI Too Long), если URI длиннее
чем сервер может обработать (см. раздел 10.4.15).

  Note: Servers ought to be cautious about depending on URI lengths
  above 255 bytes, because some older client or proxy
  implementations might not properly support these lengths.

Пожалуйста, обратитесь к RFC 2616 чтобы ваш веб-сервер работал в соответствии со стандартом.

nb, убедитесь, что вы готовы использовать атрибут chunk и после этого, если вы хотите поддерживать HTTP1.0 +, иначе ваш сервер будет соответствовать стандарту HTTP0.9.