Tommi: Request auswerten

Moin!

Ich möchte einen POST-Request auswerten. Angenommen, es wird folgender Request gesendet:

<?php  
$host = '127.0.0.1';  
$path = '/foobar.php';  
$request = "foobar";  
  
$fp = fsockopen ($host, 80, $error_nr, $error, 3);  
$http_request  = "POST " . $path . " HTTP/1.0\r\n";  
$http_request .= "Host: " . $host . "\r\n";  
$http_request .= "Content-Type: application/x-www-form-urlencoded; charset=utf-8\r\n";  
$http_request .= "Content-Length: " . strlen($request) . "\r\n";  
$http_request .= "\r\n";  
$http_request .= $request;  
fwrite($fp, $http_request);  
?>

Mit $_SERVER komme ich an die Header-Daten ran. Aber wie komme ich an den eigentlichen Inhalt, also $request (hier "foobar")?

Tommi

  1. Hello,

    Ich möchte einen POST-Request auswerten. Angenommen, es wird folgender Request gesendet:

    <?php

    $host = '127.0.0.1';
    $path = '/foobar.php';
    $request = "foobar";

    $fp = fsockopen ($host, 80, $error_nr, $error, 3);
    $http_request  = "POST " . $path . " HTTP/1.0\r\n";
    $http_request .= "Host: " . $host . "\r\n";
    $http_request .= "Content-Type: application/x-www-form-urlencoded; charset=utf-8\r\n";
    $http_request .= "Content-Length: " . strlen($request) . "\r\n";
    $http_request .= "\r\n";
    $http_request .= $request;
    fwrite($fp, $http_request);
    ?>

    
    >   
    > Mit $\_SERVER komme ich an die Header-Daten ran. Aber wie komme ich an den eigentlichen Inhalt, also $request (hier "foobar")?  
      
    Ich weiß jetzt nicht genau, was Du willst.  
    Aber vielleicht ist es hilfreich, wenn Du dir mal einen Request aus dem Browser mit der Live HTTP Headers Extension des Firefox ansiehst?  
      
    Dann sollte es klar sein, was da vom Client gesendet und vom Swerver geantwortet wird.  
      
      
    Liebe Grüße aus dem schönen Oberharz  
      
      
    Tom vom Berg  
    ![](http://selfhtml.bitworks.de/Virencheck.gif)  
      
    
    -- 
     ☻\_  
    /▌  
    / \ Nur selber lernen macht schlau  
    <http://bergpost.annerschbarrich.de>
    
    1. Moin Tom!

      Ich weiß jetzt nicht genau, was Du willst.

      Am liebsten wäre mir der komplette Request mit Header und Body als String, den ich dann auswerten kann.

      Tommi

  2. Hi,

    Ich möchte einen POST-Request auswerten. Angenommen, es wird folgender Request gesendet:

    <?php

    $host = '127.0.0.1';
    $path = '/foobar.php';
    $request = "foobar";

    $fp = fsockopen ($host, 80, $error_nr, $error, 3);
    $http_request  = "POST " . $path . " HTTP/1.0\r\n";
    $http_request .= "Host: " . $host . "\r\n";
    $http_request .= "Content-Type: application/x-www-form-urlencoded; charset=utf-8\r\n";
    $http_request .= "Content-Length: " . strlen($request) . "\r\n";
    $http_request .= "\r\n";
    $http_request .= $request;
    fwrite($fp, $http_request);
    ?>

      
    Was willst du jetzt auswerten - einen POST-Request, der an deinen Server gestellt wird, oder die \*Antwort\* auf einen POST-Request, den du mit obigem Code an einen fremden Server schickst?  
      
    (Auch wenn du 127.0.0.1 als Adresse verwendest [wirklich?], musst du dir klar darüber sein, wer Client und wer Server ist.)  
      
    
    > Mit $\_SERVER komme ich an die Header-Daten ran.  
      
    Nur an die des Request, der an dein Script geschickt wird.  
      
    
    > Aber wie komme ich an den eigentlichen Inhalt, also $request (hier "foobar")?  
      
    Was eigentlich dein Problem ist, ist mir immer noch nicht richtig klar.  
      
    Wie man die Antwort, die nach dem HTTP-Request über fsockopen eintrifft, ausliest, das sollten dir die Beispiele im Manual aber deutlich genug zeigen.  
      
    MfG ChrisB  
      
    
    -- 
    “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
    
    1. Was willst du jetzt auswerten - einen POST-Request, der an deinen Server gestellt wird, oder die *Antwort* auf einen POST-Request

      Zunächt mal möchte ich den Request auswerten, der bei foobar.php ankommt.

      Tommi

      1. Hi,

        Was willst du jetzt auswerten - einen POST-Request, der an deinen Server gestellt wird, oder die *Antwort* auf einen POST-Request

        Zunächt mal möchte ich den Request auswerten, der bei foobar.php ankommt.

        Das ist immer noch schwamming und zweideutig.

        Möchtest du *im* Script foobar.php die Daten, mit denen dieses aufgerufen wurde, auswerten? Dann kannst du das ganz genauso tun, wie du es auch machen würdest, wenn fsockopen gar nicht im Spiel wäre, und der Request stattdessen bspw. von deinem Browser käme.

        MfG ChrisB

        --
        “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
  3. Hi!

    Ich möchte einen POST-Request auswerten. Angenommen, es wird folgender Request gesendet:
    $http_request .= "Content-Type: application/x-www-form-urlencoded; charset=utf-8\r\n";

    Bei diesem Content-Type kannst du einfach auf die von PHP in $_POST bereitgestellten Werte zugreifen.

    Mit $_SERVER komme ich an die Header-Daten ran.

    Nicht auf alles, sondern nur auf das was dir vom Webserver und von PHP durchgereicht wird.

    Aber wie komme ich an den eigentlichen Inhalt, also $request (hier "foobar")?

    Das was du da sendest entspricht nicht dem angegebenen Content-Type. Da werden Name-Value-Pärchen erwartet. Aber siehe: always_populate_raw_post_data und den Verweis auf php://input.

    Lo!

    1. Moin dedlfix!

      Das was du da sendest entspricht nicht dem angegebenen Content-Type.

      Stimmt, da habe ich gar nicht dran gedacht. Muss dann wohl text/plain sein.

      ... und den Verweis auf php://input.

      OK, das sieht shon mal viel versprechend aus. Werde ich gleich mal testen...

      Tommi

      1. Werde ich gleich mal testen...

        OK, das klappt so weit. Mit $postdata = file_get_contents("php://input"); komme ich an "foobar". Jetzt bleibt noch der Header: wie komme ich z.B. an "Content-Type" bzw. wie komme ich gleich an den gesamten Request (Header und Body)?

        Tommi

        1. Hi!

          wie komme ich z.B. an "Content-Type" bzw. wie komme ich gleich an den gesamten Request (Header und Body)?

          Der gesamte Request steht PHP nicht unter allen Bedingungen zur Verfügung. Mit den Apache-Funktionen kommst du an den Header, wenn PHP als Apache-Modul läuft.

          Lo!

          1. Der gesamte Request steht PHP nicht unter allen Bedingungen zur Verfügung.

            OK, dann ist erst mal alles klar, danke!

            Tommi

  4. Mit $_SERVER komme ich an die Header-Daten ran. Aber wie komme ich an den eigentlichen Inhalt, also $request (hier "foobar")?

    Normalerweise arbeitet man mit $_POST. Aber dafür müssten die Daten in Form variable = Wert übertragen werden (so wie's ein Browser normalerweise mit Formulardaten macht, wenn's Formular gePOSTet werden soll; genaue Form weiss ich jedoch nicht). Was wohl PHP mit deinem schlichten "foobar" anfängt?

    mfg
    Rato

    --
    ie:( fl:( br:< va:) ls:[ fo:| rl:( n4:~ ss:) de:] js:| mo:| zu:)
    §§§
    Meine Postings basieren lediglich auf mein Wissen und können theoretisch faktisch wirklich völliger Blödsinn sein.
    §§§
    1. Normalerweise arbeitet man mit $_POST. Aber dafür müssten die Daten in Form variable = Wert übertragen werden

      Das ist nicht richtig, weder bei GET noch POST ist variable=wert erforderlich

      /foo.php?bar&baz&qux ist z.B. völlig ok. Werte ist ein nettes Goodie, aber keineswegs erforderlich.

      Was wohl PHP mit deinem schlichten "foobar" anfängt?

      Probier's aus, du weist staunen ;)

  5. hi,

    Mit $_SERVER komme ich an die Header-Daten ran. Aber wie komme ich an den eigentlichen Inhalt, also $request (hier "foobar")?

    POST-Daten werden serverseitig, so sagt das Protocol HTTP, aus STDIN gelesen. Dazu hast Du ja schon den richtigen Header im Request: Content-Length. Diese Länge, in bytes, nimmt die serverseitige Anwendung zum Auslesen des Standard-Eingabekanals mit der exakten Länge. Das ist ersteinmal unabhängig von PHP, das ist rein HTTP. Hat der Serverprozess STDIN gelesen, geht es ans Parsen, dies ist wiederum vom Request-Header abhängig, was da zu tun ist.

    In Deinem Fall, mit dem Req-Header
    Content-Type: application/x-www-form-urlencoded; charset=utf-8

    erwartet der Parser Schlüssel=Werte Paare, von denen mehrere mit dem Ampers-and oder mit dem ";" getrennt sind like
    a=1;a=2;a=3;b=4;c=5&d=6&x=y

    usw. Die Werte selbst sind encodet mit dem Prozent-Zeichen für bytes, die Spezial-Chars darstellen würden (z.B. Leerzeichen u.a.). Dies ist ebenfalls immer noch unabhängig von PHP, das ist rein HTTP. Btw., die Charset-Angabe im Request-Header ist optional.

    Ein anderer Content-Type wäre z.B. multipart/form-data, hierbei besteht der Message-Body, wie der Name schon sagt, aus mehreren Teilen, die durch eine boundary (deklariert im Req-Header) getrennt sind. Die Einzelteile zurückzugewinnen, das ist wiederum Aufgabe des Parsers.

    PHP nun, ist soweit entwickelt, dass es anhand des im Req-Header deklarierten Content-Type STDIN lesen kann und Dir im Script die Einzelteile präsentiert. Schick mal anstelle eines Einzelstrings ein paar Schlüssel-Wertepaare mit og. Content-Type, dann findest Du die Werte im POST-Arry.

    Hotti

    1. Hello,

      POST-Daten werden serverseitig, so sagt das Protocol HTTP, aus STDIN gelesen. Dazu hast Du ja schon den richtigen Header im Request: Content-Length. Diese Länge, in bytes, nimmt die serverseitige Anwendung zum Auslesen des Standard-Eingabekanals mit der exakten Länge. Das ist ersteinmal unabhängig von PHP, das ist rein HTTP. Hat der Serverprozess STDIN gelesen, geht es ans Parsen, dies ist wiederum vom Request-Header abhängig, was da zu tun ist.

      In Deinem Fall, mit dem Req-Header
      Content-Type: application/x-www-form-urlencoded; charset=utf-8

      erwartet der Parser Schlüssel=Werte Paare, von denen mehrere mit dem Ampers-and oder mit dem ";" getrennt sind like
      a=1;a=2;a=3;b=4;c=5&d=6&x=y

      usw. Die Werte selbst sind encodet mit dem Prozent-Zeichen für bytes, die Spezial-Chars darstellen würden (z.B. Leerzeichen u.a.). Dies ist ebenfalls immer noch unabhängig von PHP, das ist rein HTTP. Btw., die Charset-Angabe im Request-Header ist optional.

      Dabei handelt es sich im obigen Fall auch um das Content-Encoding, nicht um das Content-Transfer-Encoding. Das bildet eine zweite "Kodierungs-Hülle".

      Muss das eigentlich immer zwingend urlencoding sein, bei HTTP, oder könnte man auch ein anderes Transfer-Encoding verwenden? War mir doch so, dass jede in die URL-Encoding passende Codierung erlaubt ist, z.B. base64. Der Parser müsste mMn also das Transfer-Encoding auch beachten. Vielleicht kennt ja jemand die passende Stelle in den RFC?

      Ein anderer Content-Type wäre z.B. multipart/form-data, hierbei besteht der Message-Body, wie der Name schon sagt, aus mehreren Teilen, die durch eine boundary (deklariert im Req-Header) getrennt sind. Die Einzelteile zurückzugewinnen, das ist wiederum Aufgabe des Parsers.

      PHP nun, ist soweit entwickelt, dass es anhand des im Req-Header deklarierten Content-Type STDIN lesen kann und Dir im Script die Einzelteile präsentiert. Schick mal anstelle eines Einzelstrings ein paar Schlüssel-Wertepaare mit og. Content-Type, dann findest Du die Werte im POST-Arry.

      Liebe Grüße aus dem schönen Oberharz

      Tom vom Berg

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

        Muss das eigentlich immer zwingend urlencoding sein, bei HTTP, oder könnte man auch ein anderes Transfer-Encoding verwenden? War mir doch so, dass jede in die URL-Encoding passende Codierung erlaubt ist, z.B. base64. Der Parser müsste mMn also das Transfer-Encoding auch beachten. Vielleicht kennt ja jemand die passende Stelle in den RFC?

        Es gibt mehrere Content-Types für HTTP und Ähnliche für Mail (MIME). Die Festlegung auf einen bestimmten Content-Type ist nur interessant für den Parser, damit die Einzelteile wieder hergestellt werden können. Btw. Content-Transfer-Encoding ist ein Begriff aus der Mail-Welt.

        application/x-www-form-urlencoded
        und
        multipart/form-data

        sind die Typen, die derzeit von allen Browsern unterstützt werden und auch am weitesten Verbreitung finden. Ansonsten ist es Wurscht, in welcher Form und wie codiert ein Message-Body aufgebaut ist, im meinem CMS gehe ich daher auch einen eigenen Weg zur Übertragung von Content zum Webserver, vereinfacht gesagt, packe ich die Attribute in den Request-Header und habe im Body nur noch die Datei, also die reine Binary; das bezeichne ich als Single-Content, weil hier kein Multipart vorliegt. http://rolfrost.de/httpcont.html

        Auf meinen Seiten findest Du in den Perl-Ordnern weitere Details zu HTTP und auch die (hoffentlich) richtigen Angaben zu den entsprechenden RFCs.

        so, ich muss jetzt mal los,
        Hotti

        --
        MIME ist Müll.
      2. Mahlzeit;

        Dabei handelt es sich im obigen Fall auch um das Content-Encoding, nicht um das Content-Transfer-Encoding. Das bildet eine zweite "Kodierungs-Hülle".

        Nochne Anmerkung: Der Header "Content-Type" hat im Request eine völlig andere Bedeutung als in einer Response. Ebenso ist die Charset-Angabe im Request unnötig, bisher hat das auch kein Browser gemacht, der neue FF macht das jedoch (hat mich schonmal Nerven gekostet).

        Der Header "Content-Transfer-Encoding" spielt nur bei Mail eine Rolle, nicht jedoch bei HTTP. Bei HTTP ist "Content-Type" nur eine Deklaration für den Parser, beispielsweise steht bei

        Content-Type: multipart/form-data; boundary=boundary_string

        hintendran die Zeichenkette der boundary, damit der Parser serverseitig "weiß" wie die Komponenten getrennt sind. Bei multipart/form-data enthält eine Einzelkomponente die Angabe des inhaltsbezogenen "Content-Type" z.B. image/gif. Die Doppeldeutigkeit des Headers "Content-Type" ergibt sich aus der Tatsache, dass es eben in einem Request verschiedene Möglichkeiten gibt, wie Komponenten im Mesg-Body eingebaut sind.

        Anders ists bei einer Response, hier liegt i.d.R. nur _eine_ Komponente vor, und dementsprechend bezieht sich die Angabe "Content-Type" direkt auf den Inhalt. Z.B.

        Content-Type: text/html; charset=UTF-8

        <...hier kommt dann "nur" HTML und nüschd Anderes...>

        Selbstverständlich kannst Du auch eine Multipart-Response senden, die Frage ist dann nur, wie der UserAgent damit zurechtkommt. Ich benutze für meine Ajax-Responsen den Content-Type: application/x-www-urlencoded und kann damit vorzüglich meine Objekte und Arrays serialisiert übertragen. Das Parsen einer solchen Response im DOM funktioniert genauso wie das serverseitige Parsen eines Requests, ich habe damit ein einheitliches Encoding, einheitliche Schnittstellen und bin außerordentlich flexibel damit.

        Bissl was zm Lesen noch http://rolfrost/httproto.html

        Horst Hobbit

        --
        Jetzn Kakao...
  6. Danke an alle, jetzt ist mir einiges klarer!

    Tommi