【问题标题】:Parsing HTTP Headers解析 HTTP 标头
【发布时间】:2010-09-09 22:28:06
【问题描述】:

我对用 C 语言构建一个小型、高效的 Web 服务器产生了新的兴趣,并且在解析来自 HTTP 标头的 POST 方法时遇到了一些麻烦。有人对如何处理从“已发布”数据中检索名称/值对有任何建议吗?

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

我认为没有切实可行的方法来检索整个底线并确保它每次都有效。我不喜欢硬编码。

【问题讨论】:

    标签: c http post header


    【解决方案1】:

    您可以通过搜索 newline newline 或更具体地 \r\n\r\n 来检索名称/值对(此后,消息的正文将开始)。

    然后,您可以简单地用 & 分割列表,然后在 = 之间分割每个返回的字符串以表示名称/值对。

    请参阅HTTP 1.1 RFC

    【讨论】:

    • 啊,谢谢。我注意到在名称/值对字符串之前有一个额外的空格,但没有将两个和两个放在一起。
    • @rofly:不要计算二和二,只需阅读标准(RFC 2616)。它在第 4.1 节中。
    • 请注意,有些不合规的客户端使用“有趣”的标头结尾,例如 '\n\n' 或 '\n\r\n'。
    • 请注意,除了 application/x-www-form-urlencoded 之外,还有其他内容类型。它可能是任何类型,例如json 很流行。
    【解决方案2】:

    一旦您在标头中添加了 Content-Length,您就知道在空行之后要读取的字节数。如果出于任何原因(GET 或 POST)Content-Length 不在标头中,则意味着在空行 (crlf) 之后没有可读取的内容。

    【讨论】:

      【解决方案3】:

      您需要继续将流解析为标头,直到看到空白行。剩下的就是 POST 数据了。

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

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

      【讨论】:

        【解决方案4】:

        尽管有 IETF RFC,但这里有一个更中肯的答案。假设您意识到在标题中的 Content-Length 行之后总是有一个额外的 /r/n,您应该能够将其隔离到名为 datachar* 变量中。这是我们开始的地方。

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

        【讨论】:

          猜你喜欢
          • 2011-06-08
          • 2021-07-16
          • 2016-07-19
          • 1970-01-01
          • 1970-01-01
          • 2012-01-26
          • 2010-11-23
          • 2010-12-28
          • 1970-01-01
          相关资源
          最近更新 更多