2008-09-17 90 views
18

我已经发现了一个新的兴趣,即在C中构建一个小型,高效的Web服务器,并且在解析HTTP标头的POST方法时遇到了一些麻烦。对于如何处理从“发布”数据检索名称/值对,有没有人有任何建议?解析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 

我看不出有形的方法来检索底线作为一个整体,并确保它每次都有效。我不喜欢硬编码。

回答

19

您可以通过搜索换行符或更具体的\ r \ n \ r \ n来检索名称/值对(在此之后,邮件正文将开始)。

然后,您可以简单地将列表拆分&,然后在= for name/value对之间拆分每个返回的字符串。

查看HTTP 1.1 RFC

+0

啊,谢谢。我注意到在名称/值对串之前有一个额外的空间,但没有把两个和两个放在一起。 – 2008-09-17 03:56:21

2

您需要继续解析流为标题,直到您看到空行。其余的是POST数据。

您需要为发布数据编写一个小解析器。你可以使用C库例程来做一些快速而肮脏的事情,比如index,strtok和sscanf。如果你在“small”的定义中有空间,你可以用正则表达式库,甚至flex和bison来做更精细的事情。

至少,我认为这种回答你的问题。

4

一旦你在标题中有Content-Length,你就知道紧跟在空白行后面的字节数量。如果出于任何原因(GET或POST)Content-Length不在标题中,则意味着在空白行(crlf)之后没有任何要读的内容。

0

尽管IETF RFC,这里是一个更重要的问题。假设您意识到标题中的Content-Length行之后总是会有一个额外的/r/n,您应该可以将其分离为char*变量data。这是我们开始的地方。

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