Arbeitsnotizen zu: Perl LWP und HTTP 2

Warum requests auf HTTP/2 Seiten nichts zurück lieferten

Kommentieren Jan 05 2022

 

Eine simple Sache die sich in ein wenig Kopfweh entwickelte.

Folgendes Script soll einfach nur die URL aufrufen und das Ergebnis speichern. Nun bemerkte ich, dass bei gewissen URLs, kein Body abgespeichert wurde. Status war 200 und sonst auch kein Fehler.

Stellte sich heraus, das Setzen des Accept-Encoding headers ist das Problem. Komischerweise setzt ein Browser diesen genauso wie ich es in der ersten Version auch getan habe.

UPDATE: Sieht nun ganz danach aus das br das Problem ist. Warum dies bei einem Request auf so eine Adresse im Netzwerktab des Browsers auftaucht und trotzdem funktioniert. Keine Ahnung.

#!/usr/bin/perl
use feature ':5.16';
use warnings;
use strict;
use utf8;
use open qw( :std :encoding(UTF-8) );
use Data::Dumper;

use LWP::UserAgent;
use HTTP::Request;

my $request_headers = [
  'Aser-Agent' => 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/999.99 (KHTML, like Gecko) Chrome/79.0.3945.131 Safari/537.36',
  'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
  'Accept-Language' => 'en-US',
#  'Accept-Encoding' => 'gzip,deflate,br', # does not work with http2
#  'Accept-Encoding' => '*', # works everytime
  'Accept-Encoding' => HTTP::Message::decodable, # works everytime 
  'Cache-Control' => 'no-cache',
  'Upgrade-Insecure-Requests' => 1
];


## http/1.x
my $url = "https://www.heise.de";
#my $url = "https://www.ibm.com";
## http/2.x
#my $url = "https://www.neoterisch.de";
#my $url = "https://www.hubspot.com";
## http/3
#my $url = "https://medium.com";
#my $url = "https://getbootstrap.com";

my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(GET => $url, $request_headers);

my $res = $ua->request($req);
if ($res->is_success) {
        open(my $fh, '>', "out.txt") or die "Could not open file out.txt' $!";
        print $fh $res->decoded_content();
        close($fh);
}
else {
        print $res->code ."\n";
        print $res->status_line ."\n";
        print "Something went wrong\n";
}

Bis ich darauf kam (Danke an die Hilfe im Gentoo Forum) habe ich die Umsetzung auch mal mit WWW::Curl::Easy gemacht.

#!/usr/bin/perl
use 5.20.0;
use strict;
use warnings;
use utf8;
use open qw( :std :encoding(UTF-8) );
use Data::Dumper;
use Term::ANSIColor qw(:constants);

use ConfigReader::Simple;
use DBI;
use WWW::Curl::Easy;

open(my $fh, '>', "out.txt") or die "Could not open file 'out.txt' $!";

my $curl = WWW::Curl::Easy->new;
$curl->setopt(CURLOPT_HEADER, 1);
$curl->setopt(CURLOPT_URL, $url);
$curl->setopt(CURLOPT_CONNECTTIMEOUT, 10);
$curl->setopt(CURLOPT_FOLLOWLOCATION, 1);
$curl->setopt(CURLOPT_MAXREDIRS, 3);
$curl->setopt(CURLOPT_WRITEDATA, $fh);

# pushopt does a segfault...
$curl->setopt(CURLOPT_USERAGENT, "Mozilla/5.0 (X11; Linux x86_64; rv:95.0) Gecko/20100101 Firefox/95.0");

my $retcode = $curl->perform;
if ($retcode == 0) {
        say CLEAR,GREEN,"Transfer went ok",RESET;
push(@urlsFetched, $id);
} else {
        say BOLD, RED, "Transfer went south: $retcode ".$curl->strerror($retcode)." ".$curl->errbuf, RESET;
}

close $fh;

Dummerweise liefet die Verwendung von pushopt immer ein segmentation fault. Daher kann man nicht alle gewünschten header setzten die man möchte.