Wie richtig analysiert, der eingehenden HTTP-Anfragen
habe ich eine C++ - Anwendung mithilfe von WinSck, die eine kleine (Griffe nur ein paar features, die ich brauche) http-server implementiert. Diese wird verwendet, um die Kommunikation mit der Außenwelt mithilfe von http-Anfragen. Es funktioniert, aber manchmal sind die Anfragen nicht korrekt verarbeitet werden, da die Analyse schlägt fehl. Jetzt bin ich ziemlich sicher, dass die Anforderungen werden richtig gebildet, da diese gesendet werden, die von gängigen web-Browser wie firefox/chrome oder perl/C# (die haben http modules/dll ' s).
Nach etwas debugging fand ich heraus, dass das problem in der Tat, in der die Nachricht empfängt. Wenn die Nachricht kommt mehr als nur ein Teil (es ist nicht zu Lesen in einem recv()
nennen) dann manchmal das Parsen fehlschlägt. Ich habe gegangen durch zahlreiche versuche auf, wie diese zu lösen, aber es scheint nichts zu sein zuverlässig genug.
Was ich jetzt mache ist, dass ich das Einlesen, bis ich "\r\n\r\n"
- Sequenz, die gibt das Ende des header. Wenn WSAGetLastError()
Berichte etwas anderes als 10035 (Verbindung getrennt/fehlgeschlagen), bevor eine solche Sequenz gefunden wird, habe ich die Nachricht verwerfen. Wenn ich weiß, dass ich die ganzen header, die ich analysieren Sie diese und suchen Sie nach Informationen über die Länge des Körpers. Aber ich bin mir nicht sicher, ob diese Angaben zwingend vorgeschrieben (ich denke nicht) und was sollte ich tun, falls es keine solche Informationen - heißt es, dass es keinen Körper? Ein weiteres problem ist, dass ich nicht weiß, ob ich Aussehen sollte für eine "\r\n\r\n"
nachdem der Körper (wenn Ihre Länge größer als null).
Weiß jemand, wie zuverlässig Parsen einer http-Nachricht?
Hinweis: ich weiß, es gibt Implementierungen von http-Servern gibt. Ich möchte mit meiner eigenen, aus verschiedenen Gründen. Und ja, das Rad neu erfinden ist schlecht, ich weiss das auch.
Tischler: ich habe es angeschaut und es sieht sehr gut aus. Aber ich wirklich brauchen, um zu schreiben, meine eigenen, die unterstützt nur ein Bruchteil der http-features und gleichzeitig kennt ein paar spezielle Befehle. Wenn ich war in der Notwendigkeit einer vollständigen http-server würde ich definitiv nicht Schreibe meine eigenen.
Beachten Sie die zur Verfügung gestellte code ist kleine und treibt keine Anforderungen an Sie. Sie können halt, ignorieren Sie, und wickeln Sie es in irgendeiner Weise, die Sie bitte per customizing die wenigen Rückrufe, die es bietet. Ich sympathisiere mit dem Wunsch, Dinge zu tun, sich selbst, aber dies wird sparen Sie Stunden der Fehlersuche und Fehler aufgrund UNVORHERGESEHENER Eingabe später auf.
InformationsquelleAutor PeterK | 2010-09-13
Du musst angemeldet sein, um einen Kommentar abzugeben.
Könnten Sie versuchen, Ihren code zu sehen, wie Sie mit einer HTTP-Nachricht.
Oder man betrachtet die Skillung, es gibt Länge der Nachricht Felder, die Sie verwenden sollten. Nur buggy Browser senden zusätzliche CRLFs am Ende, scheinbar.
Das sieht gut aus, danke. Wenn das hilft werde ich gerne annehmen Ihre Antwort.
InformationsquelleAutor gbjbaanb
Wenn Sie sind auf das schreiben Ihrer eigenen parser, würde ich den Zed Shaw Ansatz: verwenden Sie die Ragel state machine compiler und bauen Sie Ihre parser basierend auf, dass. Ragel verarbeiten kann Eingang der Ankunft in Blöcken, wenn du vorsichtig bist.
Ehrlich gesagt, wenn, würde ich nur verwenden,so etwas wie dieses.
Ihre go-to-Ressource sollte RFC 2616, beschreibt, welche HTTP 1.1 verwenden, die Sie verwenden können, zu konstruieren Sie einen parser. Viel Glück!
Reden Ragel, können Sie einen Blick auf HttpMachine (github.com/bvanderveen/httpmachine/tree/master/src/HttpMachine/...). Auch wenn es in C# geschrieben, die state-Maschine kompiliert wird mit Ragel und ich denke, es sollte leicht anpassbar sein, um C++. Mehr über zwei .rl (Ragel Quellen) Dateien, die von drei sind nicht gebunden an C#, aber allgemein (also eine Menge Arbeit ist bereits erledigt).
InformationsquelleAutor Jack Kelly
Sowieso HTTP-request hat, "\r\n\r\n" am Ende der request-Header und vor den request-Daten, wenn überhaupt, auch wenn die Anforderung "GET /HTTP/1.0\r\n\r\n".
Wenn Methode ist "POST", sollten Sie Lesen, wie viele bytes nach "\r\n\r\n" wie angegeben im Content-Length-Feld.
Also pseudocode ist:
Wird es "\r\n\r\n", nachdem der Inhalt nur, wenn der Inhalt umfasst. Inhalte sind möglicherweise binäre Daten, es nicht zu beenden-Sequenzen, und die eine Methode, um seine Größe ist die Verwendung von " Content-Length-Feld.
Auch im Auge behalten, dass die HTTP-1.1-Anforderungen nicht brauchen, um eine
Content-Length
header, entweder. Sie könnenTransfer-Encoding: chunked
statt, in welchem Falle die Länge der Nachricht ist codiert in der message-Daten selbst.InformationsquelleAutor Abyx
HTTP
GET
/HEAD
Anfragen haben keinen Körper, undPOST
Anfrage kann kein Körper zu. Sie haben zu prüfen, ob es eineGET
/HEAD
, wenn es ist, dann Sie haben keinen Inhalt (body/Nachricht) geschickt. Wenn es einPOST
tun Sie, wie die specs sagen zum analysieren einer Nachricht von bekannt/unbekannt Länge, da @gbjbaanb sagte.es ist nicht genau angegeben in der HTTP-Spezifikation, ob Sie ein Körper oder nicht im GET/HEAD requests. Ich habe es lokal getestet und es funktioniert mit apache, aber ich habe nie gesehen, bevor Sie in einer realen Umsetzung, ich lese stackoverflow.com/questions/978061 und stackoverflow.com/questions/1266596 nun, danke für den Hinweis.
ob etwas in der Praxis verwendet wird und ob es erlaubt ist sind verschiedene Fragen. Wichtig ist, dass die Anfrage-parsing, nur ist die gleiche für alle Methoden. (Im Gegensatz zur response-Analyse, wo der KOPF ist etwas besonderes). Siehe auch trac.tools.ietf.org/wg/httpbis/trac/ticket/19 - das ist, warum waren die überarbeitung von RFC 2616, nachdem alle.
sichere Sache.
InformationsquelleAutor aularon