【问题标题】:How to determine the length of "Content-Length: " in HTTP packet如何确定 HTTP 数据包中“Content-Length:”的长度
【发布时间】:2014-09-22 20:13:47
【问题描述】:

我正在为嵌入式目标上的 http 服务器编写代码。我想解析我收到的原始 HTTP 数据包的内容长度。我的问题源于我不知道内容长度是多少字节。例如,

//内容长度为4个字符
内容长度:1000

//内容长度为2个字符
内容长度:20

我的代码是:

(buf is a char array with the contents of the http data, pLength is a char *)
pLength = strstr(buf, lenTok);
//advance pointer past "Content-Length: " to point to data
if (pLength != NULL) 
    pLength = (pLength + 16);
int length = 0;
for (int i = 0; i < /*length of Content-Length:*/; i++)
{
    length = length * 10;
    length = length + (pLength[i] - '0');
}

我知道我的代码有效,因为现在我已经在循环迭代器条件中放置了一个硬编码值。我只需要能够在运行时确定它。

编辑:在找到 \r 之前继续阅读字符是否安全?

【问题讨论】:

  • 读取rfc2616,header格式固定(但注意可以发送恶意请求)。

标签: c http http-headers


【解决方案1】:

标题中的每一行都以每个 section 3 of RFC7230 的 CR/LF 对结束。在同一文档的第 3.2.4 节中,它说 “字段值之前和/或之后可能是可选的空格”。因此,要成功解析内容长度,您的代码必须跳过任何前导空格,然后处理数字直到找到空格字符。换句话说

int i;
int count = 0;
int length = 0;

for ( i = 0; isspace( pLength[i] ); i++ )
{
    // skip leading whitespace
}

for ( count = 1; !isspace( pLength[i] ); i++, count++ )
{
    if ( count > 9 || !isdigit( pLength[i] ) )
    {
        // some sort of error handling is needed here
    }
    length = length * 10;
    length = length + (pLength[i] - '0');
}

请注意,检查 count &gt; 9 会将内容长度限制为 999,999,999。根据您的应用程序进行调整。例如,如果int 是 64 位,您可以支持更大的数字。另一方面,也许您只想支持较小的长度,在这种情况下,您可以将位数限制为较小的值。

【讨论】:

    【解决方案2】:

    解决此问题的一种方法是简单地从固定长度字符串“Content-Length:”之后开始计数,直到找到空格或空字节(在某些罕见的情况下)。

    #define INITIAL_LENGTH (16) /* Length of the string "Content-Length: " */
    
    if (pLength == NULL)
        return /* or whatever */
    else
        pLength += INITIAL_LENGTH
    
    int length;
    for(length = 0; *pLength != 0 && *pLength != '\n'; ++pLength)
        length++;
    
    pLength -= length; /* Now it points right after Content-Length:  */
    /* Now you have the length */
    

    【讨论】:

    • || 应该是&amp;&amp;,坦率地说它应该使用isdigit imho。
    • 更正了。 @WhozCraig:我也可以使用 ctypes 中的isspace,但我不想让一个简单的例子复杂化..
    • ...除了终止字符将是 SP、TAB 或 CR 字符,而不是 NUL 或 LF 字符。
    猜你喜欢
    • 1970-01-01
    • 2013-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    • 1970-01-01
    相关资源
    最近更新 更多