Problem mit fsockopen/fread

Hallo NG,

wenn ich mit fsockopen und fread den Inhalt einer Webseite einlese, dann
habe ich das Problem, dass ab und zu in den Daten welche mir fread
zurückliefert Markierungen enthalten sind welche anscheinend die Anzahl
Bytes bis zur nächsten Markierung enthalten (eventuell Chunk-Markierungen?).

Symbolisch sieht das Ganze dann so aus ([header] sind die
Response-Headers und [html] sind HTML-Fragmente in verschiedenen Größen):

<response>
[header]

f39
[html]
3073
[html]
17d
[html]

0

</response>

Der benutzte Code um mit fread den Socket-Stream auszulesen:

<code>
do
{
$status = socket_get_status($this->socket);
if ($status["eof"] == 1)
{
break;
}
if ($status["unread_bytes"] > 0)
{
$buffer = fread($this->socket, $status["unread_bytes"]);
$c = 0;
}
else
{
$buffer = fread($this->socket, 128);
$c++;
usleep(10);
}
$data .= $buffer;
} while (($status["unread_bytes"] > 0) || ($c++ < 10));
</code>

Mach ich was falsch? Kann man das deaktivieren? Ist das Verhalten
"Behavior by Design"? Muss ich die Markierungen selber rausfummeln?

Joe
Joe Scylla [ Do, 22 November 2007 12:24 ] [ ID #1876782 ]

Re: Problem mit fsockopen/fread

Joe Scylla schrieb:

> wenn ich mit fsockopen und fread den Inhalt einer Webseite einlese, dann
> habe ich das Problem, dass ab und zu in den Daten welche mir fread
> zurückliefert Markierungen enthalten sind welche anscheinend die Anzahl
> Bytes bis zur nächsten Markierung enthalten (eventuell
> Chunk-Markierungen?).

Das musst du doch selber am besten wissen, mit welchem Protokoll du da
hantierst und wie dort einzelne Chunks markiert sind.

> Symbolisch sieht das Ganze dann so aus ([header] sind die
> Response-Headers und [html] sind HTML-Fragmente in verschiedenen Größen):

> <response>
> [header]
>
> f39
> [html]
> 3073
> [html]
> 17d
> [html]
>
> 0
>
> </response>

Das hab ich so noch nie gesehen. Multipart-Content-Type (RFC1341) sähe
in etwa so aus:

Content-Type: multipart/mixed; boundary=34327asd7a9d7as9das7

--34327asd7a9d7as9das7
X-Further-Headers: Yeah
Content-Type: text/html

Some text.

--34327asd7a9d7as9das7
....

Was ist das denn für ein Server der die Daten sendet?

> Der benutzte Code um mit fread den Socket-Stream auszulesen:

Du solltest nicht 'unread_bytes' verwenden. Wenn du den Stream lesen
willst bis nichts mehr kommt, dann musst du eben warten bis es zu einem
Timeout kommt oder im Vorfeld ermitteln wieviel Daten der Server senden
wird. Das geht nicht anders. Aber sollte deine Vermutung stimmen, dann
hat du die Länge ja schon gefunden :)

> Mach ich was falsch? Kann man das deaktivieren? Ist das Verhalten
> "Behavior by Design"? Muss ich die Markierungen selber rausfummeln?

Deaktivieren kannst du das wenn überhaupt dort, wo der Crap generiert
wird. PHP baut diese Markierungen nicht einfach so in den Stream ein,
wäre ja auch bescheuert. Ich würde mich erstmal informieren was das für
ein Protokoll ist und welchen Nutzen die Markierungen haben. Vielleich
hat es ja auch gar nichts mit dem Protokoll zutun und die Markierungen
sind einfach nur Teil des Dokuments. Dann bleibt dir wohl nichts anderes
übrig als sie rauszufriemeln, wenn du mehrere Dateien erzeugen willst.

