Mailinglisten-Archive |
Hallo Liste, ich bin eher ein stiller Teilnehmer dieser Liste. Nun bin ich jedoch auf ein Problem gestoßen, bei dem ich alleine nicht mehr weiterkomme ich nun auf eure Hilfe bauen muss. Grob geht es darum einen POST-Request an einen Server zu schicken und die Response des Servers wieder auszugeben. Dabei schicke ich im POST eine Datei mit. Dies sei aber nur am Rande erwähnt, weil das eigentliche Problem ist - wie der Titel es schon andeutet - das Auslesen der Response. Quelltext beschreibt es vielleicht exakter. Daher zunächst einmal meine Funktion (Erklärung folgt nach dem Quelltext): function sendPostData($host, $port, $path, $filepath, $ssl = true ) { $scheme = ($ssl) ? "ssl://" : ""; $ip = gethostbyname($host); $url = $ip . ':' . $port . $path; if ( ( $io = fsockopen( $scheme.$url, $port, $errno, $errstr, 10 ) !== false ) { $boundary = "---------------------------0123456789012"; if (file_exists($filepath)) { $contentfile = file_get_contents($filepath); } else { $contentfile = null; } // set header info ... $header = "POST $path HTTP/1.1\r\n"; $header .= "Host: $host\r\n"; $header .= "User-Agent: werAuchImmer\r\n"; $header .= "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q= 0.8,image/png,*/*;q=0.5\r\n"; $header .= "Accept-Encoding: gzip,deflate\r\n"; $header .= "Keep-Alive: 300\r\n"; $header .= "Connection: keep-alive\r\n"; $header .= "Content-type: multipart/form-data, boundary=".$boundary."\r\n"; // ... and attach the file $data = "--".$boundary."\r\n"; $data .= "Content-Disposition: form-data; name=\"dateiupload\"; filename=\"".$filepath."\"\r\n"; $data .= "Content-Type: application/upload\r\n\r\n"; $data .= $contentfile."\r\n"; $data .= "--".$boundary."--\r\n"; $header .= "Content-Length: " . strlen($data) . "\r\n\r\n"; $header .= $data; // then just fputs($io, $header); // get header $response = ''; do { $response .= fgets ( $io, 4096 ); } while ( strpos ( $response, "\r\n\r\n" ) === false ); // and get header infos $info = decode_header ( $response ); $response = ''; $starttime = time() + 80; $test = array(); $start = microtime(true); $i = 1; while ( !feof($io) ) { $test[$i]['timea'] = (microtime(true) - $start) * 1000; $response .= fread( $io, 1024 ); $test[$i++]['timeb'] = (microtime(true) - $start) * 1000; if ($starttime <= time()) { return false; } } // print_r($test); fclose ( $io ); $response = decode_body ( $info, $response ); return $response; } else { return "Fehler: $errno - $errstr<br />\n"; } return false; } Zu den Parametern: $host: z.B. www.example.com $port: z.B. 8443 $path: z.B. /pfad/zu/einer/datei.php?mit=parametern $filepath: Pfad zu einer Datei, z.B. einem PDF-Dokument, welches mitgeschickt werden soll $ssl: Über SSL oder eben nicht... Innerhalb der Funktion werden 2 Hilfsfunktionen verwendet. "decode_header" holt sich dabei nur die zurückgelieferten Header-Informationen und packt diese zur Weiterverarbeitung in ein Array. "decode_body" nutzt diese Header-Informationen um den Body entsprechend darzustellen. So far... Die Funktion ist effektiv, aber nicht effizient. Ich will damit sagen dass ich bei einer Anfrage 60 Sekunden auf warten muss, bis mir das Ergebnis angezeigt wird. Nach kurzer Analyse habe ich dann auch den zeitkritischen Teil ausfindig machen könnt. Wie ihr an der Funktion sehen könnt, sind sogar noch die letzten Variablen für die Zeitmessungen drin (absichtlich). Die gesamte Funktion wird schnell durchlaufen, bis hin zu den fread. Hier gehen gute 59 Sekunden der gesamten 60 Sekunden drauf. Nach weiterer Analyse (so wie ihr es jetzt auch seht) habe ich dann festgestellt, dass diese 59 Sekunden durch den letzten Schleifendurchlauf zustande kommen. Ich habe keine Ahnung warum, aber im letzten Durchlauf scheint fread zu hängen. Ein Blick in die zurück gelieferten Header brachte keine weiteren Erkenntnisse. Bei mir wurden nur die Standard-Header gesetzt wie Status 200 usw. Ich gehe also davon aus, dass mir die Daten nicht als chunked oder so zurückgeliefert werden. Austauschen von fread mit fgets brachte auch kein anderes Verhalten. Getestet habe ich es mit unterschiedlichen PHP-Versionen (5.0.3 und eine ganz aktuelle - kann gerade leider nicht genau sagen welche). Hat irgendwer auf dieser Liste schon ähnliche Erfahrungen gesammelt und kennt vielleicht meinen Fehler? Ich bin für jede konstruktive Hilfe dankbar! // Michael Hansen
php::bar PHP Wiki - Listenarchive