posttohost, wieso klappt das nicht?
eddi
- php
Hallo,
ich will mit folgendem Code Werte an einen Server senden und dann die Antwort auswerten.
hier mein Code:
function PostToHost($host, $path, $referer, $data_to_send) {
$fp = fsockopen($host, 80, $errno, $errstr, 30);
printf("Open!\n");
printf($errstr);
fputs($fp, "POST $path HTTP/1.1\r\n");
fputs($fp, "Host: $host\r\n");
fputs($fp, "Referer: $referer\r\n");
fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
fputs($fp, "Content-length: ". strlen($data_to_send) ."\r\n");
fputs($fp, "Connection: close\r\n\r\n");
fputs($fp, $data_to_send);
printf("Sent!\n");
while(!feof($fp)) {
$res .= fgets($fp, 1000);
}
printf("Done!\n");
fclose($fp);
return $res;
}
$host = "http://www.meinserver.de/posttest.php"
$pfad = "/posttest.php";
$data = "i=halloIchbins!&b=werSonst";
$x = $x = PostToHost($host,$pfad,$host,$data);
echo $x;
Die Datei posttest.php enthält folgenden Code:
<?
echo "huhuuuuuuu ich bin daaaaa";
?>
Wenn ich die Sache richtig verstanden habe, müssten die Daten an die Seite posttest.php übertragen werden und in $x die Antwort der Seite stehen,
schließlich wird ja in der while- Schleife mit fgets die Antwort gelesen.
Die Senderseite meldet aber lediglich: open! success sent!
Das sind die printf's aus der function.
Demnach müsste das Senden klappen, aber wo ist die Antwort?
Seltsamerweise taucht auch in "Live HTTP headers" posttest.php gar nicht auf.
Ich raffs nicht?
gruß
Hi!
$fp = fsockopen($host, 80, $errno, $errstr, 30);
printf("Open!\n");
Das ist ja mal gelogen. Du befragst ja gar nicht den Rückgabewert von fsockopen(), ob die Verbindung geöffnet werden konnte.
fputs($fp, "POST $path HTTP/1.1\r\n");
Version 1.1 ist etwas komplexer zu handhaben als Version 1.0. Wenn du das in der Antwort nicht berücksichtigen willst, solltest du 1.0 nehmen ...
fputs($fp, "Host: $host\r\n");
... auch wenn die Host-Zeile für 1.0 nicht definiert ist. Alle Webserver verstehen das auch so.
$host = "http://www.meinserver.de/posttest.php"
Der erste Parameter von fsockopen() heißt "hostname" und nicht "url".
Lo!
$fp = fsockopen($host, 80, $errno, $errstr, 30);
printf("Open!\n");Das ist ja mal gelogen. Du befragst ja gar nicht den Rückgabewert von fsockopen(), ob die Verbindung geöffnet werden konnte.
OK, das hatte ich, zugegeben ohne groß nachzqdenken, aus diesem Beispiel http://www.php-faq.de/q-code-post.html übernommen.
Ich hab jetzt die Version auf 1.0 gesetzt, den Host und den Pfad getrennt,
der $errstr meldet Success.
Trotzdem kriege ich keine Antwort von der anderen Seite in $x.
Hello,
Trotzdem kriege ich keine Antwort von der anderen Seite in $x.
Du solltest keine leeren Header senden, also keine, bei denen nur der Name aber kein Value gesendet wird. Das mögen die Server meistens nicht.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hi!
$fp = fsockopen($host, 80, $errno, $errstr, 30);
der $errstr meldet Success.
Werte lieber $fp aus und nur wenn das false ist, brauchst du dir die $err...-Inhalte anzusehen.
Trotzdem kriege ich keine Antwort von der anderen Seite in $x.
Die fputs()-Aufrufe liefern auch schön eine Zahl und kein false?
Lo!
Trotzdem kriege ich keine Antwort von der anderen Seite in $x.
Die fputs()-Aufrufe liefern auch schön eine Zahl und kein false?
ich hab mal probiert:
$f1 =fputs($fp, "POST $path HTTP/1.0\r\n");
echo $f1 . "<br>";
das selbe bei allen fputs().
Nichts, keine Zahl, bei keinem :(
Hi!
$f1 =fputs($fp, "POST $path HTTP/1.0\r\n");
echo $f1 . "<br>";
das selbe bei allen fputs().
Nichts, keine Zahl, bei keinem :(
Nimm var_dump() statt echo, dann siehst du vermutlich ein false. Ergibt var_dump($fp) nach dem fsockopen() auch false? error_reporting steht auf E_ALL?
Lo!
Nimm var_dump() statt echo, dann siehst du vermutlich ein false. Ergibt var_dump($fp) nach dem fsockopen() auch false? error_reporting steht auf E_ALL?
Lo!
OK hab var_dump() genommen.
Hab nun folgenden Effekt.
Ich starte das Script, der Browser meldet in der Statuszeile: Übertragen der Daten von...
nach ner ganzen Weile meldet die Seite bool(false) Connection timed out
bool(false) der var_dump($fp)
Connection timed out der $errstr.
Daraufhin habe ich einen anderen Host genommen, einfach um zu sehen was $fp macht. Immer ist $fp false.
Hi!
bool(false) der var_dump($fp)
Connection timed out der $errstr.
Daraufhin habe ich einen anderen Host genommen, einfach um zu sehen was $fp macht. Immer ist $fp false.
Auch bei google.com oder 74.125.43.99 (eine von deren IP-Adressen)? Dann hast du vielleicht ein Netzwerkproblem. Kannst du denn die gewünschten Hosts/Adressen direkt erreichen oder gehst du mit dem Browser über einen Proxy?
Lo!
Auch bei google.com oder 74.125.43.99 (eine von deren IP-Adressen)? Dann hast du vielleicht ein Netzwerkproblem. Kannst du denn die gewünschten Hosts/Adressen direkt erreichen oder gehst du mit dem Browser über einen Proxy?
Lo!
Ich hab, den ganzen Code in den Papierkorb geworfen und komplett neu geschrieben.
Durch das viele hin- und her hatte sich da wohl ein Fehler eingeschlichen.
Jetzt siehts so aus:
function PostToHost($host, $path, $referer, $data_to_send) {
$fp = fsockopen($host, 80, $errno, $errstr, 30);
var_dump($fp);
printf $errstr;
if(!$fp){
// hier kommt später die Fehlermeldung hin
} else {
fputs($fp, "POST $path HTTP/1.1\r\n");
fputs($fp, "Host: $host\r\n");
fputs($fp, "Referer: $referer\r\n");
fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
fputs($fp, "Content-length: ". strlen($data_to_send) ."\r\n");
fputs($fp, "Connection: close\r\n\r\n");
fputs($fp, $data_to_send);
while(!feof($fp)) {
$res .= fgets($fp, 1000);
}
fclose($fp);
return $res;
}
}
$host = "www.google.de"
$path = "";
$data = "i=irgendwas&p=nochmalwas";
$x = PostToHost($host, $pfad, "irgendeineRefferer.de", $data);
echo $x;
jetzt meldet $fp resource(20) of type (stream)
Wenn ich den host und den path auf meine realen Daten setze, kommt das selbe
aber $x ist immer noch leer.
Es klappt,
hatte das echo für $x vergessen.
Die geposteten Daten kommen auch an.
DANKE
Hello,
Es klappt,
hatte das echo für $x vergessen.
Die geposteten Daten kommen auch an.
Dann lass doch nochmal einen Header leer, wie vorhin z.B. den Referer.
Würde mich interessieren, ob es dann auch noch funktioniert.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hallo,
Ich hab, den ganzen Code in den Papierkorb geworfen und komplett neu geschrieben.
das ist manchmal das beste, was man tun kann.
function PostToHost($host, $path, $referer, $data_to_send) {
$fp = fsockopen($host, 80, $errno, $errstr, 30);
var_dump($fp);
printf $errstr;if(!$fp){
// hier kommt später die Fehlermeldung hin
und genau dort ist auch erst die Ausgabe von $errstr sinnvoll.
} else {
fputs($fp, "POST $path HTTP/1.1\r\n");
Du übergibst einen leeren String als $path. Das gibt's aber in HTTP nicht; es entsteht also immer noch ein fehlerhafter Request-Header.
fputs($fp, "Host: $host\r\n");
fputs($fp, "Referer: $referer\r\n");
fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
fputs($fp, "Content-length: ". strlen($data_to_send) ."\r\n");
fputs($fp, "Connection: close\r\n\r\n");
fputs($fp, $data_to_send);while(!feof($fp)) {
$res .= fgets($fp, 1000);
}
Hier sammelst du Responsedaten in $res, hast aber versäumt, $res vorher zu initialisieren.
fclose($fp);
return $res;
}
}$host = "www.google.de"
$path = "";
$data = "i=irgendwas&p=nochmalwas";$x = PostToHost($host, $pfad, "irgendeineRefferer.de", $data);
echo $x;
jetzt meldet $fp resource(20) of type (stream)
Das ist schon mal was - die Verbindung mit der Gegenstelle hat also geklappt.
Wenn ich den host und den path auf meine realen Daten setze, kommt das selbe
aber $x ist immer noch leer.
Das überrascht mich - zumindest die Response-Header würde ich erwarten. Hier wegen des Fehlers mit $path wohl am ehesten ein "400 Bad Request". Dass gar nichts kommt, finde ich eigenartig.
So long,
Martin
Hello,
Ich starte das Script, der Browser meldet in der Statuszeile: Übertragen der Daten von...
nach ner ganzen Weile meldet die Seite bool(false) Connection timed out
bool(false) der var_dump($fp)
Connection timed out der $errstr.Daraufhin habe ich einen anderen Host genommen, einfach um zu sehen was $fp macht. Immer ist $fp false.
Hast Du das Script auch schonmal von einem lokalen Webserver (z.B. XAMPP) gestartet, der über einen transparenten Internet-Anschluss verfügt (z.B. dein DSL-Anschluss)?
Es wäre nach deiner Beschreibung durchaus möglich, dass ausgehende Requests von deinem Web-Server aus nicht erlaubt sind. Wenn die Firewall die Pakete blockt (wegschmeißt), dann bekommst Du im Script nur einen Timeout, keine weitere Fehlermeldung.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hallo,
Ich starte das Script, der Browser meldet in der Statuszeile: Übertragen der Daten von...
nach ner ganzen Weile meldet die Seite bool(false) Connection timed out
Daraufhin habe ich einen anderen Host genommen, einfach um zu sehen was $fp macht. Immer ist $fp false.
zeig doch nochmal komplett, wie dein derzeitiger Testcode aussieht. Ich werde das Gefühl nicht los, dass da noch ein grundlegender Fehler drinsteckt.
Ciao,
Martin
Hi,
Neben dem von dedlfix angemerkten Dingen:
$x = $x = PostToHost($host,$pfad,$host,$data);
Doppelt zugewiesen hält besser?
cu,
Andreas
Hi,
Neben dem von dedlfix angemerkten Dingen:
$x = $x = PostToHost($host,$pfad,$host,$data);
Doppelt zugewiesen hält besser?
Sorry, das ist irgendwie beim Übertragen reingerutscht.
Ist natürlich im original Code richtig.
Hi,
$host = "http://www.meinserver.de/posttest.php"
dass ein fsockopen() nur einen Hostnamen haben will, und keine komplette URL, hat dedlfix ja schon festgestellt. Der Request *kann* also nicht gelingen, bereits fsockopen() muss fehlschlagen. Auf eine Fehlerbehandlung hast du leider völlig verzichtet.
Seltsamerweise taucht auch in "Live HTTP headers" posttest.php gar nicht auf.
Wie sollte auch? Selbst wenn wir mal annehmen, die Adressierung sei richtig - wie sollte etwas, das außerhalb des Browsers läuft, in dessen HTTP-Logger erscheinen?
Außerdem bitte ich dich, für Beispiele nicht frei erfundene Domainnamen zu verwenden, die jemand anderem gehören, sondern die extra dafür vorgesehenen.
Ciao,
Martin
Hello,
$data = "i=halloIchbins!&b=werSonst";
Und dann schau Dir nochmal z.B. mittels des Browser-Add-Ons "Live HTTP Headers" für den Firefox an, wie ein Browser so ein POST aufbaut. Genauso muss das dann Deine Funktion auch machen.
Nam-Value-Pärchen erhalten im Post-Body jeweils eine eigene Zeile.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hi,
Nam-Value-Pärchen erhalten im Post-Body jeweils eine eigene Zeile.
Das träumst du aber.
MfG ChrisB
Hello,
Hi,
Nam-Value-Pärchen erhalten im Post-Body jeweils eine eigene Zeile.
Das träumst du aber.
Echt?
Dann weiß ich jetzt auch, warum ich morgens immer so müde bin ;-P
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hello,
Nam-Value-Pärchen erhalten im Post-Body jeweils eine eigene Zeile.
Das träumst du aber.
Echt?
Dann weiß ich jetzt auch, warum ich morgens immer so müde bin ;-P
Ok, ich war jetzt von
Content-Type: multipart/form-data
ausgegangen. Da bekommt jedes Name-Value-Pärchen einen eigenen Abschnitt; eben "Multipart".
Wie ich mit einem Browser bei POST
Content-type: application/x-www-form-urlencoded
erzeugen kann, habe ich noch nicht entdeckt.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hi,
Wie ich mit einem Browser bei POST
Content-type: application/x-www-form-urlencoded
erzeugen kann, habe ich noch nicht entdeckt.
"application/x-www-form-urlencoded" ist der Defaultwert für das enctype-Attribut eines POST-Formulars.
MfG ChrisB
Hello,
Wie ich mit einem Browser bei POST
Content-type: application/x-www-form-urlencoded
erzeugen kann, habe ich noch nicht entdeckt.
"application/x-www-form-urlencoded" ist der Defaultwert für das enctype-Attribut eines POST-Formulars.
Danke. Dachte ich mir doch. War aber eben zu faul, es auszuprobieren (hab gerade mal wieder meinen XAMPP kaputtgespielt), oder nachzuschauen. ;-P
Also, wenn man meine "method" angibt?
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
hi eddi,
zuallererst: Schau mal in das ServerLog, ob Dein Request überhaupt ankommt.
Und was mir so auffällt, warum HTTP/1.1?
fputs($fp, "POST $path HTTP/1.1\r\n");
Du sendest den Header
fputs($fp, "Connection: close\r\n\r\n");
und möchtest dann das Socket auslesen. Es ist angebracht, dazu die Version HTTP/1.0 zu nehmen, das macht die Sache einfacher: Mit dem Request-Header "Connection: close" wird der Server angewiesen, die Response zu senden und unmittelbar danach die Verbindung zu schließen. D.h., Du liest die Response einfach solange aus dem Socket, bis nichts mehr kommt (Server schließt Socket).
Hotti
Hello Hotti,
ich fand es ja auch noch spannend herauszufinden, warum es nicht funktioniert hat. Ich glaube bisher immer noch, dass das an dem leeren Header (Referer) lag. Leider hat sich eddi ja ausgeklinkt, und es nicht nochmal ausprobiert.
Siehe https://forum.selfhtml.org/?t=203793&m=1378854
und https://forum.selfhtml.org/?t=203793&m=1378799
Leider habe ich im Moment keinen Testserver zur Verfügung. Ich warte noch auf die neuen HDDs, vorher installier ich mein Sorgenkind nicht nochmal :-(
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Helo Tom,
ich fand es ja auch noch spannend herauszufinden, warum es nicht funktioniert hat. Ich glaube bisher immer noch, dass das an dem leeren Header (Referer) lag. Leider hat sich eddi ja ausgeklinkt, und es nicht nochmal ausprobiert.
Siehe https://forum.selfhtml.org/?t=203793&m=1378854
und https://forum.selfhtml.org/?t=203793&m=1378799
Es könnte spannend bleiben ;)
Leider habe ich im Moment keinen Testserver zur Verfügung. Ich warte noch auf die neuen HDDs, vorher installier ich mein Sorgenkind nicht nochmal :-(
Ok, ich habe das gerade eben mal mit Perl getestet. 'Leere' Header like:
Otto:
Referer:
Referrer:
foo:
bar:
kommen alle am Server an als HTTP_OTTO, HTTP_FOO, HTTP_BAR usw. (in Hash %ENV) und die Response folgt prompt (lokal und remote getestet). Wie gesagt, mit Perl: nopro.
Hotti
Hallo,
Ok, ich habe das gerade eben mal mit Perl getestet. 'Leere' Header like:
Otto:
Referer:
Referrer:
foo:
bar:
kommen alle am Server an als HTTP_OTTO, HTTP_FOO, HTTP_BAR usw. (in Hash %ENV) und die Response folgt prompt (lokal und remote getestet). Wie gesagt, mit Perl: nopro.
PHP hat damit bei "erwarteten", standardisierten Headern auch kein Problem, dann existiert halt $_SERVER['HTTP_REFERER'], enthält aber einen String der Länge 0. Der Zugriff auf unbekannte, nicht standardisierte Header ist in PHP sowieso schwierig, vielleicht sogar unmöglich. Mir ist jedenfalls keine Methode bekannt.
Ciao,
Martin
Hello,
Ok, ich habe das gerade eben mal mit Perl getestet. 'Leere' Header like:
Otto:
Referer:
Referrer:
foo:
bar:
kommen alle am Server an als HTTP_OTTO, HTTP_FOO, HTTP_BAR usw. (in Hash %ENV) und die Response folgt prompt (lokal und remote getestet). Wie gesagt, mit Perl: nopro.PHP hat damit bei "erwarteten", standardisierten Headern auch kein Problem, dann existiert halt $_SERVER['HTTP_REFERER'], enthält aber einen String der Länge 0. Der Zugriff auf unbekannte, nicht standardisierte Header ist in PHP sowieso schwierig, vielleicht sogar unmöglich. Mir ist jedenfalls keine Methode bekannt.
Schade, ich dachte, das war es, denn so ein Verhalten ist mir schon öfter begegnet. Und wenn dann die Header gefüllt wurden, war der Fehler weg. Ok, dann war das wohl auch nur Zufall.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
hi,
PHP hat damit bei "erwarteten", standardisierten Headern auch kein Problem, dann existiert halt $_SERVER['HTTP_REFERER'], enthält aber einen String der Länge 0. Der Zugriff auf unbekannte, nicht standardisierte Header ist in PHP sowieso schwierig, vielleicht sogar unmöglich. Mir ist jedenfalls keine Methode bekannt.
Hmm, hast Du das mal getestet, also die komplette Serverumgebung mal ausgegeben? Es kann schon möglich sein, dass PHP in Zusammenarbeit mit dem ApacheWebserver stricter vorgeht als Perl und wenn ich mich nicht irre, müssen custom-Header mit Prefix 'x-' eingeleitet werden.
Hotti