границы запроса HTTP - PullRequest
       20

границы запроса HTTP

1 голос
/ 04 марта 2011

Я пишу клиент для загрузки файлов через обычные http multipart / form-data в megaupload. Теперь дело не в мегаплатформе как таковой, а в поведении их веб-сервера.

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

После игры с необработанными сокетами и strace в течение некоторого времени выясняется, что единственное различие между ними состоит в том, что curl отправляет блок заголовка только с одним вызовом sendto (2), а затем остальные с другими вызовами sendto ( 2). Мой клиент, с другой стороны, отправляет каждый заголовок отдельно с записью (2).

Теперь sendto и write должны быть эквивалентны, если send не указывает какой-либо флаг, и это не так. Фактически я заставил его работать с записью, но только отправив блок заголовка за один вызов. Любая другая последовательность вызовов записи приводила к зависанию запроса в ожидании.

Итак, вопрос: как это вообще возможно? Tcp не сохраняет границы сообщений, это потоковый протокол.

Единственное, о чем я могу думать, это то, что каждый системный вызов write / send вызывает отправку пакета и что удаленный сервер прослушивает необработанные пакеты и лжет о том, что он apache.

Идеи? Или я идиот, и это нормальное поведение для совместимого http-сервера? Это первый веб-сервер, который ведет себя со мной так.

Ответы [ 2 ]

0 голосов
/ 10 июля 2011

Вопрос, указывающий на разницу между http и tcp. Я думаю, что весь заголовок http-запроса должен быть в одном tcp-сообщении. Попробуйте получить доступ к журналу ошибок отладки веб-сервера

0 голосов
/ 03 апреля 2011

Протокол http содержит механизмы, позволяющие клиенту / серверу определять границы сообщений. Для выгруженных данных (POST, PUT) требуется заголовок запроса длины содержимого или фрагментное кодирование. Длина содержимого позволяет серверу точно знать, сколько байтов нужно получить из сокета. Как только эти байты будут получены, они будут отправлены в другом направлении. Это фактически граница сообщения здесь. Chunked-кодирование также сообщает серверу, сколько байтов; только в нескольких частях.

Для ответа необязательна длина содержимого (или кусочная кодировка). Это также говорит клиенту, сколько байтов ожидать; это требуется для постоянных соединений для работы. Если длина содержимого не может быть определена, сервер просто закрывает сокет, тогда клиент знает, что у него есть полный ответ:)

...