Войти

Показать полную графическую версию : сокеты


E-mail
30-07-2006, 04:25
вот скажите мне, как через протокол 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, если запрашивать у меилру, будут соответственно другие символы, я пытаюсь понять как принимать контент без этих символов, они я так понимаю несут какуето служебную информацию

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

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


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

E-mail
30-07-2006, 17:55
vadimiron
мы не ищем легких путей:)
да дело на самом деле не в легком пути, просто этот протокол де факто, порядком уже устарел как никак более 10 лет спецификации,

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

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

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

vadimiron
30-07-2006, 18:44
и еще насколько понимаю размер не до а после куска идет
Нет, размеры должны до куска идти, какой смысл их в конец ставить

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

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

E-mail
30-07-2006, 19:02
106b4 - это рамер того что было до, следовательно цифра пишется после куска


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

вот именно, как можно знать цифру размера куска до подготовки к отправке:)

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

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

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

E-mail
30-07-2006, 20:16
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
vadimiron ну как там с примером?..

archy
09-08-2006, 15:22
Возможно следует обратить внимание на RFC 2616 Hypertext Transfer Protocol -- HTTP/1.1 (ftp://ftp.rfc-editor.org/in-notes/rfc2616.txt)

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
archy уже обратили внимание, работающий пример по алгоритму, есть те у кого получится или получился? :clapping:

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




© OSzone.net 2001-2012