Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] HTTP Post mit PHP (Stream Funktionen)

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [Erledigt] HTTP Post mit PHP (Stream Funktionen)

    Hallo,
    ich möchte mit PHP einen HTTP Post an einen entfernten Webserver senden. Hierzu habe ich folgenden Code geschrieben:

    function PostToHost($host, $path, $referer, $data_to_send) {
    $opts = array('ssl'=>array(
    'local_cert'=>"",
    'passphrase'=>"",
    'capath'=>"c:/2/"));
    $context = stream_context_create();
    $result = stream_context_set_option($context, 'ssl', 'local_cert', 'c:/2/userzertifikat.pem');
    $result = stream_context_set_option($context, 'ssl', 'passphrase', 'ffffffff');
    $result = stream_context_set_option($context, 'ssl', 'capath', '');

    $fp = fsockopen($host, 80, $errno, $errstr, 5, $context);
    printf("Open!\n");
    fputs($fp, "POST $path HTTP/1.1\r\n");
    fputs($fp, "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, */*\r\n");
    fputs($fp, "Referer: https://test/test/\r\n");
    fputs($fp, "Accept-Language: de\r\n");
    fputs($fp, "Content-Type: application/x-www-form-urlencoded\r\n");
    fputs($fp, "Accept-Encoding: gzip, deflate\r\n");
    fputs($fp, "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; MyIE2; .NET CLR 1.1.4322)\r\n");
    fputs($fp, "Host: $host\r\n");
    fputs($fp, "Cache-Control: no-cache");
    fputs($fp, "Connection: close\r\n\r\n");
    fputs($fp, $data_to_send);
    printf("Sent!\n");
    while(!feof($fp)) {
    $res .= fgets($fp, 12;
    }
    printf("Done!\n");
    fclose($fp);

    return $res;
    }
    Schön ist schonmal, dass der Code funktioniert, d.h. an der Gegenstelle kommt was an und das Zertifikat (da SSL) wird auch korrekt angewendet. Schlecht ist hingegen, dass die Gegenstelle (Apache Webserver) mir folgenden Fehler ausgibt:

    HTTP/1.1 400 Bad Request Date: Mon, 10 May 2004 12:52:06 GMT Server: Apache/1.3.26 (Unix) PHP/4.2.3 ApacheJServ/1.1.2 mod_perl/1.27 mod_ssl/2.8.10 OpenSSL/0.9.6g Connection: close Transfer-Encoding: chunked Content-Type: text/html; charset=iso-8859-1 X-Pad: avoid browser bug 169
    Bad Request
    Your browser sent a request that this server could not understand.
    Client sent malformed Host header
    Das war jetzt nicht unbedingt mein Ziel
    Fällt jemandem vielleicht ein Fehler in meinem HTTP Header auf? Muss ich bei HTTPS vielleicht noch etwas anderes beachten?

    Danke für Eure Mühe,

    Exe


    PS: bevor jetzt jemand auf die Idee kommt zu sagen "dann bau doch einfach eine Form und schick die per JS ab" --> ganz schlecht, weil ich auf die Rückmeldung vom Server angewiesen bin und ich wüsste jetzt nicht, wie ich eine Server Rückmeldung per JS an mein PHP Skript zur Weiterverarbeitung übergebe ...

  • #2
    Hatte auch mal ein Problem mit der POST Übermittlung. Bei mir hats geklappt nachdem ich "\r" entfernt hatte.

    Zur POST Übermittlung nutze ich meistens diese Klasse:
    class HTTPPost {

    var $url;
    var $uri;
    var $dataArray = array();

    function HTTPPost($url = '', $dataArray = '') {
    $this->setURL($url);
    $this->setDataArray($dataArray);
    }

    function setUrl($url) {
    if($url != '') {
    $url = preg_replace("|^http://|", "", $url);
    $this->url = substr($url, 0, strpos($url, "/"));
    $this->uri = strstr($url, "/");
    return TRUE;
    } else {
    return FALSE;
    }
    }

    function setDataArray($dataArray) {
    if(is_array($dataArray)) {
    $this->dataArray = $dataArray;
    return TRUE;
    } else {
    return FALSE;
    }
    }

    function post($includeHeaders = false)
    {
    foreach($this->dataArray as $key => $val)
    {
    $dataArray[] = $key."=".urlencode($val);
    }
    $body = implode('&', $dataArray);
    $contentLength = strlen($body);
    $request = "POST $this->uri HTTP/1.1\r\n".
    "Host: $this->url\r\n".
    "User-Agent: HTTPPost\r\n".
    "Content-Type: application/x-www-form-urlencoded\r\n".
    "Content-Length: $contentLength\r\n\r\n".
    "$body\r\n";
    $socket = fsockopen($this->url, 80, &$errno, &$errstr);
    if(!$socket) {
    $result["errno"] = $errno;
    $result["errstr"] = $errstr;
    return $result;
    }
    fputs($socket, $request);
    $inHeader = !$includeHeaders;
    while (!feof($socket))
    {
    $line = fgets($socket, 1024);
    if(!$inHeader)
    {
    $result[] = $line;
    } else {
    $inHeader = (trim($line) != '');
    }
    }
    return $result;
    }

    // Änderung: "\r" raus!!
    function post2($includeHeaders = false)
    {
    foreach($this->dataArray as $key => $val)
    {
    $dataArray[] = $key."=".urlencode($val);
    }
    $body = implode('&', $dataArray);
    $contentLength = strlen($body);
    $request = "POST $this->uri HTTP/1.1\n".
    "Host: $this->url\n".
    "User-Agent: HTTPPost\n".
    "Content-Type: application/x-www-form-urlencoded\n".
    "Content-Length: $contentLength\n".
    "Connection: close\n\n".
    "$body\n";
    $socket = fsockopen($this->url, 80, &$errno, &$errstr);
    if(!$socket) {
    $result["errno"] = $errno;
    $result["errstr"] = $errstr;
    return $result;
    }
    fputs($socket, $request);
    $inHeader = !$includeHeaders;
    while (!feof($socket))
    {
    $line = fgets($socket, 1024);
    if(!$inHeader)
    {
    $result[] = $line;
    } else {
    $inHeader = (trim($line) != '');
    }
    }
    return $result;
    }



    } // end class


    // Beispielanwendung
    //$arr['name'] = 'Daniel';
    //$arr['address'] = 'New York';
    //$arr['email'] = 'daniel@websapp.com';
    //$post = new HTTPPost('data/checkpost.php', $arr);
    //$result = $post->post();
    //foreach($result as $line) {
    // echo "$line
    ";
    //}
    Gruß KiBa

    Kommentar


    • #3
      Dankeschön,
      ich werde die Sache morgen gleich mal testen. Wenns wirklich an den \r liegt, dann

      Allerdings tippe ich immer noch darauf, dass ich bei HTTPS einen anderen Header senden muss... Aus der entsprechenden RFC werde ich aber nicht so richtig schlau.

      Wirklich schön ist, dass ich den Traffic noch nicht mal sniffen kann ...

      Kommentar


      • #4
        Es wäre wohl sinnvoll, beim HTTP Host Parameter nicht den Wert zu verwenden, der auch bei fsockopen() zum Einsatz kommt!!
        fsockopen() braucht ja ein vorangestelltes ssl:// damit es weiss, dass es sich um SSL handelt. Im Host Parameter im HTTP Header ist die Zeichenkette ssl:// natürlich vollkommen unangebracht.

        Absoluter Leichtsinnsfehler, Asche auf mein Haupt

        Kommentar


        • #5
          Hi

          Ich habe ein änliches Script und möchte auch einen SSL Server kontaktieren. Wenn ich das ganze mit fsockopen(..); mache, geht das Script in eine Endlosschleife, das heisst es wartet bis der Timeout abgeloffen ist. Ich habe es auch mit der neuen PHP5 Funktion stream_socket_client(..); versucht. Da habe ich genau das gleiche Problem. An meinem Lan Proxy kann es nicht liegen, denn den habe ich zu testzwecken auch mal ausgeschaltet. Nun meine Frage:

          Kann es sein, dass die Gegenseite keine socket Verbindungen erlaubt? Kann man diese Verbindungen überhaupt blocken? (Es ist eine Website einer grösseren Firma...)

          Danke, fluppel

          Kommentar


          • #6
            ouu mann, bin ich blöd! SSL läuft ja standardmässig über Port 443 und nicht über 80!!!!!

            anyway, cooles forum

            Kommentar


            • #7
              Nur ein kleiner Tipp: Für dich mag vielleicht die PEAR-Klasse "HTTP_Request" (http://pear.php.net/package/HTTP_Request) recht interessant sein.

              Kommentar


              • #8
                Das tönt sehr interessant, muss es jedoch noch ausprobieren.

                Ich hab jedenfalls noch ein Regex Problem: Wie kann ich den folgenden http Header auseinandernehmen, sodass ich nur den Cookie Wert selbst habe?
                Code:
                POST /seite.asp HTTP/1.1
                Accept: */*
                Referer: http://localhost/seite.html
                Accept-Language: de-ch
                Content-Type: application/x-www-form-urlencoded
                Accept-Encoding: gzip, deflate
                User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
                Host: www.domain.com
                Content-Length: 185
                Connection: Keep-Alive
                Cache-Control: no-cache
                Cookie: JSESSIONID=dd38pohdt4; IsiWeb23mobile=1ARKxUC/bANZjgA6qaCb/7jBTqMb+yb91/w5bhCgp3mbWKgIS0YT+QESpY5LBj3XLkHibSps63ypbGUhh4Dr+sA0dw54m+ZUJccTp0tq9U8Mdt16ViVQ+97l990iZn6FtyerY4slEW4lC70UmpEn2cJm+VOfw9LVzgobQ+8vU8/SKc4xixxgY6PLpCKcNV5T5mv3098kvgvxf/Qnc4KNdKUjRx2IcnTE19BdmA==; ARPT=ONZZKJS10.148.24.43CKUIJ; ASPSESSIONIDAQBQADSQ=HACAKHIDALGECDCHFICMFAOH; ASPSESSIONIDASBCDRQB=GPKCJMHDDMPPIJILJDOFMEGH; MenuIds=; MenuSelectID=1_64; LastSelectedID=1_64
                (mit Cookie Wert meine ich dd38pohdt4)
                Ich habs mit folgender Regex versucht:
                Code:
                ^JSESSIONID=([a-z]|[A-Z]|[0-9]){10};^
                Aber diese liefert mir nicht das gewünschte. Als Funktion ist sehrwarhscheindlich preg_split am geeignetsten?

                Kommentar


                • #9
                  Zitat von fluppel
                  Ich habs mit folgender Regex versucht:
                  Code:
                  ^JSESSIONID=([a-z]|[A-Z]|[0-9]){10};^
                  Ich glaube, damit suchst du eine Zeichenkette, die 10 Zeichen a-z, 10 Zeichen A-Z oder 10 Zeichen 0-9 hat. Du willst aber eine Zeichenkette suchen, die 10 Zeichen a-z,A-Z oder 0-9 hat. Also (ungetestet):
                  Code:
                  ]^JSESSIONID=([a-zA-Z0-9]){10};^
                  KMAssS

                  Kommentar


                  • #10
                    Mit der Funktion
                    Code:
                    preg_match('^([a-zA-Z0-9]){10};^',$string,$matches);
                    kommt genau das raus:
                    Code:
                    Array ( [0] => dd38pohdt4; [1] => 4 )
                    Keine Ahnung von wo die vier kommt und ich weiss auch nicht wie ich das ";" wegbringe, denn ohne diesen Charakter sucht die Funktion einfach nach einem 10 Zeichenmuster, da könnte auch mal ein anderer String rauskommen. Diese Regular Expressions bleiben mir ein Rätsel...

                    Kommentar


                    • #11
                      Zitat von fluppel
                      Code:
                      preg_match('^([a-zA-Z0-9]){10};^',$string,$matches);
                      Ich weiß zwar nicht was du da machts ... das hier geht auf jeden Fall:
                      Code:
                      preg_match('~Cookie: JSESSIONID=([a-zA-Z0-9]{10});~',$string,$matches)
                      KMAssS

                      Kommentar


                      • #12
                        Danke vielmals! Das geht perfekt. Wie hast du denn Regular Expressions gelernt? Ich find die ziemlich komplex und schwer verständlich..

                        Was ich da mache? Ein Script, welches sich automatisch auf eine Site (Mobilfunk..) einloggt, ein SMS sendet und sich wieder ausloggt. Die einfachste Variante ist, so denke ich jedenfalls, einfach die rohen http(s) Header zu senden und zu verwerten.

                        Kommentar


                        • #13
                          Hi!

                          Die Seite hier ist das erste und (fast) das einzige was ich bisher über Regexe gelesen habe und das hat mich schon ziemlich weit gebracht:

                          http://tut.php-q.net/regex.html

                          Außerdem ist dieses Board hier noch zu empfehlen, wenns um Regexe geht (leider auf Englisch):

                          http://www.regexp.org/

                          Viel Erfolg noch mit deinem Projekt...

                          KMAssS

                          Kommentar

                          Lädt...
                          X