eddi: posttohost, wieso klappt das nicht?

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ß

  1. 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!

    1. $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.

      1. 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

        --
         ☻_
        /▌
        / \ Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
      2. 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!

        1. 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 :(

          1. 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!

            1. 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.

              1. 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!

                1. 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.

                  1. Es klappt,

                    hatte das echo für $x vergessen.
                    Die geposteten Daten kommen auch an.

                    DANKE

                    1. 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

                      --
                       ☻_
                      /▌
                      / \ Nur selber lernen macht schlau
                      http://bergpost.annerschbarrich.de
                  2. 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

                    --
                    Zwei Kumpels sitzen vor dem Computer. "Welche Suchmaschine beutzt du eigentlich meistens?" - "Prima Vera." - "Hmm, kenn' ich gar nicht." Dann geht die Tür auf: "Schatz ich habe deine Sonnenbrille wiedergefunden!" - "Prima, Vera!"
                    Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
              2. 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

                --
                 ☻_
                /▌
                / \ Nur selber lernen macht schlau
                http://bergpost.annerschbarrich.de
              3. 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

                --
                Nein, es ist nicht wahr, dass bei der Post Beamte schneller befördert werden als Pakete.
                Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
  2. Hi,

    Neben dem von dedlfix angemerkten Dingen:

    $x = $x = PostToHost($host,$pfad,$host,$data);

    Doppelt zugewiesen hält besser?

    cu,
    Andreas

    --
    Warum nennt sich Andreas hier MudGuard?
    O o ostern ...
    Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.
    1. 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.

  3. 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

    --
    Ja, ja ... E.T. wusste schon, warum er wieder nach Hause wollte.
    Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
  4. 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

    --
     ☻_
    /▌
    / \ Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de
    1. Hi,

      Nam-Value-Pärchen erhalten im Post-Body jeweils eine eigene Zeile.

      Das träumst du aber.

      MfG ChrisB

      --
      RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
      1. 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

        --
         ☻_
        /▌
        / \ Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
        1. 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

          --
           ☻_
          /▌
          / \ Nur selber lernen macht schlau
          http://bergpost.annerschbarrich.de
          1. 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

            --
            RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
            1. 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

              --
               ☻_
              /▌
              / \ Nur selber lernen macht schlau
              http://bergpost.annerschbarrich.de
  5. 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

    1. 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

      --
       ☻_
      /▌
      / \ Nur selber lernen macht schlau
      http://bergpost.annerschbarrich.de
      1. 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

        1. 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

          --
          Besteht ein Personalrat aus nur einer Person, erübrigt sich die Trennung nach Geschlechtern.
            (aus einer Info des deutschen Lehrerverbands Hessen)
          Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
          1. 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

            --
             ☻_
            /▌
            / \ Nur selber lernen macht schlau
            http://bergpost.annerschbarrich.de
          2. 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