This very simple script will help you learn a bit more about HTTP headers and how they work. It asks for a small amount of information and then creates a simple, but valid HTTP request. The following is a simple HEAD request from Perlmonks:
Request method (GET, TRACE, OPTIONS, or HEAD - HEAD is default)? h Enter host: www.perlmonks.org Port (80 is default)? Path (/index.html is default)? Attempting to connect to www.perlmonks.org:80 HEAD /index.html HTTP/1.1 Host: www.perlmonks.org HTTP/1.1 200 OK Date: Sun, 26 Nov 2000 21:17:19 GMT Server: Apache/1.3.9 (Unix) mod_perl/1.21 Last-Modified: Fri, 17 Nov 2000 02:57:44 GMT ETag: "23e95c-0-3a149ea8" Accept-Ranges: bytes Content-Length: 0 Connection: close Content-Type: text/html X-Pad: avoid browser bug
#!/usr/bin/perl -w use strict; use IO::Socket; my %method = ( g => 'GET', h => 'HEAD', o => 'OPTIONS', t => 'TRACE' ); my $method = ''; while ( $method !~ /^[gtho]/i ) { print 'Request method (GET, TRACE, OPTIONS, or HEAD - HEAD is defa +ult)? '; $method = <STDIN>; $method = 'HEAD' if ! $method; } $method = $method{ lc substr $method, 0, 1 }; my $host = ''; while ( ! $host ) { print 'Enter host: '; chomp ( $host = <STDIN> ); } my $port = 0; while ( $port < 1 or $port > 65535 ) { print 'Port (80 is default)? '; chomp ( $port = <STDIN> ); $port = 80 if ! $port; } my $path = ''; while ( ! $path ) { print 'Path (', $method eq 'OPTIONS' ? '*' : '/index.html', ' is + default)? '; chomp ( $path = <STDIN> ); if ( ! $path ) { $path = ( $method eq 'OPTIONS' ) ? '*' : '/index.html'; } } my $maxForwards = 0; if ( $method eq 'TRACE' ) { while ( $maxForwards < 1 ) { print 'Max forwards? '; chomp ( $maxForwards = <STDIN> ); } } print "Attempting to connect to $host:$port\n"; my $target = new IO::Socket::INET("$host:$port"); my $request = "$method $path HTTP/1.1\n" . "Host: $host\n"; $request .= "Max-Forwards: $maxForwards\n" if $method eq 'TRACE'; $request .= "\n"; print "\n$request"; # Send the headers to the host print $target $request; my $response; { undef $/; # Here are the headers $response = <$target>; } print $response;

Replies are listed 'Best First'.
Re: Learning HTTP headers
by extremely (Priest) on Nov 27, 2000 at 08:12 UTC
    Nice stuff. =) But for those out there that already have Bundle::LWP installed should look for the GET/HEAD/POST scripts that it installs. A fine and sexy tool I use almost every day. Try these if you have it installed:
    /usr/local/bin/GET -USed http://www.yahoo.com/ /usr/local/bin/GET -USed http://www.microsoft.com/ /usr/local/bin/GET -USed http://www.apple.com/

    --
    $you = new YOU;
    honk() if $you->love(perl)

Re: Learning HTTP headers
by snax (Hermit) on Nov 27, 2000 at 19:09 UTC
    I was under the impression that one should use
    \r\n
    as line terminators when playing with web servers, since this would signal end of line to Mac, Windows, and *NIX machines.

      Two misconceptions here (one in theory, the other in implementation). Most web servers adapt fine to different newline styles, so normally this isn't a problem, but you are correct in that the "correct" newline representation wasn't accurate in the original code.

      However, "\r\n" is not the way a correct newline should be represented. \n does not have a direct, portable mapping to a specific ASCII code. Instead, it's Perl's representation of a "newline", which WILL vary depending upon the OS being used. Thus, while "\r\n" will give you the desired results under Unix, it will break even more under Windows or on MacOS. If you want to be strict about your newlines, you need to use "\015\012".

        Ahh, right -- thanks.

        I knew there was something like this going on, and whenever I think about doing server/client type things I am reminded of the general philosophy that one should be strict in conforming (when initiating contact) and lax in demanding conformity (when receiving contact). It's nice to know how to do things "right" :)

        Of course, in most cases here, "right" will involve an LWP module :)