2008-09-17 31 views
18

He encontrado un nuevo interés en construir un servidor web pequeño y eficiente en C y he tenido problemas para analizar los métodos POST desde el encabezado HTTP. ¿Alguien tiene algún consejo sobre cómo manejar la recuperación de los pares de nombre/valor de los datos "publicados"?Analizando encabezados HTTP

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 

No veo una forma tangible de recuperar la línea de fondo como un todo y asegurar que funcione siempre. No soy fanático de la codificación en nada.

Respuesta

19

Puede recuperar los pares nombre/valor buscando newline newline o más específicamente \ r \ n \ r \ n (después de esto, se iniciará el cuerpo del mensaje).

Luego puede simplemente dividir la lista por &, y luego dividir cada una de esas cadenas devueltas entre = para pares de nombre/valor.

Ver el HTTP 1.1 RFC.

+0

Ah, gracias. Noté que había un espacio extra justo antes de la cadena de pares de nombre/valor, pero no uní dos y dos. –

+2

@rofly: no calcule dos y dos, solo lea el estándar (RFC 2616). Está en la sección 4.1. – bortzmeyer

+2

Solo tenga en cuenta que hay clientes no conformes que usan el final de encabezados "interesante", como '\ n \ n' o '\ n \ r \ n'. – Wade

2

Debe seguir analizando la secuencia como encabezados hasta que vea la línea en blanco. El resto es la información POST.

Necesita escribir un pequeño analizador para los datos de la publicación. Puede usar las rutinas de la biblioteca C para hacer algo rápido y sucio, como index, strtok y sscanf. Si tiene espacio para ello en su definición de "pequeño", podría hacer algo más elaborado con una biblioteca de expresiones regulares, o incluso con flex y bison.

Al menos, creo que este tipo de respuestas a su pregunta.

4

Una vez que tenga Content-Length en el encabezado, sabrá la cantidad de bytes que se leerán justo después de la línea en blanco. Si, por cualquier motivo (GET o POST) Content-Length no está en el encabezado, significa que no hay nada que leer después de la línea en blanco (crlf).

0

IETF RFC, aquí hay una respuesta más al punto. Suponiendo que se da cuenta de que siempre hay un /r/n extra después de la línea Content-Length en el encabezado, debería poder hacer el trabajo para aislarlo en una variable char* llamada data. Aquí es donde comenzamos.

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); 
Cuestiones relacionadas