Ungepufferter POST-Request
Andreas Flückiger
- perl
Hallo!
Ist es möglich, mit Perl einen ungepufferten POST-Request durchzuführen?
Im folgendem Beispiel wird zuerst STDIN eingelesen und erst dann der Request durchgeführt.
Bei grösseren Datenmengen ist dies aber nicht optimal.
Kennt jemand eine Möglichkeit, dieses Problem zu lösen?
Gruss
Andreas
--------------------
binmode STDIN;
read(STDIN, $stdin, $ENV{'CONTENT_LENGTH'});
use LWP::UserAgent;
$ua = new LWP::UserAgent;
$request = HTTP::Request->new(POST, $uri, $header, $stdin);
Ist es möglich, mit Perl einen ungepufferten POST-Request durchzuführen?
Im folgendem Beispiel wird zuerst STDIN eingelesen und erst dann der Request durchgeführt.
Bei grösseren Datenmengen ist dies aber nicht optimal.
Kennt jemand eine Möglichkeit, dieses Problem zu lösen?
Also irgendwo mehrere Schichten tiefer als LWP::UserAgent wird diese Kommunikation doch sicherlich mit TCP/IP-Sockets, Schleifen, Abfrage von Returncodes usw. ablaufen, also wahrscheinlich mit der Übertragung vieler einzelner Pakete.
Wenn Du Dir die Mühe machen willst, den Source-Code dieser Ebenen (den hast Du ja in Form der Module) zu verstehen, kannst Du sicherlich den POST-Aufruf mit einer dieser niedrigeren Ebenen abwickeln und verschränkt dazu Deine Datei einlesen.
Das macht aber nur dann Sinn, wenn Dir der Adreßraum für die Datei ausgeht (oder die Maschine sich zu Tode swappt). Wie groß sind denn Deine Datenmengen?
Und wem postest Du Deine Daten zu? Wenn das eine eigene Anwendung ist, dann kannst Du natürlich ein eigenes handshake-Protokoll aufmachen:
Dabei hast Du natürlich etwas Overhead für die einzelnen Verbindungsaufnahmen ... aber es ist so sicher schneller geschrieben als LWP::UserAgent zu lesen.
Und es ist fehlertoleranter bei großen Datenmengen: Wenn irgendwas nicht funktioniert, kannst Du eine eigene Fehlerbehandlung realisieren, statt daß alles verloren ist. Beispielsweise irgendwann später einfach die Übertragung wieder aufnehmen, denn der Partner weiß ja noch, wo er aufgehört hat, wenn er sich Deine Paketnummern gemerkt hat, und durch die handle findet er auch die passende Datei wieder.
Hallo!
Also irgendwo mehrere Schichten tiefer als LWP::UserAgent wird diese Kommunikation doch sicherlich mit TCP/IP-Sockets, Schleifen, Abfrage von Returncodes usw. ablaufen, also wahrscheinlich mit der Übertragung vieler einzelner Pakete.
Wenn Du Dir die Mühe machen willst, den Source-Code dieser Ebenen (den hast Du ja in Form der Module) zu verstehen, kannst Du sicherlich den POST-Aufruf mit einer dieser niedrigeren Ebenen abwickeln und verschränkt dazu Deine Datei einlesen.
Ich möchte lieber auf der Ebene von LWP::* und HTTP::* bleiben.
Das macht aber nur dann Sinn, wenn Dir der Adreßraum für die Datei ausgeht (oder die Maschine sich zu Tode swappt). Wie groß sind denn Deine Datenmengen?
Der Speicherplatz ist primär nicht das Problem.
Und wem postest Du Deine Daten zu? Wenn das eine eigene Anwendung ist, dann kannst Du natürlich ein eigenes handshake-Protokoll aufmachen:
Ich poste die Daten via HTTP an einen beliebigen Server, auf den ich keinen Einfluss habe. Das Problem ist, das ich den Response dieses Servers an den Aufrufer des Scripts zurückschicken möchte. Wenn ich die Daten auf meinem Server zwischenspeichere, wartet der Client doppelt so lange auf die Antwort.
Ich dachte eher daran, dem Request-Objekt eine Referenz auf eine Subroutine oder STDIN direkt zu übergeben. Dies sollte auch möglich sein, da das Modul HTTP::Request::Common auch stückweise Daten in einem Request sendet, und das mit HTTP::Request. Leider fand ich noch nicht heraus, wie es das macht.
Ich versuchte es mal mit einer Subroutine als Content, doch die gibt nur CODE(0x1011c338) zurück.
--------------------
$content = sub
{
read STDIN, $buf, 1024;
return $buf;
};
use LWP::UserAgent;
$request = HTTP::Request->new($request_method, $uri, $header, $content);
--------------------
Was muss ich da ändern, damit $content den Inhalt von STDIN zurückgibt?
Gruss
Andreas