#!/usr/bin/perl
use Socket;
use IO::Handle;
use strict;
my ($h, $p, $r, $d, $cz, $ltg, $tr, $buf);
my $u = shift or die "specifu url.\\n"; # берём урл из параметров скрипта
my $f = shift or die "specify output file.\\n"; # берём выходной файл отуда же
open(F, ">$f") or die "file."; # открываем выходной файл на чтение
$p = 80; # порт по умолчанию
$r = "/"; # ури по умолчанию
$u =~ s/http\\:\\/\\///; # удаляем из урла лишнее (лишнее для данного скрипта, конечно =))
($h, $p, $r)= ($u=~ m#([^/:]*):?([^/]*)(/.*)?$#i); # парсим так, что вид урла может иметь вид
# [url]www.url.com:8080/dir/page.html?params=value[/url] etc. то есть имеется возможность задать порт
$p = ($p || 80) ; # думаю ясно
$r = ($r || "/") ; # тоже
socket(S,AF_INET,SOCK_STREAM,getprotobyname("tcp")) or die "$!\\n"; # создаём сокет
connect(S,sockaddr_in($p,inet_aton($h))) or die "$!\\n"; # конектимся
S->autoflush(1);
print S "GET $r HTTP/1.1\\r\\nHOST: $h\\r\\n\\r\\n"; шлём GET запрос для сервера, поддерживающего HTTP 1.1
my $ih = 1; # 
my ($rp, %hv, $vn, $v);
while ($d = ) { #читаем ответ сервера. Значения из HTTP заголовка заносим в хэш %hv (header values)
    if ($d =~ /^\\015?\\012/) {
        last;
    }
    else {
        if ($ih == 1) {
            $rp = (split(/ /, $d))[1];
            $ih = 2;
        }
        else {
            ($vn, $v) = $d =~ /(.+?):(.+?)\\r?\\n/;
            $hv{$vn} = $v;
        }
    }
}
if ($hv{\'Transfer-Encoding\'} =~ /chunked/i) { #если параметр HTTP Transfer-Encoding = chunked, то  данные читаем
#способом номер раз =) подробнее в RFC
    while ($cz = hex() ) {
        $ltg = $cz ;
            while ($ltg && ($tr = read(S, $d, $ltg)) ) {
                    print F $d;
                    $ltg -= $tr ;
            }
            defined($tr) || die "$!" ;
            $_=  ;
    }
}
elsif ($hv{\'Content-Length\'}) { # иначе и определён параметр Content-Length номер два =) подробнее там же
    $ltg = $hv{\'Content-Length\'};
    while ($ltg && ($tr = read(S, $d, ($ltg > 16384)?16384:$ltg))) {
        print F $d;
        $ltg-= $tr ;
    }
    defined($tr) || die "$!" ;
    $ltg && die "Not all data.\\n";
} else { # иначе просто читаем данные по 16384 байт =)
    print F $_ while read(S, $_, 16384) ;
}
close S;
# конец =)