#!/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;
# конец =)