Скрипт очень долго считывает информацию через сокет.

Тимур

Новичок
Скрипт очень долго считывает информацию через сокет.

Пишу простенький прокси-сервер для себя.
PHP:
$s=fsockopen($host,$port,$errno,$errstr,30);
       if (!$s)
       {
        echo "$errstr ($errno)<br>\n";
       }
       else
       {
        fputs($s,"GET $url HTTP/1.1\r\n");
        fputs($s,"Accept: */*\r\n");
        fputs($s,"Referer: $referer\r\n");
        fputs($s,"Accept-Language: ru\r\n");
        fputs($s,"Accept-Encoding: gzip, deflate\r\n");
        fputs($s,"User-Agent: $user-agent\r\n");
        fputs($s,"Host: $host\r\n");
        fputs($s,"Connection: Keep-Alive\r\n\r\n");
        while(!feof($s)) $content.=fgets($s,1024);
        fclose($s);
       }
Скрипт выполняется около 15 секунд! И это явно не из-за размера запрашиваемой странички. Какой бы url не запрашивал все время около 15 секунд.
Посмотрел ответ сервера на запрос. Там есть такая строчка:
Keep-Alive: timeout=15, max=100
У меня такое предположение: в цикле считывается информация, но не находится конец файла. и через 15 секунд сервер разрывает соединение.
Вопрос: Как сделать так, чтобы скрипт выдовал ответ не через 15 секунд, а сразу как скачает полностью документ?
 

master_x

Pitavale XXI wieku
что за пременная такая $user-agent?

-~{}~ 19.10.05 15:59:

вообще что утебя в таком случае лежит в $user? подозреваю, что что-то здесь ты неправильно используешь.
 

Andreika

"PHP for nubies" reader
Тимур
сделать Connection: Close вместо Keep-Alive
эт если совсем просто.. )
 

master_x

Pitavale XXI wieku
не бывает такой переменной $user-agent. Ты ее именно так и инициализировал? да, зачем спрашиваю, ты просто не мог ее так инициализировать, потому как скрипт отвалится с парсеррор. Ты в этом коде $user-agent=$HTTP_USER_AGENT; пытешься сначала отнять от $user константу agent а потом приравнять ко всему этому $HTTP_USER_AGENT. В общем лови ошибки, которые тебе пхп вываливает.
 

Andreika

"PHP for nubies" reader
master_x
если таки у него парсер не выпадает, то в худшем случае у него юзерагент будет равен -agent, что совсем не критично
 

master_x

Pitavale XXI wieku
значит не надо мне рассказывать про вот это:
$user-agent=$HTTP_USER_AGENT;
 

Тимур

Новичок
Andreika, спасибо! Работает, но можно ли добиться этого результата без изменения http заголовков?
А то через $HTTP_CONNECTION всё видно - нормальные браузеры используют Keep-Alive.

-~{}~ 19.10.05 16:48:

master_x, пардон $user_agent=$HTTP_USER_AGENT;
 

Andreika

"PHP for nubies" reader
Тимур
хттп-коннекшн- Keep-Alive указывает серверу по возможности не разрывать соединение и за эти 15 секунд может послать еще один запрос, не тратя время на новое соединение с сервером т.е. тебе после прихода всех данных еще прийдется читать новый запрос браузера и повторять все с начала... как ты это в своем пхп-прокси реализуешь даж не знаю..
 

Andreika

"PHP for nubies" reader
а насчет определения пришли все данные или нет надо смотреть ответ сервера Conent-Length: размер или Transfer-Encoding: chunked - отдаваться будет частями, далее в описание протокола HTTP учиться склеивать кусочки )
 

Тимур

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

-~{}~ 19.10.05 17:17:

Э... ответ получил.

-~{}~ 19.10.05 17:47:

я тут заметил, что не всегда сервер указывает content-length:
HTTP/1.1 200 OK
Date: Fri, 30 Sep 2005 13:32:57 GMT
Server: sensored
Pragma: No-Cache
Set-Cookie: JSESSIONID=C449E7A12D982DB5D04556A7F6061DBD; Path=/
Keep-Alive: timeout=15, max=25
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: image/jpeg

И сколько байт считывать?
А может пользоваться методом "в лоб" считать первые 1.000.000 байт? надеюсь лишний траффик накручиваться не будет?
 

tony2001

TeaM PHPClub
см. мой пост.

>А может пользоваться методом "в лоб" считать первые 1.000.000 байт?
для того, чтобы что-то "считывать", сначала нужно чтобы кто-то это "выдал".
 

Andreika

"PHP for nubies" reader
tony2001
а разве $data_block = fread($s, 4096) когда прочитает все данные не будет ждать разъединения?
 

whirlwind

TDD infected, paranoid
> Можно сделать не меняя заголовков?
Нет. На сервер - "Connection: close", Клиенту - при "Transfer-Encoding: chunked" д.б. заменен на "Content-Length: Х" или просто удален.
 

Тимур

Новичок
tony2001
Это вот так, что ли?
while ($data_block=fread($s, 4096)) { $cont .= $data; };
Так, если оставить Connection: Keep-Alive скрипт опять будет только через 15 секунд выдовать результат.
 

whirlwind

TDD infected, paranoid
Да. Сервер будет ждать некоторое время следующий запрос, а цикл while не завершится пока не будет EOF.
 
Сверху