Occasionally I need to make an HTTP request via telnet for debug purposes – either I want to easily see exactly what the server returned as response, or I want to tamper with the HTTP request for some reason.
There are many articles around the net which explain how to make an HTTP request via telnet. However, most of them don’t explain how to construct the “Content-Length” HTTP header, or it’s just me who can’t find the answer quickly.
The straight answer to what number do we write for content length is: the length of the body.
However, if we take a look at the following Perl example:
#!/usr/bin/perl use strict; use warnings; my $url = '/post.php'; my $host = 'example.com'; my $http_post_body = <<EOF; POST_REQUEST_LINE1 POST_REQUEST_LINE2 POST_REQUEST_LINE3 EOF my $content_length = length($http_post_body); # Construct the request print <<EOF; POST $url HTTP/1.1 Host: $host Content-Length: $content_length $http_post_body EOF
The above calculated length of $content_length won’t be what the HTTP server expects, at least this is what my Apache installation shown. If you paste via telnet what the Perl script output, the HTTP server will not accept this POST request. Because the “Content-Length” is wrong.
Actually, telnet ends lines with “\r\n”, not just with “\n”. This is what Apache seems to expect for sure too, but I haven’t researched that thoroughly. Here comes the tricky part. You need to end your lines in Perl with “\r\n”, not just with “\n” as most text editors do. Therefore, before calculating the value of “Content-Length”, we need to convert the body of the HTTP request by using the following code:
... # convert "\n" to "\r\n" endings $http_post_body =~ s/([^\r])\n/$1\r\n/g; my $content_length = length($http_post_body); ...
I would have published a more useful Perl example, but the reason I needed to calculate “Content-Length” for a POST HTTP request this time was because I wrote a small script as a proof-of-concept for the PHP “multipart/form-data” denial of service bug. And I’m not in a mood to make script-kiddies’ life easier 🙂 Even though our hosting servers were not vulnerable to this attack as the resource limits for the hosting accounts manage to mitigate it enough.