Работа с постоянными HTTP-соединениями - PullRequest
2 голосов
/ 17 февраля 2010

Мы пытаемся реализовать прокси-доказательство концепции, но столкнулись с интересным вопросом: поскольку одно HTTP-соединение может и действительно должно делать несколько запросов, а HTTP-транзакции отправляются через несколько пакетов из-за волшебства TCP,возможно ли, чтобы HTTP-запрос начинался в середине пакета?

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

Уточнение: мы знаем, что если мы будем работать только на уровне HTTP, нам не нужно беспокоиться об этом вопросе, однако мы пытаемся выяснить, можно ли применить какой-то продвинутый метод, работая на TCPслой первый.

Ответы [ 5 ]

3 голосов
/ 17 февраля 2010

Предполагая, что вы говорите о IP-пакетах: Да, возможно, HTTP-запрос начинается с середины IP-пакета.

Когда вы используете постоянные HTTP-соединения , то есть, используя одно и то же TCP-соединение для нескольких HTTP-запросов, вполне возможно, что граница запроса является серединой IP-пакета.

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

HTTP-запрос может также состоять из нескольких IP-пакетов (в случае загрузки файлов, ошибок передачи и последующих повторных передач и т. Д.).

Однако мне интересно, почему вы заинтересованы в пакетах, если вы работаете на уровне HTTP. TCP должен скрывать детали IP-пакета.

3 голосов
/ 17 февраля 2010

Прежде всего, TCP - это потоковый протокол, не имеющий понятия пакетов. Сам по себе HTTP может содержать какой-либо разделитель сообщений или записей, но TCP - нет.

Эта страница может быть полезна: Структура транзакций HTTP

Из вашего вопроса звучит так, как будто вы думаете, что каждое чтение из сокета TCP является "пакетом" данных. В действительности, каждое чтение просто читает столько байтов, сколько находится в буфере, до максимального запрошенного вами значения, без какой-либо концепции записей или пакетов.

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

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

0 голосов
/ 06 марта 2010

Мне кажется, я понимаю, куда вы пытаетесь обратиться с этим вопросом.

Если вы не используете постоянные соединения HTTP, заголовок запроса HTTP GET всегда является первой вещью, которая отправляется через TCPсоединение, поэтому мы можем быть уверены, что начало заголовка HTTP-запроса GET «не начинается в середине какого-либо TCP-пакета».Но имейте в виду, что может быть один или несколько пакетов TCP без каких-либо пользовательских данных, например, только SYN, который может предшествовать пакету TCP с началом заголовка запроса HTTP GET.Также имейте в виду, что заголовок запроса HTTP GET может не содержаться в одном пакете TCP.

Если вы используете постоянные соединения HTTP, начало заголовка запроса HTTP GET для номера запроса N + 1 можетначать в середине TCP-пакета, а именно после окончания HTTP-запроса GET, тело запроса номер N.

Если вы задаете эти вопросы, вы, возможно, «делаете это неправильно».Как уже отмечали несколько других респондентов, в подавляющем большинстве случаев вам, вероятно, следует просто быть TCP-клиентом, иметь дело с потоком данных TCP и позволить коду TCP беспокоиться о пакетах TCP.(Если, конечно, вы не работаете на каком-то специальном оборудовании, которое просматривает отдельные IP-пакеты, когда они пролетают, и пытается выполнить некоторую обработку на уровне HTTP.)

0 голосов
/ 22 февраля 2010

Если вы не реализуете свой собственный стек TCP, вам не нужно беспокоиться о пакетах, а скорее об API, который предоставляет TCP, в случае интерфейсов POSIX это будет recv () или read (). Поэтому я рассматриваю вопрос как «Может ли более одного HTTP-запроса поступить в один read (), и можно ли разделить HTTP-запрос на несколько запросов read ()?» - Ответ на оба вопроса будет «да, это возможно».

Примером того, где это может произойти, является HTTP pipelining . Это не часто встречается в реальной жизни (по иронии судьбы, по крайней мере, некоторые браузеры отключают его по умолчанию из-за «глючных прокси» :-) - но когда это происходит, пользователи могут столкнуться с проблемой диагностики - особенно если они не имеют доступа к прокси.

Одно очень заметное место, где это происходит по умолчанию apt-get в Linux-системах, производных от Debian. Просто установите сервер Debian или Ubuntu и попробуйте использовать его через прокси. Вы можете сделать это, отредактировав файл / etc / apt / apt.conf.d / proxy и разместив там следующее:

Acquire::http::Proxy "http://your.proxy.address:8080";
0 голосов
/ 17 февраля 2010

Зависит от того, какой уровень абстракции пакета вы говорите: под HTTP есть много уровней.

HTTP --> TCP (byte stream) --> IP (packet) --> (possibly something else) Ethernet (frame) --> (possibly) some other transport

Если вы говорите об уровне IP, то да, уровень HTTP будет запущен позже ... Обратите внимание, что TCP представляет «интерфейс потока байтов» на своем уровне клиентаследовательно, здесь нет понятия пакета.

...