void HttpClient::onRequest(Http::Client& client) { try { Pt::Http::MessageProgress progress = client.endSend(); if( ! progress.finished() ) { client.beginSend(false); return; } while( ! advanceMessage() ) { if(client.request().buffer().size() > 8192) { client.beginSend(false); return; } } finishMessage(); client.beginReceive(); } catch(const System::IOError&) // HttpError is also an IOError { // setError() makes finishResult() call onError() where we throw setError(); finishResult(); } }
virtual void getIdentity(const OAuthAccessToken& token) { Http::Client *client = new Http::Client(this); client->setTimeout(15); client->setMaximumResponseSize(10*1024); client->done().connect (boost::bind(&FacebookProcess::handleMe, this, _1, _2)); client->get("https://graph.facebook.com/me?fields=name,id,email&access_token=" + token.value()); #ifndef WT_TARGET_JAVA WApplication::instance()->deferRendering(); #endif }
std::size_t HttpClientImpl::onReplyBody(http::Client& client) { std::size_t count = 0; char ch; std::istream& is = client.in(); while (is.rdbuf()->in_avail() && is.get(ch)) { ++count; if (_scanner.advance(ch)) { log_debug("scanner finished"); try { _scanner.finalizeReply(); } catch (const RemoteException& e) { _proc->setFault(e.rc(), e.text()); } catch (const std::exception&) { log_warn("exception occured in finalizeReply"); _exceptionPending = true; _proc->onFinished(); } break; } } log_debug("no more data - " << count << " bytes consumed"); return count; }
void HttpClient::onReply(Http::Client& client) { try { Http::MessageProgress progress = client.endReceive(); if( progress.header() ) { //_impl->verifyHeader( client.reply() ); beginResult( client.reply().body() ); } if( progress.body() ) { // reads until error or XML was consumed parseResult(); // discard remaining data client.reply().discard(); } if( ! progress.finished() ) { client.beginReceive(); return; } } catch(const System::IOError&) // HttpError is also an IOError { // finished signal will call onError() setError(); finishResult(); return; } // send finished signal finishResult(); }
// This call retrieves information about LinkedIn user: basic profile info and email address (as defined by the scope member variable): virtual void getIdentity(const OAuthAccessToken& token) { // Create Http REST client object: Http::Client *client = new Http::Client(this); client->setTimeout(15); client->setMaximumResponseSize(10*1024); // Tell how to handle the response: client->done().connect(boost::bind(&LinkedInProcess::handleMe, this, _1, _2)); // Initialize request headers: std::vector<Http::Message::Header> headers; headers.push_back(Http::Message::Header("Authorization", "Bearer " + token.value())); const char *UserInfoUrl = "https://api.linkedin.com/v1/people/~:(id,num-connections,first-name,last-name,headline,location,email-address,positions,public-profile-url)?format=json"; client->get(UserInfoUrl, headers); #ifndef WT_TARGET_JAVA WApplication::instance()->deferRendering(); #endif }
void request(Settings settings, http::Headers headers, std::string body, http::RequestCallback &&callback) { http_client.request( settings, headers, body, [=](Error error, http::Response &&response) { YAML::Node rr; rr["request"]["headers"] = std::map<std::string, std::string>(headers); rr["request"]["body"] = body; rr["request"]["url"] = settings.at("url"); rr["request"]["http_version"] = settings.at("http_version"); rr["request"]["method"] = settings.at("method"); // XXX we should probably update the OONI data format to remove // this. rr["method"] = settings.at("method"); if (error == 0) { rr["response"]["headers"] = std::map<std::string, std::string>(response.headers); rr["response"]["body"] = response.body; rr["response"]["response_line"] = response.response_line; rr["response"]["code"] = response.status_code; } else { rr["failure"] = "unknown_failure measurement_kit_error"; rr["error_code"] = (int)error; } entry["requests"].push_back(rr); entry["agent"] = "agent"; entry["socksproxy"] = ""; callback(error, std::move(response)); }, &logger); };
size_t HTTPFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) { s64 absoluteEnd = std::min(absolutePos + (s64)bytes, filesize_); if (absolutePos >= filesize_ || bytes == 0) { // Read outside of the file or no read at all, just fail immediately. return 0; } Connect(); char requestHeaders[4096]; // Note that the Range header is *inclusive*. snprintf(requestHeaders, sizeof(requestHeaders), "Range: bytes=%lld-%lld\r\n", absolutePos, absoluteEnd - 1); int err = client_.SendRequest("GET", url_.Resource().c_str(), requestHeaders, nullptr); if (err < 0) { Disconnect(); return 0; } Buffer readbuf; std::vector<std::string> responseHeaders; int code = client_.ReadResponseHeaders(&readbuf, responseHeaders); if (code != 206) { ERROR_LOG(LOADER, "HTTP server did not respond with range, received code=%03d", code); Disconnect(); return 0; } // TODO: Expire cache via ETag, etc. // We don't support multipart/byteranges responses. bool supportedResponse = false; for (std::string header : responseHeaders) { if (startsWithNoCase(header, "Content-Range:")) { // TODO: More correctness. Whitespace can be missing or different. s64 first = -1, last = -1, total = -1; std::string lowerHeader = header; std::transform(lowerHeader.begin(), lowerHeader.end(), lowerHeader.begin(), tolower); if (sscanf(lowerHeader.c_str(), "content-range: bytes %lld-%lld/%lld", &first, &last, &total) >= 2) { if (first == absolutePos && last == absoluteEnd - 1) { supportedResponse = true; } else { ERROR_LOG(LOADER, "Unexpected HTTP range: got %lld-%lld, wanted %lld-%lld.", first, last, absolutePos, absoluteEnd - 1); } } else { ERROR_LOG(LOADER, "Unexpected HTTP range response: %s", header.c_str()); } } } // TODO: Would be nice to read directly. Buffer output; int res = client_.ReadResponseEntity(&readbuf, responseHeaders, &output); if (res != 0) { ERROR_LOG(LOADER, "Unable to read HTTP response entity: %d", res); // Let's take anything we got anyway. Not worse than returning nothing? } // TODO: Keepalive instead. Disconnect(); if (!supportedResponse) { ERROR_LOG(LOADER, "HTTP server did not respond with the range we wanted."); return 0; } size_t readBytes = output.size(); output.Take(readBytes, (char *)data); filepos_ = absolutePos + readBytes; return readBytes; }
void HttpClientImpl::onReplyHeader(http::Client& client) { verifyHeader(client.header()); }