HTTP POST



  • Hi,

    ich habe da mal eine kleine Verständnisfrage zu HTTP POST.
    Mal ein kleines Beispiel mit boundary:

    POST /upload.html HTTP/1.1
    Host: 192.168.0.118
    User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-us,en;q=0.5
    Accept-Encoding: gzip, deflate
    Connection: keep-alive
    Referer: http://192.168.0.118/
    Content-Length: 302
    Content-Type: multipart/form-data; boundary=---------------------------73761393126308
    Pragma: no-cache
    Cache-Control: no-cache
    
    -----------------------------73761393126308
    Content-Disposition: form-data; name="filename"; filename="New Text Document.txt"
    Content-Type: text/plain
    
    [---DATEIINHALT---]
    -----------------------------73761393126308--
    

    Hier gibt es einige Dinge die ich nicht logisch finde. z.B. ist Content-Length nicht die Länge der Datei, sondern die Länge vom Anfang bis einschließlich dem Ende des Boundary. Ok, den Anfang der Datei kann man leicht finden. Aber das Ende? De facto könnte das Boundary auch in der Datei vorkommen*, dementsprechend ist Content-Length eigentlich das Einzige, an dem man sich orientieren kann. Aber Content-Length ist nicht eindeutig! Beim IE z.B. kommt da am Ende noch mehr dazu. Was soll der Quatsch? Habe ich irgendetwas übersehen? (Lustig: Hier steht die Content-Length logisch: https://developer.mozilla.org/en/FileGuide/FileUpDown)

    * Es ist natürlich unwahrscheinlich, aber irgendwie kann ich nicht glauben, dass die das Protokoll so entworfen haben, dass man sich darauf verlassen soll. 🙄



  • z.B. ist Content-Length nicht die Länge der Datei, sondern die Länge vom Anfang bis einschließlich dem Ende des Boundary.

    Das liegt daran, dass sich HTTP soweit ich weiss nicht darum schert dass das File ein MIME-multipart File ist.
    Für HTTP ist das ein ganz normales File, daher schliesst Content-Length auch die MIME-multipart-Boundary mit ein.

    Man kann ja auch andere MIME-Typen POSTen als multipart/form-data - soweit ich weiss gibt es da seitens HTTP keine Restriction.

    Ok, den Anfang der Datei kann man leicht finden. Aber das Ende? De facto könnte das Boundary auch in der Datei vorkommen*,

    * Es ist natürlich unwahrscheinlich, aber irgendwie kann ich nicht glauben, dass die das Protokoll so entworfen haben, dass man sich darauf verlassen soll. 🙄

    Kleiner Tip: das Programm das die Files in ein MIME-multipart verpackt kennt ja den Inhalt aller Files. Daher ist es für dieses Programm auch relativ einfach eine Boundary zu erzeugen die in keinem File vorkommt - sowas liesse sich im Falle des Falles ja überprüfen. Die meisten Programme werden freilich darauf verzichten, und statt dessen einfach eine GUID erzeugen (oder wie in 1000 schlechten Beispielen eine noch kürzere Zufallszahl verwenden). Grundsätzlich ist es aber kein "Fehler" im MIME-multipart Standard (und schon gar nicht im HTTP Protokoll, das damit ja nix zu tun hat), sondern nur etwas was ... sagen wir mal umständlicher gemacht wurde als es nötig gewesen wäre.

    Aber Content-Length ist nicht eindeutig! Beim IE z.B. kommt da am Ende noch mehr dazu. Was soll der Quatsch? Habe ich irgendetwas übersehen?

    Wo? Was kommt dazu? Beispiel?
    Oder ist da vielleicht nur ein zweiter Request hinten dran, der über die selbe Connection geschickt wurde ( Connection: keep-alive und so).
    Oder ist vielleicht Transfer-Encoding: chunked im Spiel?

    (Lustig: Hier steht die Content-Length logisch: https://developer.mozilla.org/en/FileGuide/FileUpDown)

    Das Beispiel mit dem " Content-length: 20 " ist mMn. falsch.
    Weiter unten gibt's ein Code-Beispiel, da steht es richtig ( req.setRequestHeader("Content-length", multiStream.available()); - wobei multiStream ein Stream ist der alles inklusive Boundaries enthält)



  • Danke schon mal.

    hustbaer schrieb:

    Wo? Was kommt dazu? Beispiel?

    Das hier steht beim IE am Ende. (Also nach dem Ende der Datei.) (Das Beispiel oben ist von Firefox.)

    -----------------------------7dc1031140662
    Content-Disposition: form-data; name="submit"
    
    Upload
    -----------------------------7dc1031140662--
    

    Soweit ich das verstanden habe, sind diese -- am Ende ein "hier wird geschlossen, nicht geöffnet" Zeichen. Insofern weiß ich nicht so ganz was das soll.

    hustbaer schrieb:

    sagen wir mal umständlicher gemacht wurde als es nötig gewesen wäre.

    Vielleicht, es regt mich nur gerade etwas auf. Vor allem haben sie unter dem Boundary ja eh einen Mini-Header, da hätten sie auch einfach Content-Length für die Datei angeben können. Aber nein, unten steht das Boundary einfach noch mal. (Bzw. nicht nur das, oder der IE hält sich nicht daran.)
    Es ist einfach so lächerlich komplex zu parsen im Gegensatz zu einer Längenangabe.



  • Ja, "--foo" heisst "hier beginnt der erste/nächste Teil" und "--foo--" heisst "das war der letzte Teil". Das muss so sein.

    BTW: es darf laut MIME-multipart Standard nach der letzten Boundary noch Text kommen, der soll/muss dann laut Standard einfach ignoriert werden.
    Genau so darf vor der ersten Boundary Text kommen, der ebenfalls zu ignorieren ist.

    MIME (inklusive multipart): http://www.ietf.org/rfc/rfc2046.txt
    multipart/form-data: http://www.ietf.org/rfc/rfc2388.txt

    Da drin solltest du alles finden was du brauchst. Ansonsten selber googeln, so schwer ist das nicht. (Lästig zu implementieren: ja. Aber die Infos sind gut und reichlich vorhanden)

    Vielleicht, es regt mich nur gerade etwas auf. Vor allem haben sie unter dem Boundary ja eh einen Mini-Header, da hätten sie auch einfach Content-Length für die Datei angeben können. Aber nein, unten steht das Boundary einfach noch mal. (Bzw. nicht nur das, oder der IE hält sich nicht daran.)
    Es ist einfach so lächerlich komplex zu parsen im Gegensatz zu einer Längenangabe.

    MIME ist ursprünglich für Emails gemacht worden.

    Ein Ziel war dabei vermutlich, dass man MIME Mails "durch" alle möglichen bereits existierenden Mail-Gateways schicken kann, ohne dass Schlimme Dinge (tm) passieren. Und das selbe nochmal für Mail-Clients - z.B. dass man ne MIME Mail noch korrekt dekodieren kann, nachdem sie von einem oder mehreren pre-MIME Mail-Clients weitergeleitet wurde.

    Ein weiteres Ziel war, dass man MIME Mails auch ohne MIME-fähigen Mail-Client halbwegs normal lesen können sollte.

    Das erklärt warum eine Content-Length Angabe bei MIME nicht möglich bzw. nicht sinnvoll gewesen wäre. Nämlich weil Mail-Gateways und Mail-Clients dafür bekannt sind/waren allen möglichen Unfug mit Mails anzustellen. z.B. \r\n zu \n zu konvertieren oder umgekehrt (oder gar alles in ein anderes Charset zu konvertieren). Wodurch sich halt die Länge ändert.

    Das ist auch einer der Gründe warum Binärfiles in Emails BASE64-kodiert gesendet werden, und nicht einfach 1:1 binär.

    Weiters erklärt es auch dass nach der letzten Boundary noch zusätzlicher Text kommen darf. Diverse pre-MIME Mail-Clients werden vermutlich z.B. beim Weiterleiten einer Mail hinten noch was drangeschrieben haben. Dass vor der ersten Boundary noch was stehen darf hat soweit ich weiss hauptsächlich den Zweck, dass ein Mail-Client beim Erzeugen einer Multipart Email vorne eine Nachricht ala "Dies ist eine MIME-Multipart-Email, ihr Mail-Client unterstützt das aber nicht trallala blabla blub" dranschreiben darf. Was ja auch Sinn macht, wenn man den Inhalt einer Multipart-Email "roh" presentiert bekommt ist das gerade für "normale" PC User, die keinen Tau von der Technik dahinter haben, recht praktisch.



  • Sehe ich auch in etwa so... Im nachhinein könnte man immer etwas besser machen..dies gilt auch für verhauene Standards.


Anmelden zum Antworten