Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Вебмастеру (http://forum.oszone.net/forumdisplay.php?f=22)
-   -   сокеты (http://forum.oszone.net/showthread.php?t=69157)

E-mail 30-07-2006 04:25 466254

сокеты
 
вот скажите мне, как через протокол http 1.1 снять копию контента с удаленного web сервера, без дополнений и изменений считывая построчно функцией

fgets($f,1024);

если сервер не отдает content-lenght и использует кодирование Transfer-Encoding: chunked ??

вот вам и пример ответа этого форума:

Код:

HTTP/1.1 200 OK
Date: Sun, 30 Jul 2006 00:03:36 GMT
Server: Apache/1.3.34 (Unix) mod_accounting/0.5 PHP/4.4.2
X-Powered-By: PHP/4.4.2
Set-Cookie: ***
Set-Cookie: ***
Set-Cookie: ***
Expires: 0
Cache-Control: private, post-check=0, pre-check=0, max-age=0
Pragma: no-cache
Transfer-Encoding: chunked
Content-Type: text/html; charset=Windows-1251

106b4
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html dir="ltr" lang="ru">
<head>
        <!-- no cache headers -->
        <meta http-equiv="Pragma" content="no-cache" />

</script>
</body>
</html>
0

как видно выше, появляются символы 0 и 106b4, если запрашивать у меилру, будут соответственно другие символы, я пытаюсь понять как принимать контент без этих символов, они я так понимаю несут какуето служебную информацию

ведь браузер и прокси както избавляются от этих символов перед выдачей на экран, но как??((

сам скрипт запроса ниже, возможно его надо дополнить для решения этой задачи, но чем??

PHP код:

$f=fsockopen("forum.oszone.ru","80",80);
fputs($f,"GET http://forum.oszone.ru HTTP/1.1\r\nHost: forum.oszone.ru\r\n\r\n");
while(!
feof($f))
{
    
$tmp=fgets($f,1024);
    
$content    .=    $tmp;
}
fclose($f);

echo 
$content


vadimiron 30-07-2006 14:11 466301

E-mail
А обязательно нужно по HTTP 1.1 запрашивать??
Я например в основном делаю запросы по версии 1.0, там например нет всех этих проблем с chunked

E-mail 30-07-2006 17:55 466335

vadimiron
мы не ищем легких путей:)
да дело на самом деле не в легком пути, просто этот протокол де факто, порядком уже устарел как никак более 10 лет спецификации,

да и там вообще ничего нет почти, к счастью нужно через http 1.1 .. в общем не до комца еще разобрался с этим алгоритмом передачи, что делать когда сервер не отдает длину тела..

vadimiron 30-07-2006 18:11 466339

E-mail
Да длинну тела то не обязательно знать, читай пока сокет чтото возвращает и всё (но это конечно только для 1.0)
Другое дело как обходиться с Transfer-Encoding: chunked
Фишка в том, что это число (106b4) и есть размер, но вроде в восмиричной системе
Ноль в конце означает, что больше нет данных для передачи. То есть можно сообщение на много кусков разбить, какждый кусок начинается с размера куска, потом <CR><LF>, далее сам кусок, и так далее... а заканчивается на 0<CR><LF>

E-mail 30-07-2006 18:31 466344

vadimiron в 16-ричной,
я пытаюсь понять по какому алгоритму браузеры и прокси обрезают эти размеры кусков, они для каждой страницы свои, и кусков для каждой страницы свое количество и еще насколько понимаю размер не до а после куска идет

vadimiron 30-07-2006 18:44 466351

Цитата:

и еще насколько понимаю размер не до а после куска идет
Нет, размеры должны до куска идти, какой смысл их в конец ставить

Цитата:

я пытаюсь понять по какому алгоритму браузеры и прокси обрезают эти размеры кусков,
А что не понятного? Браузер видит в загаловке, что тело будет chunked, поэтому он после всех хедеров читает по принципу:
сначало берём строчку до первого <CR><LF>, эта строчка является размером куска, далее читаем столько символов, на сколько этот размер указывает, далее снова читаем строчку с размером и тд..... если строчка с размером равна 0, значит больше не читаем

Кстати, эту всю историю с Transfer-Encoding: chunked как раз придумали, чтобы отсылать куски ещё неполностью сгенерированного документа, поэтому полный размер и нельзя знать.

E-mail 30-07-2006 19:02 466359

106b4 - это рамер того что было до, следовательно цифра пишется после куска


Цитата:

Кстати, эту всю историю с Transfer-Encoding: chunked как раз придумали, чтобы отсылать куски ещё неполностью сгенерированного документа, поэтому полный размер и нельзя знать.
вот именно, как можно знать цифру размера куска до подготовки к отправке:)

как ты отделишь размер куска от самого куска пример к скрипту в студию можно?)
например к меилру

vadimiron 30-07-2006 19:19 466366

E-mail
Цитата:

106b4 - это рамер того что было до, следовательно цифра пишется после куска
Не-а, в начале. Размер куска мы то знаем, который посылаем, единственно. что мы не знаем, так это размер всего сообщения, то есть размер всей страницы. Чтобы не ждать генерацию всей страницы, можно посылать то, что уже сгенерированно.

Код могу завтра написать, смысл прост: после хедеров читаем с помощью fgets строку с размером куска, далее обычный fread c размером куска, полученным с помощью fgets и тд до нуля

E-mail 30-07-2006 20:16 466392

vadimiron

Цитата:

Не-а, в начале
длдинна вот этого:

Код:

HTTP/1.1 200 OK
Date: Sun, 30 Jul 2006 00:03:36 GMT
Server: Apache/1.3.34 (Unix) mod_accounting/0.5 PHP/4.4.2
X-Powered-By: PHP/4.4.2
Set-Cookie: ***
Set-Cookie: ***
Set-Cookie: ***
Expires: 0
Cache-Control: private, post-check=0, pre-check=0, max-age=0
Pragma: no-cache
Transfer-Encoding: chunked
Content-Type: text/html; charset=Windows-1251

равна вот этому 106b4

если так -> значит после:)

Цитата:

после хедеров читаем с помощью fgets строку с размером куска, далее обычный fread
у меня freead не пригодился (см. выше)

очень интересно посмотреть на рабочий пример

E-mail 05-08-2006 00:21 468460

vadimiron ну как там с примером?..

archy 09-08-2006 15:22 470068

Возможно следует обратить внимание на RFC 2616 Hypertext Transfer Protocol -- HTTP/1.1
Код:

      Chunked-Body  = *chunk
                        last-chunk
                        trailer
                        CRLF

      chunk          = chunk-size [ chunk-extension ] CRLF
                        chunk-data CRLF
      chunk-size    = 1*HEX
      last-chunk    = 1*("0") [ chunk-extension ] CRLF

      chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
      chunk-ext-name = token
      chunk-ext-val  = token | quoted-string
      chunk-data    = chunk-size(OCTET)
      trailer        = *(entity-header CRLF)

Судя по этому куску vadimiron прав

E-mail 12-08-2006 14:36 471275

archy уже обратили внимание, работающий пример по алгоритму, есть те у кого получится или получился? :clapping:

интересно на php perl или #asp


Время: 16:24.

Время: 16:24.
© OSzone.net 2001-