Parsowanie nagłówków HTTP

Miałem nowe zainteresowanie budową małego, wydajnego serwera www w C i miałem pewne problemy z parsowaniem metod POST z nagłówka HTTP. Czy ktoś ma jakieś rady jak poradzić sobie z pobieraniem par nazwa / wartość z "zamieszczonych" danych?

POST /test HTTP/1.1
Host: test-domain.com:7017
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1
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
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://test-domain.com:7017/index.html
Cookie: __utma=43166241.217413299.1220726314.1221171690.1221200181.16; __utmz=43166241.1220726314.1.1.utmccn=(direct)|utmcsr=(direct)|utmcmd=(none)
Cache-Control: max-age=0
Content-Type: application/x-www-form-urlencoded
Content-Length: 25

field1=asfd&field2=a3f3f3
// ^-this

Nie widzę namacalnego sposobu na odzyskanie dolnej linii jako całości i upewnienie się, że działa za każdym razem. Nie jestem fanem hard-codingu w niczym.

Author: Chuck Callebs, 2008-09-17

4 answers

Możesz pobrać pary nazwa / wartość, wyszukując newline newline lub dokładniej \R \ n\R\n(następnie rozpocznie się Treść wiadomości).

Następnie możesz po prostu podzielić listę przez&, a następnie podzielić każdy z tych zwróconych łańcuchów między parami = for nazwa / wartość.

Zobacz HTTP 1.1 RFC .

 20
Author: Brian R. Bondy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-17 03:55:14

Gdy w nagłówku znajdziesz Content-Length, znasz ilość bajtów do odczytania zaraz po pustej linii. Jeśli z jakiegoś powodu (GET lub POST) Content-Length nie znajduje się w nagłówku, oznacza to, że nie ma nic do odczytania po pustej linii (crlf).

 4
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-22 12:07:38

Musisz analizować strumień jako nagłówki, dopóki nie zobaczysz pustej linii. Reszta to dane POST.

Musisz napisać mały parser dla danych postu. Możesz użyć procedur biblioteki C, aby zrobić coś szybkiego i brudnego, jak index, strtok i sscanf. Jeśli masz na to miejsce w swojej definicji "małego", możesz zrobić coś bardziej rozbudowanego z biblioteką wyrażeń regularnych, a nawet z flex i bison.

Przynajmniej tak mi się wydaje, że ten rodzaj odpowiedzi na twoje pytanie.

 2
Author: jfm3,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-17 04:00:27

IETF RFC niezależnie od tego, oto odpowiedź bardziej do punktu. Zakładając, że zdajesz sobie sprawę, że po linii Content-Length w nagłówku zawsze znajduje się dodatkowa /r/n, powinieneś być w stanie wyizolować ją do zmiennej char* o nazwie data. Od tego zaczniemy.

char *data = "f1=asfd&f2=a3f3f3";
char f1[100], 
char f2[100];
sscanf(data, "%s&%s", &f1, &f2); // get the field tuples

char f1_name[50];
char f1_data[50];
sscanf(f1, "%s=%s", f1_name, f1_data);  

char f2_name[50];
char f2_data[50];
sscanf(f2, "%s=%s", f2_name, f2_data);  
 0
Author: Oliver,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-23 05:00:11