fsocketopen() Header und Inhalt trennen
AllesMeins
- php
Hiho,
ich versuche gerade eine Datei (Bild oder HTML) per fsocketopen und GET von einem Server runter zu laden. Das klappt auch prima nur fehlt mir das nötige Hintergrundwissen um Inhalt und den mitgesendeten Header sicher voneinander zu trennen.
Meine erste Idee war am doppelten \r\n zu trennen, da ja eine Leere Zeile das ende vom Header ist. Doch dann ist mir aufgefallen das nach dem \r\n\r\n der eigentliche Inhalt noch nicht direkt beginnt, sondern erst noch eine Zeile mit einer dreistelligen Kombination (113 oder f1d) folgt.
Wie kann ich also sicher trennen (auch ich Hinsicht auf eventuelle Probleme wenn die empfangene Datei dieses Zeichen enthält (bsp. ich würde am \r\n\r\n trennnen, was wäre wenn jemand in eine Datei genau diese Kombination auch rein schreibt. )
Grüsse
Marc
Halihallo AllesMeins
ich versuche gerade eine Datei (Bild oder HTML) per fsocketopen und GET von einem Server runter zu laden. Das klappt auch prima nur fehlt mir das nötige Hintergrundwissen um Inhalt und den mitgesendeten Header sicher voneinander zu trennen.
http://ftp.ics.uci.edu/pub/ietf/http/rfc1945.html#Message
Meine erste Idee war am doppelten \r\n zu trennen, da ja eine Leere Zeile das ende vom Header ist. Doch dann ist mir aufgefallen das nach dem \r\n\r\n der eigentliche Inhalt noch nicht direkt beginnt, sondern erst noch eine Zeile mit einer dreistelligen Kombination (113 oder f1d) folgt.
Das muss ein anderer Fehler sein. Nach HTTP gibt es genau einen Delimiter für Message-Header und -Response: CRLF (\015\012) + natürlich das CRLF des letzten Headers. Der Delimiter ist also wirklich _eine einzige_ Leerzeile.
Wie kann ich also sicher trennen (auch ich Hinsicht auf eventuelle Probleme wenn die empfangene Datei dieses Zeichen enthält (bsp. ich würde am \r\n\r\n trennnen, was wäre wenn jemand in eine Datei genau diese Kombination auch rein schreibt. )
Wie gehabt: Trenne bei dem ersten CRLFCRLF. Dies entspricht _nicht_ \r\n! - Benutze "\015\012\015\012". Alles, was nach dem CRLFCRLF folgt _ist_ die Datei, es spielt also keine Rolle, wenn dort nochmals CRLFCRLF folgt. Das erste Auftreten von CRLFCRLF ist entscheidend.
Viele Grüsse
Philipp
Moin!
Meine erste Idee war am doppelten \r\n zu trennen, da ja eine Leere Zeile das ende vom Header ist. Doch dann ist mir aufgefallen das nach dem \r\n\r\n der eigentliche Inhalt noch nicht direkt beginnt, sondern erst noch eine Zeile mit einer dreistelligen Kombination (113 oder f1d) folgt.
Das muss ein anderer Fehler sein.
Nein, das muß HTTP/1.1 und chunked Output sein. Da werden nämlich einzelne Bröckchen der Ausgabe gesendet, jeweils mit einer vorlaufenden Zeile, die die jeweiligen Bytes des Brockens angibt.
- Sven Rautenberg
Halihallo Sven
Das muss ein anderer Fehler sein.
Nein, das muß HTTP/1.1 und chunked Output sein. Da werden nämlich einzelne Bröckchen der Ausgabe gesendet, jeweils mit einer vorlaufenden Zeile, die die jeweiligen Bytes des Brockens angibt.
RFC 2616, 3.6.1 Chunked Transfer Coding
All HTTP/1.1 applications MUST be able to receive and decode the
"chunked" transfer-coding, and MUST ignore chunk-extension
extensions
they do not understand.
Es war ein/sein Fehler :-)
Viele Grüsse
Philipp
Hello Sven, hello Philipp,
Das muss ein anderer Fehler sein.
Nein, das muß HTTP/1.1 und chunked Output sein. Da werden nämlich einzelne Bröckchen der Ausgabe gesendet, jeweils mit einer vorlaufenden Zeile, die die jeweiligen Bytes des Brockens angibt.RFC 2616, 3.6.1 Chunked Transfer Coding
All HTTP/1.1 applications MUST be able to receive and decode the
"chunked" transfer-coding, and MUST ignore chunk-extension
extensions
they do not understand.Es war ein/sein Fehler :-)
Habe hier mitgelesen und frage zur Sicherheit nochmals nach. Muss man bei HTTP/1.1 also nun immer dieses "Längenbyte" beachten und wie groß kann so ein Brocken werden? Oder woraus erkennt men diesen Sendemodus?
Werden da dann nur noch Datenbrocken gesendet oder kommt jedes Mal ein vollständiger Header davor?
Liebe Grüße aus http://www.braunschweig.de
Tom
Halihallo Tom
Habe hier mitgelesen und frage zur Sicherheit nochmals nach. Muss man bei HTTP/1.1 also nun immer dieses "Längenbyte" beachten
Nur bei der Transfer-Encoding: chunked. Ein Beispiel wie dort das
ganze Entity wiederhergestellt wird steht als Pseudo unter:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.4.6
Aber: Wie im letzten Post zittiert: Jede HTTP/1.1 Application MUSS
"chunked" transfer-coding empfangen und dekodieren müssen. Falls
also ein entsprechender Header in der Response steht, muss dein
Programm auch damit umgehen können, oder aber du verwendest HTTP/1.0.
und wie groß kann so ein Brocken werden? Oder woraus erkennt men diesen Sendemodus?
Erkennen kann man ihn über den entsprechenden Header in der Response
("Transfer-Encoding: chunked"). Die Länge ist in der RFC nicht
beschränkt: RFC 2616, 14.39:
Note: HTTP/1.1 does not define any means to limit the size
of a chunked response such that a client can be assured of
buffering the entire response.
Werden da dann nur noch Datenbrocken gesendet oder kommt jedes Mal ein vollständiger Header davor?
Nun, normalerweise nicht. Es gibt die TE-"Option" 'trailer', welche
IMHO bedeutet, dass jedem chunk ein Header vorangeht.
... soweit ich die RFC jetzt gelesen habe...
Viele Grüsse
Philipp
Hello Philipp,
Werden da dann nur noch Datenbrocken gesendet oder kommt jedes Mal ein vollständiger Header davor?
Nun, normalerweise nicht. Es gibt die TE-"Option" 'trailer', welche
IMHO bedeutet, dass jedem chunk ein Header vorangeht.... soweit ich die RFC jetzt gelesen habe...
Das heißt also erstmal wieder: Nichts ist unmöglich...
Na danke auf jeden Fall für Deine ausführliche Antwort. Ich werde versuchen, es bei den betroffenen Scripten zu berücksichtigen. Hoffentlich denke ich dran.
Liebe Grüße aus http://www.braunschweig.de
Tom
Halihallo Tom
Na danke auf jeden Fall für Deine ausführliche Antwort. Ich werde versuchen, es bei den betroffenen Scripten zu berücksichtigen. Hoffentlich denke ich dran.
Nun, also ich handhabe es so, dass ich gar nicht erst eine HTTP/1.1
Anfrage sende, sondern "nur" HTTP/1.0 verwende. Das Leben ist
leichter :-)
Viele Grüsse
Philipp