Throw exception from inside HttpClientSession.Request().
This commit is contained in:
+17
-16
@@ -37,34 +37,35 @@ int main() {
|
||||
// - constructor: HttpRequestArgs{ "GET" }
|
||||
// - move constructor: auto args = ...
|
||||
|
||||
//auto args = HttpRequestArgs{"GET"}.
|
||||
// url("http://httpbin.org/get").
|
||||
// parameters({ "key1", "value1", "key2", "value2" }).
|
||||
// headers({ "Accept", "application/json" }).
|
||||
// buffer_size(1000);
|
||||
auto args = HttpRequestArgs{"GET"}.
|
||||
url("http://httpbin.org/get").
|
||||
parameters({ "key1", "value1", "key2", "value2" }).
|
||||
headers({ "Accept", "application/json" }).
|
||||
buffer_size(1000);
|
||||
|
||||
//r = session.Request(std::move(args));
|
||||
r = session.Request(std::move(args));
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Use pre-defined wrappers.
|
||||
|
||||
//r = session.Get("http://httpbin.org/get",
|
||||
// { "key1", "value1", "key2", "value2" },
|
||||
// { "Accept", "application/json" },
|
||||
// HttpRequestArgs{}.buffer_size(1000));
|
||||
r = session.Get("http://httpbin.org/get",
|
||||
{ "key1", "value1", "key2", "value2" },
|
||||
{ "Accept", "application/json" },
|
||||
HttpRequestArgs{}.buffer_size(1000));
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// HTTPS is auto-detected from the URL schema.
|
||||
|
||||
r = session.Post("https://httpbin.org/post", "{ 'key': 'value' }", true,
|
||||
{ "Accept", "application/json" },
|
||||
try {
|
||||
r = session.Post("httpt://httpbin.org/post", "{ 'key': 'value' }", true,
|
||||
{"Accept", "application/json"},
|
||||
HttpRequestArgs{}.ssl_verify(false).buffer_size(1000));
|
||||
|
||||
if (r) {
|
||||
std::cout << r->content() << std::endl;
|
||||
}
|
||||
std::cout << r->status() << std::endl << r->content() << std::endl;
|
||||
|
||||
GetBoostOrgLicense(session);
|
||||
} catch (const webcc::Exception& e) {
|
||||
std::cout << "Exception: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ namespace webcc {
|
||||
|
||||
const char* DescribeError(Error error) {
|
||||
switch (error) {
|
||||
case kSchemaError:
|
||||
return "Schema error";
|
||||
case kHostResolveError:
|
||||
return "Host resolve error";
|
||||
case kEndpointConnectError:
|
||||
@@ -29,4 +31,14 @@ const char* DescribeError(Error error) {
|
||||
}
|
||||
}
|
||||
|
||||
Exception::Exception(Error error, bool timeout, const std::string& details)
|
||||
: error_(error), timeout_(timeout), msg_(DescribeError(error)) {
|
||||
if (timeout) {
|
||||
msg_ += " (timeout)";
|
||||
}
|
||||
if (!details.empty()) {
|
||||
msg_ += " (" + details + ")";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webcc
|
||||
|
||||
+49
-26
@@ -33,9 +33,8 @@
|
||||
namespace webcc {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Constants
|
||||
|
||||
const char* const CRLF = "\r\n";
|
||||
const char* const kCRLF = "\r\n";
|
||||
|
||||
// Default buffer size for socket reading.
|
||||
const std::size_t kBufferSize = 1024;
|
||||
@@ -54,30 +53,7 @@ const std::size_t kMaxDumpSize = 2048;
|
||||
const char* const kPort80 = "80";
|
||||
const char* const kPort443 = "443";
|
||||
|
||||
// Client side error codes.
|
||||
enum Error {
|
||||
kNoError = 0, // i.e., OK
|
||||
|
||||
kHostResolveError,
|
||||
kEndpointConnectError,
|
||||
kHandshakeError, // HTTPS handshake
|
||||
kSocketReadError,
|
||||
kSocketWriteError,
|
||||
|
||||
// HTTP error.
|
||||
// E.g., failed to parse HTTP response (invalid content length, etc.).
|
||||
kHttpError,
|
||||
|
||||
// Server error.
|
||||
// E.g., HTTP status 500 + SOAP Fault element.
|
||||
kServerError,
|
||||
|
||||
// XML parsing error.
|
||||
kXmlError,
|
||||
};
|
||||
|
||||
// Return a descriptive message for the given error code.
|
||||
const char* DescribeError(Error error);
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// HTTP headers.
|
||||
namespace http {
|
||||
@@ -146,6 +122,53 @@ const char* const kUtf8 = "utf-8";
|
||||
|
||||
} // namespace http
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Client side error codes.
|
||||
enum Error {
|
||||
kNoError = 0, // i.e., OK
|
||||
|
||||
kSchemaError,
|
||||
|
||||
kHostResolveError,
|
||||
kEndpointConnectError,
|
||||
kHandshakeError, // HTTPS handshake
|
||||
kSocketReadError,
|
||||
kSocketWriteError,
|
||||
|
||||
// HTTP error.
|
||||
// E.g., failed to parse HTTP response (invalid content length, etc.).
|
||||
kHttpError,
|
||||
|
||||
// Server error.
|
||||
// E.g., HTTP status 500 + SOAP Fault element.
|
||||
kServerError,
|
||||
|
||||
// XML parsing error.
|
||||
kXmlError,
|
||||
};
|
||||
|
||||
// Return a descriptive message for the given error code.
|
||||
const char* DescribeError(Error error);
|
||||
|
||||
class Exception : public std::exception {
|
||||
public:
|
||||
explicit Exception(Error error = kNoError, bool timeout = false,
|
||||
const std::string& details = "");
|
||||
|
||||
const char* what() const override {
|
||||
return msg_.c_str();
|
||||
}
|
||||
|
||||
private:
|
||||
Error error_;
|
||||
|
||||
// If the error was caused by timeout or not.
|
||||
bool timeout_;
|
||||
|
||||
std::string msg_;
|
||||
};
|
||||
|
||||
} // namespace webcc
|
||||
|
||||
#endif // WEBCC_GLOBALS_H_
|
||||
|
||||
@@ -45,8 +45,6 @@ HttpResponsePtr HttpClientSession::Request(HttpRequestArgs&& args) {
|
||||
|
||||
request.Prepare();
|
||||
|
||||
// TODO:
|
||||
|
||||
std::shared_ptr<HttpClientBase> impl;
|
||||
|
||||
if (request.url().scheme() == "http") {
|
||||
@@ -54,17 +52,15 @@ HttpResponsePtr HttpClientSession::Request(HttpRequestArgs&& args) {
|
||||
} else if (request.url().scheme() == "https") {
|
||||
impl.reset(new HttpSslClient{args.ssl_verify_});
|
||||
} else {
|
||||
return HttpResponsePtr{};
|
||||
throw Exception(kSchemaError, false,
|
||||
"unknown schema: " + request.url().scheme());
|
||||
}
|
||||
|
||||
if (impl) {
|
||||
if (!impl->Request(request, args.buffer_size_)) {
|
||||
return HttpResponsePtr{};
|
||||
}
|
||||
return impl->response();
|
||||
throw Exception(impl->error(), impl->timed_out());
|
||||
}
|
||||
|
||||
return HttpResponsePtr{};
|
||||
return impl->response();
|
||||
}
|
||||
|
||||
HttpResponsePtr HttpClientSession::Get(const std::string& url,
|
||||
|
||||
@@ -34,8 +34,7 @@ public:
|
||||
std::vector<std::string>&& headers = {},
|
||||
HttpRequestArgs&& args = HttpRequestArgs());
|
||||
|
||||
HttpResponsePtr Post(const std::string& url,
|
||||
std::string&& data, bool json,
|
||||
HttpResponsePtr Post(const std::string& url, std::string&& data, bool json,
|
||||
std::vector<std::string>&& headers = {},
|
||||
HttpRequestArgs&& args = HttpRequestArgs());
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ void HttpMessage::Dump(std::ostream& os, std::size_t indent,
|
||||
} else {
|
||||
// Split by EOL to achieve more readability.
|
||||
std::vector<std::string> splitted;
|
||||
boost::split(splitted, content_, boost::is_any_of(CRLF));
|
||||
boost::split(splitted, content_, boost::is_any_of(kCRLF));
|
||||
|
||||
std::size_t size = 0;
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ bool HttpParser::ParseHeaders() {
|
||||
|
||||
if (!start_line_parsed_) {
|
||||
start_line_parsed_ = true;
|
||||
message_->set_start_line(line + CRLF);
|
||||
message_->set_start_line(line + kCRLF);
|
||||
if (!ParseStartLine(line)) {
|
||||
return false;
|
||||
}
|
||||
@@ -98,7 +98,7 @@ bool HttpParser::ParseHeaders() {
|
||||
|
||||
bool HttpParser::NextPendingLine(std::size_t off, std::string* line,
|
||||
bool remove) {
|
||||
std::size_t pos = pending_data_.find(CRLF, off);
|
||||
std::size_t pos = pending_data_.find(kCRLF, off);
|
||||
|
||||
if (pos == std::string::npos) {
|
||||
return false;
|
||||
|
||||
@@ -20,7 +20,7 @@ bool HttpRequest::Prepare() {
|
||||
start_line_ += " ";
|
||||
start_line_ += target;
|
||||
start_line_ += " HTTP/1.1";
|
||||
start_line_ += CRLF;
|
||||
start_line_ += kCRLF;
|
||||
|
||||
if (url_.port().empty()) {
|
||||
SetHeader(http::headers::kHost, url_.host());
|
||||
|
||||
Reference in New Issue
Block a user