Два запроса HTTP 1.1 (один не работает)?

Я собираюсь потерять его здесь, я пытаюсь отправить два HTTP 1.1, чтобы получить исходный код некоторых моих страниц URL (я не хочу использовать LWP), и работает только первая, даже когда я переключаю порядок, так что в теории оба запроса в порядке, вот что я делаю:

Я даже создал два сокета на всякий случай, но результат тот же...

my $sock =  IO::Socket::INET->new(
                PeerAddr => $dom,
                PeerPort => 'http(80)',
                Proto    => 'tcp'
            )
            or die "Could not connect to :80!! $!";

my $sock2 =     IO::Socket::INET->new(
                PeerAddr => $dom,
                PeerPort => 'http(80)',
                Proto    => 'tcp'
            )
            or die "Could not connect to :80!! $!";         


my $req2 = << 'EOT'
POST / HTTP/1.1
Host: $dom
Connection: keep-alive
Content-Length: 57
Cache-Control: max-age=0
Origin: ${org}
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: ${ref}


EOT
;




my $req = << 'EOT'
POST / HTTP/1.1
Host: $dom
Connection: keep-alive
Content-Length: 57
Cache-Control: max-age=0
Origin: ${org}
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: ${ref}


EOT
;           



$sock2->send($req2);


sleep 5;


my $abc;
while(<$sock2>) {
        print $_;
    }


$sock->send($req);


sleep 5;


while(<$sock>) {
        print $_;
    }

Где, кажется, проблема?

Заранее спасибо.

2 ответа

Решение

Вы отправляете запрос HTTP/1.1 с keep-alive (что неявно подразумевается в HTTP/1.1, поэтому вы можете пропустить заголовок Соединения). Но вы не пытаетесь анализировать HTTP-ответ, а просто предполагаете, что он закроет соединение, когда запрос будет выполнен. Это совершенно неправильно.

Я действительно рекомендую вам использовать установленные библиотеки HTTP, такие как LWP, HTTP::Tiny ... и не пытаться делать это самостоятельно. Если вы действительно хотите это сделать, ознакомьтесь с соответствующим стандартом, например, RFC 2616, в котором объясняются все важные вещи, которые вы просто игнорируете: заголовок и текст ответа http, длина контента и кодированная часть, кодировки контента и т. Д. HTTP/1.1 не это просто - если вы хотите, просто используйте HTTP/1.0 и не используйте keep-alive.

Я не уверен, но при создании экземпляра второго сокета сразу после первой отправки, повторного создания первого сокета он работает, сначала я подумал, что это потому, что я не закрыл первый сокет, но даже с этим close($socket) это не работает, если я не использую это так:

my $sock =  IO::Socket::INET->new(
                PeerAddr => $dom,
                PeerPort => 'http(80)',
                Proto    => 'tcp'
            )
            or die "Could not connect to :80!! $!";


my $req2 = <<"EOT"
POST / HTTP/1.1
Host: $dom
Connection: keep-alive
Content-Length: 57
Cache-Control: max-age=0
Origin: ${org}
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: ${ref}


EOT
;




my $req = <<"EOT"
POST / HTTP/1.1
Host: $dom
Connection: keep-alive
Content-Length: 57
Cache-Control: max-age=0
Origin: ${org}
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: ${ref}


EOT
;           



my $sock2 =     IO::Socket::INET->new(
                PeerAddr => $dom,
                PeerPort => 'http(80)',
                Proto    => 'tcp'
            )
            or die "Could not connect to :80!! $!";         

$sock2->send($req2);


sleep 5;


my $abc;
while(<$sock2>) {
        print $_;
    }


$sock->send($req);


sleep 5;


while(<$sock>) {
        print $_;
    }
Другие вопросы по тегам