Perl: невозможно использовать LWP :: Parallel :: UserAgent для веб-сайтов HTTPS - PullRequest
1 голос
/ 10 марта 2019

Я не могу использовать Perl-модуль LWP :: Parallel :: UserAgent для веб-сайтов https.Ниже приведен код, который я использую:

#!/usr/bin/perl

use LWP::Parallel::UserAgent qw(:CALLBACK);
use HTTP::Request; 

my $BrowserName = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36";

my $pua = LWP::Parallel::UserAgent->new();
$pua->agent( $BrowserName );
$pua->nonblock('true');
$pua->in_order  (1);
$pua->duplicates(0);
$pua->timeout   (10);
$pua->redirect  (2);
$pua->remember_failures ( 1 );

$url = "https://www.squeezemind.it";

my $res = $pua->register( HTTP::Request->new('GET', $url), \&gestione_risposta, 4096 );

my $entries = $pua->wait();

# Leggo le risposte
foreach (keys %$entries) {
  my $res = $entries->{$_}->response;
  print "\n\nAnswer for '",$res->request->url, "' was ", $res->code,": ", $res->message;  
}


sub gestione_risposta {

  my($html_content, $response, $protocol, $entry) = @_;

  if( !$response->is_success || $response->code != 200 ) { return C_ENDCON; }  

  if( length($html_content) ) {    
    # Bla Bla
  }

  return undef; 

}

Это хорошо работает для http , но если вы попытаетесь изменить $ url на веб-сайте https, это не удастся.

Дляhttps://www.squeezemind.it:

Код ошибки: 500 Сообщение: Не удается найти метод объекта «get_cipher» через пакет «IO :: Socket :: INET» в / usr / share / perl5 / LWP / Protocol /https.pm line 119

Для https://www.stackoverflow.com:

Код ошибки: 402 Сообщение: Неожиданный EOF при чтении ответа

Система работаетдо настоящего времени.Предложения?

Спасибо!

1 Ответ

2 голосов
/ 10 марта 2019

Из вашего кода:

$pua->nonblock('true');

При взгляде на код LWP :: Parallel :: UserAgent похоже, что неблокирующая поддержка HTTPS полностью нарушена: https поддержка реализована в LWP:: Parallel :: Protocol :: https, который происходит от LWP :: Parallel :: Protocol :: http для , выполняющего фактическое соединение .Соответствующий код в sub _connect :

103     unless ($nonblock) {
104       # perform good ol' blocking behavior
105       #
106       # this method inherited from LWP::Protocol::http
107       $socket = $self->_new_socket($host, $port, $timeout);
108       # currently empty function in LWP::Protocol::http
109       # $self->_check_sock($request, $socket);
110     } else {
111       # new non-blocking behavior
...
116       $socket =
117         IO::Socket::INET->new(Proto => 'tcp', # Timeout => $timeout,
118                               $self->_extra_sock_opts ($host, $port));

Видно, что для случая блокировки (по умолчанию) код использует функциональность LWP::Protocol::http, но для случая неблокированияон напрямую использует IO::Socket::INET - а не IO::Socket::SSL для HTTPS.Но LWP :: Protocol :: http (который используется позже) на самом деле ожидает сокет SSL и пытается вызвать get_cipher на нем.Это приводит к ошибке, которую вы видите:

Невозможно найти метод объекта "get_cipher" через пакет "IO :: Socket :: INET" в / usr / share / perl5 / LWP / Protocol / https.pm line 119

Когда не используется неблокирующая поддержка, кажется, что код работает вместо этого.

Что касается HTTPS в целом в этом модуле, см. README.SSL :

 ** DISCLAIMER: https support is pretty buggy as of now. i haven't **
 ** had time to test much of it, so feel free to see if it works   **
 ** for you, but don't expect it to :-)  

Другими словами: вам, вероятно, следует использовать другой модуль для получения надежной поддержкиHTTPS.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...