--
"Faulheit ist die Wurzel allen Fortschritts!"
(Inhalt eines Knallbonbons, 2002)
dafox [ Do, 22 November 2007 12:54 ] [ ID #1876783 ]

Re: Problem mit fsockopen/fread

Thomas Hamacher wrote:
> Joe Scylla schrieb:
>
> ... snipped ...
> Du solltest nicht 'unread_bytes' verwenden. Wenn du den Stream lesen
> willst bis nichts mehr kommt, dann musst du eben warten bis es zu einem
> Timeout kommt oder im Vorfeld ermitteln wieviel Daten der Server senden
> wird. Das geht nicht anders. Aber sollte deine Vermutung stimmen, dann
> hat du die Länge ja schon gefunden :)

Gut möglich, dass der Code "semi-optimal" ist, weil diese API zum ersten
mal so benutze. Eventuelle Unzulänglichkeiten muss ein Code-Review
aufräumen ;)

> ...snipped...
> Deaktivieren kannst du das wenn überhaupt dort, wo der Crap generiert
> wird. PHP baut diese Markierungen nicht einfach so in den Stream ein,
> wäre ja auch bescheuert. Ich würde mich erstmal informieren was das für
> ein Protokoll ist und welchen Nutzen die Markierungen haben. Vielleich
> hat es ja auch gar nichts mit dem Protokoll zutun und die Markierungen
> sind einfach nur Teil des Dokuments. Dann bleibt dir wohl nichts anderes
> übrig als sie rauszufriemeln, wenn du mehrere Dateien erzeugen willst.
>

Ich hab die Antwort inzwischen gefunden im RFC für HTTP/1.1. Das
Verhalten ist "Behavior by Design" wenn das "Transfer Encoding" auf
"chunked" steht.
Nach RFC muss auch jeder Client diesen Transfermodus beherrschen.

Quelle: http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6 .1

Das bedeutet dann, dass ich diese Markierungen manuell entfernen muss.

Joe
Joe Scylla [ Do, 22 November 2007 13:01 ] [ ID #1876784 ]

Re: Problem mit fsockopen/fread

Joe Scylla schrieb:
> Hallo NG,
>
> wenn ich mit fsockopen und fread den Inhalt einer Webseite einlese, dan=
n
> habe ich das Problem, dass ab und zu in den Daten welche mir fread
> zur=C3=BCckliefert Markierungen enthalten sind welche anscheinend die A=
nzahl
> Bytes bis zur n=C3=A4chsten Markierung enthalten (eventuell
> Chunk-Markierungen?).

Es fehlt ja ein bisschen Code von dir darum gucke ich mal in meine
Glaskugel.

Du machst eine HTTP/1.1 Anfrage und gibst damit dem Webserver das Recht
"Chunk Decoding" zu benutzen was er dann auch verwendet. Mach das
gleiche mal nur mit HTTP/1.0 [1] und der Webserver darf das dann nicht
mehr machen.

Andernfalls gucke in der RFC nach wie du das encodierst.


[1] Die Praxis zeigt das auch bei HTTP/1.0 die Server den Host Header
ausferten auch wenn der erst spaeter dazu kam. Der alte NS4.x konnte nie =

HTTP/1.1 und denoch funkt. es mit Namebased Hosts.

Gruss
Joerg


--
TakeNet GmbH, Geschaeftsfuehrer Wolfgang Meier
97080 Wuerzburg Tel: +49 931 903-2243
Alfred-Nobel-Stra=C3=9Fe 20 Fax: +49 931 903-3025
HRB Wuerzburg 6940 http://www.takenet.de
Joerg Behrens [ Do, 22 November 2007 13:06 ] [ ID #1876785 ]
PHP » de.comp.lang.php.misc » Problem mit fsockopen/fread

Vorheriges Thema: pfd AddTextWrap Problem
Nächstes Thema: Darstellung sehr großer Zahlen