HTTP длина сообщения ?

Тема в разделе "WASM.NETWORKS", создана пользователем Exception13, 26 дек 2007.

  1. Exception13

    Exception13 New Member

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    66
    Адрес:
    Владимир
    Столкнулся с проблемой при написании HTTP снифера:
    Иногда приходят HTTP ответы ( нормальные с кодом 200 ), т.е. которые предполагают существование тела сообщения, причем они не содержат ни поле Content-Length, ни поле Transfer-Encoding и как определить длинну передаваемой информации - х.з.
    Вот, пример такого заголовка:

    HTTP/1.1 200 OK
    Date: Mon, 17 Sep 2007 13:54:51 GMT
    Server: Apache/1.3.37 (Unix) mod_ssl/2.8.28 OpenSSL/0.9.8d mod_gzip/1.3.26.1a mod_fastcgi/2.4.2 PHP/4.4.7 mod_perl/1.29 rus/PL30.22
    Vary: Accept-Encoding
    Connection: close
    Content-Type: text/html

    <html>
    <head>
    ...................................................................................
    Или же если указано Connection: close - то всасываем все данные что нам передают до тех пор пока соединение существует, т.е. до обмена маркерами FIN ?
     
  2. Proteus

    Proteus Member

    Публикаций:
    0
    Регистрация:
    19 июн 2004
    Сообщения:
    344
    Адрес:
    Russia
    Ну так всё и определяют на самом деле. Всё кроме Host: в пакете, в реальной жизни поля опциональные и не обязательные. Если ты качаешь файл, то ты качаешь до тех пор пока соедидение не будет закрыто.

    Т.е. если recv вернул -1 , произошла ошибка передачи или разрыв соединения. Если recv вернул 0, то соединение было нормально закрыто (через FIN) и файл докачан. Если сервер на пол пути передумает отдавать тебе файл, то у в сокетах есть способ закрыть соединение с ошибкой на другой стороне.

    Короче жди нуля, а на длину не смотри...
     
  3. Exception13

    Exception13 New Member

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    66
    Адрес:
    Владимир
    Могу вас разочаровать - во первых - это не по стандарту и не до конца правильно, т.к. в пределах одной TCP сессии может быть передано сколь угодно много запросов и ответов.

    Вот, кстати еще пример заголовка, уже без указания Connection: close

    HTTP/1.0 200 OK
    Date: Mon Sep 17 17:54:53 2007
    Cache-control: no-cache, max-age=0, must-revalidate, no-store
    Pragma: no-cache
    Expires: Thu, 01 Jan 1970 00:00:00 GMT
    P3P: policyref="/w3c/p3p.xml", CP="NON CUR ADM DEV PSA PSD OUR IND UNI NAV INT STA"
    Set-Cookie: uid=928277860; expires=Wednesday, 01-Jan-2020 00:00:00 GMT;path=/;domain=.adriver.ru
    Content-type: text/html

    <head></head>
    <body bgcolor="#FFFFFF" topmargin="0" leftmargin="0" marginwidth="0" marginheight="0" scroll="no">
    .........................................................................................
    Вобщем, фиг знает как это может понимать браузер ? по крайней мере я этого не понимаю.

    На счет поля Host - оно указывается только в запросах и то не всегда, так что оно тоже опциональное. бывают ответы вообще замечательные:
    HTTP/1.0 200 OK
    и все...
    Ну, конечно, на такие кладу болт, но те примеры которые я привел их как то обрабатывает браузер ?
     
  4. Proteus

    Proteus Member

    Публикаций:
    0
    Регистрация:
    19 июн 2004
    Сообщения:
    344
    Адрес:
    Russia
    Ну я не знаю как там по стандарту. Зато видел как пишут серверы и браузеры. Любая программа ориентируется на нормальное закрытие соединения. Программы которые не разрывают соединение, кажется пишут в ответном заголовке Connection: keep-alive. Но как я понимаю никто не мешает им попросту этого не делать. Это от софта зависит. Иногда в таких случаях концов считается двойная пустая строка.
    Можно сделать так чтобы сниффер реагировал на изменение направления потока. Если передаётся новый запрос, то передача ответа надо полагать запрещена.....

    Ну а забить болт - это самый правильный поступок. Ситуация когда HTTP работает без разрыва, крайне редка и если встречается где-то, то только не в браузерах....
     
  5. Exception13

    Exception13 New Member

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    66
    Адрес:
    Владимир
    О, кстати, вот это я еще не проверял, на счет двойной пустой !

    Нет, такой номер не пройдет, т.к. это асинхронный протокол:
    например, HTTP может работать так:

    G1-G2-G3-G4- H1 - HD1 - HD2 - G5 - HD3 - H2 - H3 - H4 - H5,

    где G# - запрос ( например GET и его порядковый номер )
    H# - ответ на запрос с номером #
    HD# - продолжение ответа на запрос с номером #

    как видно из диаграммы запрос G5 "как бы" разрывает поток данных ответа.
    Почему "как бы", потому что необходимо рассматривать отдельно входящий и исходящий потоки, тогда подобного разрыва мы уже не увидим.

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

    TarasCo New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2005
    Сообщения:
    106
    сервера бывают такие кривые, что просто удивительно, как броузеры с ними работают. Например, мне попался как то на глаза сервак, который строчки разделял через \n, а не \r\n. Они могут быть запросто чувствительными к регистру полей. Они могут забывать закрывать соединение. Короче, они могут делать все, что им угодно :)))).

    Во поводу первого запроса, там формально все правильно - указано Connection: close и конец сообщения можно определить по концу соединения

    По поводу второго - обратите внимание еще на строку HTTP/1.0 - версия не 1.1. В 1.0 по моему нельзя было передавать пачками запросы и.т.п. В любом случае, вежливо завершение соединения сервером - самый надежный признак конца данных.
     
  7. Exception13

    Exception13 New Member

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    66
    Адрес:
    Владимир
    Наблюдал, учтено.
    тоже учел.

    действительно и как это все работает до сих пор ?...

    Бааальшое спасибо за информацию, будут еще мнения - высказывайтесь, всяко лучше чем одна голова :)
     
  8. Proteus

    Proteus Member

    Публикаций:
    0
    Регистрация:
    19 июн 2004
    Сообщения:
    344
    Адрес:
    Russia
    Нагнал я похоже про дополнительную пустую строку. Там в ответах заголовков может быть некое поле Transfer-Encoding: chunked. В таком случае указывать длину не надо. Данные передаются какими-то кусками хитрого формата и определить их размер и конец данных можно каким-то соотвествующим способом. А вот как это всё работает подробнее, я не понял пока что. Ща покурю RFC или дамбы, может пойму....
     
  9. Proteus

    Proteus Member

    Публикаций:
    0
    Регистрация:
    19 июн 2004
    Сообщения:
    344
    Адрес:
    Russia
    Всё крайне просто.
    Каждый блок начинается с текстовой записи шеснадцатеричной цифры, которая указывает размер данных блока. После чего идёт перевод строки и блок данных (после цифры кажется могут быть пробелы и всякая херня). После блока данных опять идёт перевод строки. И цифра с размером следующего блока.
    Последний блок имеет нулевой размер, и тоже как бы содержит перевод строки, до и после данных (т.е. '0' и две пустых строки).
     
  10. JAPH

    JAPH New Member

    Публикаций:
    0
    Регистрация:
    23 июн 2007
    Сообщения:
    124
    а что есть trailers?
     
  11. Proteus

    Proteus Member

    Публикаций:
    0
    Регистрация:
    19 июн 2004
    Сообщения:
    344
    Адрес:
    Russia
    В том месте где я сижу сейчас, никаких док под рукой нету. Поточнее нельзя сформулировать вопрос?))).
     
  12. JAPH

    JAPH New Member

    Публикаций:
    0
    Регистрация:
    23 июн 2007
    Сообщения:
    124
    Клиент серверу:
    Код (Text):
    1. Connection: Keep-Alive; TE
    2. TE: identity, chunked, trailers
    Что есть trailers?
     
  13. Proteus

    Proteus Member

    Публикаций:
    0
    Регистрация:
    19 июн 2004
    Сообщения:
    344
    Адрес:
    Russia
    В rfc2616 написано. Можно повникать)) но у меня уже новый год..
     
  14. Exception13

    Exception13 New Member

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    66
    Адрес:
    Владимир
    Это все ясно и уже реализовано, в самом первом посте еще упомянул, в RFC2616 описано. Вобщем, все как сказал Proteus.
    Trailers - это кусок HTTP заголовка который может присутствовать в сообщении у которого Transfer-Encoding: chunked
    Т.е. после блока с нулевой длинной "0" - могут присутствовать еще какие-либо поля заголовка, за исключением следующих полей:
    Transfer-Encoding,
    Content-Length,
    Trailer.