#include #include "HttpReq.h" #include #include "Log.h" #include boost::asio::io_service HttpReq::io_service; std::string HttpReq::urlEncode(const std::string &s) { const std::string unreserved = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~"; std::string escaped=""; for(size_t i=0; i> http_version; response_stream >> mResponseStatusCode; std::string status_message; std::getline(response_stream, status_message); if(!response_stream || http_version.substr(0, 5) != "HTTP/") { mStatus = REQ_INVALID_RESPONSE; return; } if(mResponseStatusCode != 200) { mStatus = REQ_BAD_STATUS_CODE; return; } // Read the response headers, which are terminated by a blank line. boost::asio::async_read_until(mSocket, mResponse, "\r\n\r\n", boost::bind(&HttpReq::handleReadHeaders, this, boost::asio::placeholders::error)); } else { onError(err); } } void HttpReq::handleReadHeaders(const boost::system::error_code& err) { if (!err) { // Process the response headers. std::istream response_stream(&mResponse); std::string header; while (std::getline(response_stream, header) && header != "\r"); //and by process we mean ignore // Write whatever content we already have to output. if (mResponse.size() > 0) mContent << &mResponse; // Start reading remaining data until EOF. boost::asio::async_read(mSocket, mResponse, boost::asio::transfer_at_least(1), boost::bind(&HttpReq::handleReadContent, this, boost::asio::placeholders::error)); } else { onError(err); } } void HttpReq::handleReadContent(const boost::system::error_code& err) { if (!err) { // Write all of the data that has been read so far. mContent << &mResponse; // Continue reading remaining data until EOF. boost::asio::async_read(mSocket, mResponse, boost::asio::transfer_at_least(1), boost::bind(&HttpReq::handleReadContent, this, boost::asio::placeholders::error)); }else{ if (err != boost::asio::error::eof) { onError(err); }else{ mStatus = REQ_SUCCESS; } } } HttpReq::Status HttpReq::status() { try { io_service.poll(); } catch(boost::system::system_error& e) { LOG(LogError) << "Boost.ASIO system error! " << e.what(); } return mStatus; } std::string HttpReq::getContent() { if(mStatus != REQ_SUCCESS) { LOG(LogError) << "Called getContent() on an unsuccessful HttpReq!"; return ""; } return mContent.str(); } //only called for boost-level errors (REQ_IO_ERROR) void HttpReq::onError(const boost::system::error_code& err) { mError = err; mStatus = REQ_IO_ERROR; } std::string HttpReq::getErrorMsg() { switch(mStatus) { case REQ_BAD_STATUS_CODE: return "Bad status code"; case REQ_INVALID_RESPONSE: return "Invalid response from server"; case REQ_IO_ERROR: return mError.message(); case REQ_IN_PROGRESS: return "Not done yet"; case REQ_SUCCESS: return "No error"; default: return "???"; } }