AllesMeins: fsocketopen() Header und Inhalt trennen

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

  1. 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

    1. 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

      --
      Die SelfHTML-Developer sagen Dankeschön für aktuell 20885,68 Euro Spendengelder!
      1. 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

        1. 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

          --
          Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
          1. 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

            1. 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

              --
              Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
              1. 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