boost::asio und HTTP POST request
-
Hallo,
also die idee ist ein PHP script auf dem Server zu haben welches einen Upload bewerkstelligt (move_uploaded_file()).
Nun möchte ich aus meiner Applikation via boost::asio eine entsprechende HTTP Post anfrage an dieses Skript übermitteln wie es normalerweise ein HTML formular tun würde um eine datei vom PHP skript hochladen zu lassen.
Ich bin mir aber nicht sicher wie ich den request Header zu definieren habe.
Hat jemand Ahnung?boost::asio::io_service io_service; tcp::resolver resolver(io_service); tcp::resolver::query query("www.meinserver.de", "http"); tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); tcp::resolver::iterator end; tcp::socket socket(io_service); boost::system::error_code error = boost::asio::error::host_not_found; while (error && endpoint_iterator != end) { socket.close(); socket.connect(*endpoint_iterator++, error); } if (error) throw boost::system::system_error(error); boost::asio::streambuf request; std::ostream request_stream(&request); request_stream << "POST " << uploadscriptlocation << " HTTP/1.0\r\n"; request_stream << "Host: www.meinserver.de \r\n"; request_stream << "Accept: */*\r\n"; request_stream << "Content-type: multipart/form-data\r\n"; request_stream << "Connection: close\r\n\r\n"; request_stream << "datei=" << filetoupload; boost::asio::write(socket, request, boost::asio::transfer_all(), error); [...]
Weiß jemand wie das korrekterweise zu bewerkstelligen ist? Vielleicht ist das auch das falsche Forum dafür?
Vielen Dank für jegliche Tipps oder auch den Verweis auf ein HTML forum, aber ich dachte mir dass das vielleicht schonmal jemand mit boost probiert hätte.
Der Vollständigkeit halber schaut das PHP skript so aus:
<?php
move_uploaded_file($_FILES['datei']['tmp_name'], $_FILES['datei']['name']);
?>Gruß
-
Steht alles im RFC Standard 2616:
http://ietfreport.isoc.org/rfc2600-2699.html#rfc2616Oder du verwendest gleich eine fertige Bibliothek, wie zum Beispiel cURL.
Grüssli
-
Hi,
danke erstmal für deine Antwort. Den Standard habe ich mir schon angeschaut und soweit ich das sehe erfüllt mein Request Header alle Anforderungen für eine erfolgreiche POST Anfrage. Das ändert aber leider nichts daran dass es nicht funktioniert. Ich erhalte in der Response auch den Statuscode 200, sprich irgendwie scheint die Anfrage korrekt durchzugehen, aber dennoch wird die Datei nicht hochgeladen (das Skript an sich funktioniert aber, habe ich mit einer simplen HTML form getestet). Die frage ist also warum das nicht funktioniert. Der Standard hilft mir da leider nicht weiter.
Ich möchte desweiteren auch bei Boost bleiben, libcurl hat bei mir einfach Probleme gemacht schon bei den lib erstellungen.
Daher steht meine Frage ob jemand weiß wie man mit boost eine entsprechende POST Anfrage erfolgreich durchkriegt.
Danke.
-
Was kommt denn auf dem Server an? Schon mal probiert ein
<?php print_r($_FILES); ?>
zu machen? Was war das Ergebnis?Grüssli
-
Habe natürlich ein
echo $_FILES['datei']['tmp_name'];
echo "...";
echo $_FILES['datei']['name'];verwendet, wenn ich es via html form mache. Da kommt natürlich alles richtig an.
Aber das seh ich ja nicht wenn ich es direkt aus der Applikation aufrufe. Oder wie kann ich das in meiner Applikation auslesen?Edit: print_r gibt aus
Array ( [datei] => Array ( [name] => test.zip [type] => application/x-zip-compressed [tmp_name] => /mnt/shared/tmp/phpr0aG24 [error] => 0 [size] => 163 ) )
-
Katachi schrieb:
Habe natürlich ein
echo $_FILES['datei']['tmp_name'];
echo "...";
echo $_FILES['datei']['name'];verwendet, wenn ich es via html form mache. Da kommt natürlich alles richtig an.
Aber das seh ich ja nicht wenn ich es direkt aus der Applikation aufrufe. Oder wie kann ich das in meiner Applikation auslesen?Mich würde vor allem auch noch die anderen Parameter interessieren. Über deine Applikation kannst du es dir anzeigen lassen, wenn du einfach das zurückerhaltene irgendwohin speicherst.
Katachi schrieb:
Edit: print_r gibt aus
Array ( [datei] => Array ( [name] => test.zip [type] => application/x-zip-compressed [tmp_name] => /mnt/shared/tmp/phpr0aG24 [error] => 0 [size] => 163 ) )Ist das nun das, was du über die Applikation zurückerhälst oder über die Form? Wenn es über die Applikation ist, stimmt es denn mit dem überein, was du gesendet hast? Also ist das File auch 163 Bytes gross?
Grüssli
-
Das ist was ich von der Form erhalte und ist auch die richtige dateigröße.
Da ich direkt im debugmodus bin lese ich die Response aus, aber da steht nichts vom Dateinamen oder ähnlichem:boost::asio::streambuf responser; boost::system::error_code errorcode; while (boost::asio::read(socket, responser, boost::asio::transfer_all(), errorcode)); // Check that response is OK. std::istream response_stream(&responser); std::string http_version; response_stream >> http_version; unsigned int status_code; response_stream >> status_code; std::string status_message; std::getline(response_stream, status_message); if (!response_stream || http_version.substr(0, 5) != "HTTP/") { socket.close(); return false; } if (status_code != 200) { socket.close(); return false; } // Read the response headers, which are terminated by a blank line. boost::asio::read_until(socket, responser, "\r\n\r\n"); // Process the response headers. std::string header; while (std::getline(response_stream, header) && header != "\r") std::cout << header << "\n"; std::cout << "\n"; if (responser.size() > 0){ std::cout << &responser; } // Read until EOF while (boost::asio::read(socket, responser,boost::asio::transfer_at_least(1), error)){ std::cout << &responser; } socket.close();
Im response steht lediglich:
"das Datum, servertyp (also apache), php version, Transfer-Encoding: chunked, Content-type: text/html, Array()0"Sagt mir jetzt nicht wirklich viel, aber hinten das Array()0, könnte das bedeuten dass das Array nicht gefüllt ist (so wie es print_r ausgibt?)?
-
Ok, wusste ich doch, dass da etwas am Upload Protocol nicht stimmt. Musste aber zwischenzeitlich auch zuerst nochmals nachsehen gehen. Am besten liest du dir mal das RFC 2388 durch, welches den Teil über
multipart/form-data
abhandelt. Beispiele gibt es auch genügend im Netz:
http://www.monkey-business.biz/842/http-post-datei-upload-rfc1867/
http://www.coder-wiki.de/HowTos/PHP-POST-Request-Datei
http://www.php-faq.de/q-code-upload.htmlDamit sollte es nun eigentlich zu schaffen sein. Die korrekte Antwort ist übrigens 201 und nicht 200.
Grüssli
-
ok, danke, das lese ich mir erstmal durch und schaue mir die links an. Ich hatte zwar schon gelesen dass 201 (also neue Resource erstellt) als Antwort die richtige sein könnte, aber na ja, mein Gehirn wollte wohl nicht daran glauben.
thx erstmal, wenn ich es gelesen hab und probiert habe melde ich mich zurück.
-
Vielen Dank nochmal. Mit der richtigen standard Definition hat es jetzt funktioniert.
Im übrigen ist die Response trotzdem 200!
-
Hallo,
habe das gleiche Problem.
Könntest du evtl. mal posten wie du es gelöst hast.
Gruß
-
Ich vermute, der wird dir nicht antworten. Ist wohl schüchtern.