HTTP Client mit Boost ASIO in einem Proxy Netzwerk
-
Hallo Leute,
ich habe mir mit Boost (ASIO) einen HTTPClient gebaut.
Es treten jetzt bei einem speziellen Fall folgende Probleme auf:
Die Methode handleReadContent() empfängt die Daten, und schreibt sie in ein File. Das passiert so lange, bis eof (end of file) erreicht ist.
Es kann jetzt aber passieren, dass kein eof kommt (keine Daten kommen). Das File ist aber trotzdem komplett geladen nur leider steht mein C++ Programm.
Schliesslich wurde die eof Bedienung nie erfüllt.Wann passiert das ganze:
- Nur bei großen Files (jpg funktioniert trotzdem, Videos funktionieren nicht)
- Nur bei einem speziellen Netzwerk (ich glaube es hat was mit Proxy zu tun)HTTP-Response von dem Netzwerk mit Proxy (funktioniert nicht):
Via: 1.1 STATMG01 Connection: Keep-Alive Proxy-Connection: Keep-Alive Content-Length: 11713528 Date: Thu, 11 Apr 2013 11:24: Content-Type: text/texmacs ETag: "788a9e9-b2bbf8-4d446d6 Server: Apache/2.2.16 (Debian Accept-Ranges: bytes Last-Modified: Sun, 27 Jan 20
HTTP-Response von funktionierenden Netzwerk:
Connection: close Content-Length: 11713528 Date: Thu, 11 Apr 2013 11:23:50 GMT Content-Type: text/texmacs ETag: "788a9e9-b2bbf8-4d446d6991b00" Server: Apache/2.2.16 (Debian) Accept-Ranges: bytes Last-Modified: Sun, 27 Jan 2013 15:30:20 GMT
Unterschiede der HTTP-Headers:
- Connection ist Keep-alive sonst close
- Proxy-Connection: Keep-Alive
- Via: 1.1 STATMG01 wurde hinzugefügtAlso ich nehme mal an der Proxy schreibt da böses Header-Zeugs in meinen Response-Header. Boost kann damit nicht umgehen..? Oder wie kann man sich das sonst vorstellen?
Es folgt nun die Methode wo alles zum stehen kommt.
void HTTPClient::handleReadContent(const boost::system::error_code& error, size_t bytesTransferred) { if (!error) { m_fileStream.open(m_filename.c_str(), std::fstream::out | std::fstream::app); m_fileStream << &m_Response; m_fileStream.close(); // Continue reading remaining data until EOF. boost::asio::async_read(*m_Socket, m_Response, boost::asio::transfer_at_least(1), boost::bind(&HTTPClient::handleReadContent, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } else if (error != boost::asio::error::eof) { std::cout << "error in handleReadContent() " << error << "\n"; } else if(error == boost::asio::error::eof) { m_fileStream.open(m_filename.c_str(), std::fstream::out | std::fstream::app); m_fileStream << &m_Response; m_fileStream.close(); } }
Hier noch der Code wie mein HTTP-Header zusammen gebaut wird. Vielleicht mache ich da ja auch schon was falsch.
std::ostream requestStream(&m_Request); requestStream << "GET " << "/" << m_URL.getPath()+m_URL.getFile() << " HTTP/1.0\r\n"; requestStream << "Host: " << m_URL.getHost() << "\r\n"; requestStream << "Accept: */*\r\n"; addHeaderFieldsToHeader(requestStream); requestStream << "Connection: close\r\n\r\n";
Wäre echt super wenn mir da jemand ein paar Tipps geben könnte. Ich weiß da nicht mehr weiter. Vielleicht gibt es einfache Workarounds?
thx und lg
Darian
-
Du musst erst den Response-Header empfangen, dann
Connection
undContent-Length
auswerten und dann entsprechend den Response-Body empfangen.D.h. wenn
Connection: Keep-Alive
gesetzt ist, musst du auchContent-Length
auswerten und dann noch genau soviele Bytes empfangen, wie angegeben ist.Danach kannst du die Connection entweder schliessen (ein wenig verschwenderisch) oder wieder für den nächsten Request benutzen.
-
Okay danke, werde mir das mal genauer ansehen.
Weil bis jetzt hatte ich immer HTTP 1.0 verwendet und Connection:Close. Mein HTTPClient kann also mit den keep-alive noch nicht umgehen.
thx und lg
Darian