Разделить CRLF между полезными нагрузками TCP - PullRequest
2 голосов
/ 02 сентября 2011

В настоящее время я пишу низкоуровневый синтаксический анализатор HTTP и столкнулся со следующей проблемой:

Я получаю данные HTTP по каждому пакету, то есть полезные данные TCP по одному за раз.При синтаксическом анализе этих данных я использую стандарты протокола HTTP для поиска CRLF для разграничения строк заголовка, данных чанка (в случае chunked-кодирования) и двойного CRLF для разграничения заголовка из тела.

MyВопрос заключается в следующем: нужно ли беспокоиться о возможности разделения CRLF между двумя полезными нагрузками пакета TCP?Например, заголовок HTTP будет заканчиваться CRLFCRLF.Возможно ли, что два последующих TCP-пакета будут иметь CR, а затем LFCRLF?

Я предполагаю, что да;Это тот случай, о котором стоит беспокоиться, поскольку уровни приложения (HTTP) и TCP довольно независимы друг от друга.

Любое понимание этого будет высоко оценено, спасибо!

Ответы [ 2 ]

3 голосов
/ 02 сентября 2011

Да, возможно, что CRLF разделен на разные TCP-пакеты.Подумайте только о возможности того, что один заголовок HTTP будет ровно на один байт длиннее, чем TCP MTU.В этом случае есть место только для CR, но не для NL.

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

1 голос
/ 02 сентября 2011

На каком языке вы работаете?Разве у него нет какой-либо формы буферизированной функции чтения для сокета, так что у вас нет этой проблемы?

Краткий ответ на ваш вопрос: да, теоретически вам нужно об этом беспокоиться, потому что этовозможно, что пакеты будут доставлены так.Это очень маловероятно, потому что большинство конечных точек HTTP будут склонны отправлять заголовок в одном пакете и тело в последующих пакетах.Это меньше по соглашению и больше по характеру работы большинства программ / языков, основанных на сокетах.

Следует иметь в виду, что хотя стандарты протоколов достаточно ясны в отношении разделения CRLF, многие людикоторые реализуют HTTP (в частности, клиенты, но в некоторой степени и серверы), не знают / не заботятся о том, что делают, и не будут подчиняться правилам.Они будут стремиться разделять строки только с LF - в частности, пустая строка между головой и телом, количество сегментов кода, которые я видел с этой проблемой, я не мог подсчитать быстро.Хотя это технически является нарушением протокола, большинство серверов / клиентов будут принимать это поведение и обходить его, поэтому вам также необходимо это сделать.

Если вы не можете выполнить какую-либо функцию буферизованного чтения, существуетхорошие новостиВсе, что вам нужно сделать, это прочитать пакет за один раз в память и пометить данные на предыдущий пакет (ы).Каждый раз, когда вы прочитали пакет, отсканируйте ваши данные на наличие двойной последовательности CRLF, если вы ее не найдете, прочитайте следующий пакет и так далее, пока не найдете конец заголовка.Это будет относительно небольшое использование памяти, потому что заголовок любого запроса никогда не должен превышать 5-6 КБ, что при значениях MTU Ethernet (в среднем около 1450 байт) означает, что вам не нужно загружать больше 4 или5 пакетов в память, чтобы справиться с этим.

...