Suche http Parser in C
-
Hallo
ich hab ein ziemlich spezielles Problem und da stundenlanges Suchen nichts gebracht hat hoffe ich dass jemand sich da auskennt.
Grundsätzlich soll ein Webserver auf embedded Systemen eingebaut werden. Ich habe die Vorgabe, ein bestehendes Programm (Open Source) zu verwenden, um schneller voranzukommen und gleich am Anfang ein durchgetestetes System zu haben.
Im Internet findet man zwar ca. 10^19 Webserver, das Problem ist allerdings, dass ich etwas suche das keine eigene Verbindung aufbaut, weil das an anderer Stelle bereits gemacht wird. Letztendlich brauche ich also im Prinzip nur einen http Parser, der die eingehenden Anfragen analysiert und die Daten ggf. schön aufbereitet in eine Struktur schreibt.
Gibt es sowas als einzelne Komponente? Oder vielleicht kennt jemand einen Webserver, bei dem sich diese Funktion schön heraustrennen ließe?
-
Was soll denn der Parser koennen? Headerinformation, Oder Html ... ? Wie sollen die Daten aufbereitet werden und wie werden sie weiterverarbeitet? Als Idee: libcurl. Habe aber keine Erfahrung damit. Auch gibt es Tools wie flex und bison, die aus einer Parserbeschreibung C-Code generieren (mit einigen Kniffen auch ohne externe Abhaengigkeiten, habe etwas Erfahrung damit).
-
Kartoffelsalat schrieb:
Letztendlich brauche ich also im Prinzip nur einen http Parser, der die eingehenden Anfragen analysiert und die Daten ggf. schön aufbereitet in eine Struktur schreibt.
naja, fertige parser sind meistens ziemlich komplett und daher leider zu fett für kleine embedded systeme. wie sehen deine daten aus, die du parsen darfst? ein subset von html vielleicht?
-
Danke für die Antwort
Ich will zunächst mal nur die http Anfragen parsen. Als Eingabe bekomme ich zB so einen String:
GET /test.html HTTP/1.1 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1 Host: www.google.de Accept: */*
Wenn es nach mir ginge würde ich das einfach selbst schnell parsen, aber die Leute hier sind skeptisch was das angeht. Da ich auf dem Gebiet auch nicht die wahnsinns Ahnung habe, wäre es gut möglich dass ich dabei ein großes Scheunentor aufmache. Ein fertiges System, dass mir die einzelnen Parameter aus dem Text rauszieht die ich dann weiterverarbeiten könnte wäre also bevorzugt.
Wie die http Antwortnachricht zustande kommt ist jetzt erstmal nicht wichtig, da ich das selbst noch nicht so genau weiß. Ist halt alles embedded und da kann es sein dass man nichtmal ein Dateisystem hat.
libcurl muss ich mir nochmal genauer anschauen. Auf den ersten Blick sieht es so aus als ob es auch hauptsächlich Verbindungen aufbaut, aber das will ich ja nicht.
-
^^achso, das sollte nicht so schwer sein. die erste zeile ist die anfrage, bestehend aus anfrage-methode (GET, POST), dann der pfad (was angefragt wird) und dann das protokoll (HTTP/1.1 bzw. HTTP/1.0). alle 'tokens' sind durch leerzeichen getrennt, am ende der zeile ist ein cr/lf (0x0d,0x0a). danach kommt eine gewisse anzahl an optionalen headers (oder nix mehr), bestehend aus header-typ, doppelpunkt und inhalt. jede dieser zeilen hat wieder ein cr/lf am ende. sobald 2 cr/lfs hintereinander kommen (also 0x0d,0x0a,0x0d,0x0a) ist der http-header zuende (danach kommt dann das html-zeugs o.ä.). aber falls ich irgendwo unsinn erzählt habe, schau besser mal hier: http://www.faqs.org/rfcs/rfc2616.html
-
Ich hab ja schon vermutet dass es am einfachsten ist das selbst zu parsen. Ich werd es zum Testen jetzt erstmal so machen.
Falls aber doch noch jemand einen (kleinen) Webserver kennt der gut strukturiert ist, dann bitte sagen
-
Kennen tu ich leider keinen, aber ne liste kriegt man hier http://en.wikipedia.org/wiki/Tiny_web_servers
-
Suchst du sowas?
int CDownloadThread::ProcessHeader( void ) { CStringA line; // Header response int left = 0, right = 0; do { if( (right = m_Header.Find( "\r\n", left )) == -1 ) return( BS_ERROR ); line = m_Header.Mid( left, right-left ); left = right + 2; line.Trim(); if( line.Find( "HTTP/1." ) != 0 ) return( BS_ERROR ); int pos = line.Find( ' ' ); if( pos == -1 || pos + 4 > line.GetLength() ) return( BS_ERROR ); hf.iStatus = atoi( line.Mid( pos+1, 3 ) ); if( hf.iStatus == 100 ) { do { if( (right = m_Header.Find( "\r\n", left )) == -1 ) return( BS_ERROR ); line = m_Header.Mid( left, right-left ); left = right + 2; } while( left < m_HeaderLength ); } else if( hf.iStatus < 200 || hf.iStatus > 999 ) return( BS_ERROR ); } while( hf.iStatus < 200 ); hf.strResponse = line.Mid( line.Find( ' ' )+1 ); if( left >= m_HeaderLength ) return( BS_ERROR ); // Header body hf.iContentLength = -1; do { if( (right = m_Header.Find( "\r\n", left )) == -1 ) return( BS_ERROR ); line = m_Header.Mid( left, right-left ); left = right + 2; if( !line.IsEmpty() ) { int colon( line.Find( ':' ) ); if( colon == -1 ) return( BS_ERROR ); CStringA field( line.Left( colon ) ), value( line.Mid( colon+1 ) ); field.MakeLower(); value.Trim(); if( field == "content-length" ) hf.iContentLength = atoi( value ); ...