Leser: 17
1
2
3
4
5
6
7
my $i = 0;
while(my $n = $nh->read_entity_body(my $record, 794)){
my($ts, $url, $hugo, $ref) = unpack "NZ255Z35Z500", $record;
print "$n $ts $url\n";
last if ++$i == 3;
last unless $n;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
use 5.012; use warnings; use Errno qw/EINTR EAGAIN/; # ... initialization stuff ... RECORD_LOOP: while (1) { my $record = ""; READ_LOOP: while (length($record) < 794) { my $_; given ($nh->read_entity(my $chunk, 794 - length($record))) { last RECORD_LOOP when ($_ == 0 and length($record) == 0); next READ_LOOP when ($_ ~~ [ undef, -1 ] and $! ~~ [ EINTR, EAGAIN ]); die "I/O error: $!" when ([ undef, -1 ]); die "Unexpected end of file" when (0); default { $record .= $chunk; } } } # ... record processing ... }
2011-03-20T17:40:29 rosti[...]
Leider kann ich aufgrund meiner Perlversion den Code nicht testen.
Quote[...]
In Summa bin ich am Überlegen, ob es vielleicht doch besser ist, ein eigenes kleines Modul zu schreiben, etwa Net::HTTP10 (nur HTTP/1.0) und ein eigenes Objekt erstellen dem eine Callbackfunktion mitgegeben wird, die exact 794 Bytes aus dem Socket liest
[...]
1 2 3 4 5 6
my $s = Net::HTTP10->new($sockattr, $headers) or die "Kein Socket"; #print dump $s, "\n"; $s->request; my($code, $mess, $href) = $s->read_headers or die; printf "Status: %s Mesg: %s \nHeaders: %s\n", $code, $mess, dump $href; #$s->body_callback;
1
2
3
4
5
6
7
Status: 200 Mesg: OK
Headers: {
Connection => "close",
"Content-Type" => "application/octet-stream",
Date => "Mon, 21 Mar 2011 08:57:09 GMT",
Server => "Apache/2.2.14 (Win32) PHP/5.3.0",
}
2011-03-21T09:53:10 LinuxerSteh grad auf dem Schlauch. Wofür steht das "TE"?
2011-03-21T10:28:57 rostiEdit: mein neues Modul hat nur 117 Zeilen, gerne würde ich es hier mal vorstellen zur Diskussion.
2011-03-21T09:00:16 rosti[...]
Meine Client-Server-Anwendung, an der ich schon länger schreibe, erfordert es, dass kein TE (chunked) stattfindet.
[...]
2011-03-21T13:30:21 murphy2011-03-21T09:00:16 rosti[...]
Meine Client-Server-Anwendung, an der ich schon länger schreibe, erfordert es, dass kein TE (chunked) stattfindet.
[...]
Aus purer Neugier wüsste ich ja gerne, warum Deine Anwendung das eigentlich erfordert.
Meine naive Vorstellung ist, dass es der Anwendung doch reichlich egal sein könnte, wie das Übertragungsformat aussah, solange sich die HTTP-Bibliothek korrekt um diese Protokolldetails kümmert und einen Datenblock abliefert, der weiterverarbeitet werden kann.
1 2 3 4 5 6
.. my $service="http://www.test.org"; my $header=HTTP::Headers->new('Accept-Encoding'=>'deflate'); my $req=HTTP::Request('GET',$service,$header); my $res=$lwp_user_agent->request($req); ...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
use 5.010; use strict; use warnings; use LWP; my $agent = LWP::UserAgent->new(); my $response = $agent->get('http://example.com/foo/bar'); if ($response->is_success) { for my $chunk ($response->decoded_content(charset => 'none') =~ m/.{794}/g) { # ... process $chunk of binary data ... } } else { die 'Network protocol error: ' . $response->status_line; }
2011-03-22T15:22:09 rosti[...]
Transfer-Encoding: chunked
ist das Problem.
[...]
Zum Übertragen von Binary-Sequenzen ist das jedoch nicht brauchbar, da müssen exakt eine bestimmte Anzahl an bytes gelesen werden, was am besten gleich aus dem Socket-Handle gemacht wird.
[...]
$response->decoded_content(charset => 'none')
2011-03-22T17:28:30 murphy
Das ist auch der Grund, warum ich in meinem letzten Beispielaufrufe: decoded_content um die Transportkodierungen aufzulösen und charset => 'none' um keine Textdekodierung durchzuführen sondern einen Binärstring zu bekommen.Code (perl): (dl )$response->decoded_content(charset => 'none')