Ryan
Ryan

Reputation: 33

How to determine the length of "Content-Length: " in HTTP packet

I'm writing code for an http server on an embedded target. I want to parse the raw HTTP packet I am receiving for its' content length. My problem arises from the fact that I don't know how many bytes the content length is. For example,

//Content-Length is 4 characters
Content-Length: 1000

//Content-Length is 2 characters
Content-Length: 20

My code is:

(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');
}

I know my code works because for now I have put a hard coded value in the loop iterator condition. I just need to be able to determine it at run time.

EDIT: Would it be safe to keep reading characters until \r is found?

Upvotes: 2

Views: 5395

Answers (2)

Amr Ayman
Amr Ayman

Reputation: 1159

One way to solve this is to simply start counting from after the fixed-length string "Content-Length: " until you find either whitespace or a null byte (in some rare conditions).

#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 */

Upvotes: 1

user3386109
user3386109

Reputation: 34839

Each line in the header ends with a CR/LF pair per section 3 of RFC7230. In section 3.2.4 of the same document, it says that "a field value might be preceded and/or followed by optional whitespace". Therefore to parse the content-length successfully, your code must skip any leading whitespace, then process digits until a whitespace character is found. In other words

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

Note that checking for count > 9 limits the content-length to 999,999,999. Adjust as necessary for your application. For example, you can support larger numbers if int is 64-bits. On the other hand, maybe you only want to support smaller lengths, in which case you could limit the number of digits to a smaller value.

Upvotes: 2

Related Questions