diff --git a/webcc/async_rest_client.cc b/webcc/async_rest_client.cc index 341e9c6..31b4525 100644 --- a/webcc/async_rest_client.cc +++ b/webcc/async_rest_client.cc @@ -10,7 +10,7 @@ AsyncRestClient::AsyncRestClient(boost::asio::io_context& io_context, void AsyncRestClient::Request(const std::string& method, const std::string& url, - const std::string& content, + std::string&& content, HttpResponseHandler response_handler) { response_handler_ = response_handler; @@ -21,7 +21,8 @@ void AsyncRestClient::Request(const std::string& method, request->SetHost(host_, port_); if (!content.empty()) { - request->SetContent(content); + request->SetContent(std::move(content), true); + request->SetContentType(kAppJsonUtf8); } request->UpdateStartLine(); diff --git a/webcc/async_rest_client.h b/webcc/async_rest_client.h index 0ef332b..64e09d3 100644 --- a/webcc/async_rest_client.h +++ b/webcc/async_rest_client.h @@ -2,6 +2,7 @@ #define WEBCC_ASYNC_REST_CLIENT_H_ #include +#include // for move() #include "webcc/async_http_client.h" @@ -10,8 +11,7 @@ namespace webcc { class AsyncRestClient { public: AsyncRestClient(boost::asio::io_context& io_context, // NOLINT - const std::string& host, - const std::string& port); + const std::string& host, const std::string& port); void set_timeout_seconds(int timeout_seconds) { timeout_seconds_ = timeout_seconds; @@ -22,22 +22,19 @@ class AsyncRestClient { Request(kHttpGet, url, "", response_handler); } - void Post(const std::string& url, - const std::string& content, + void Post(const std::string& url, std::string&& content, HttpResponseHandler response_handler) { - Request(kHttpPost, url, content, response_handler); + Request(kHttpPost, url, std::move(content), response_handler); } - void Put(const std::string& url, - const std::string& content, + void Put(const std::string& url, std::string&& content, HttpResponseHandler response_handler) { - Request(kHttpPut, url, content, response_handler); + Request(kHttpPut, url, std::move(content), response_handler); } - void Patch(const std::string& url, - const std::string& content, + void Patch(const std::string& url, std::string&& content, HttpResponseHandler response_handler) { - Request(kHttpPatch, url, content, response_handler); + Request(kHttpPatch, url, std::move(content), response_handler); } void Delete(const std::string& url, @@ -46,10 +43,8 @@ class AsyncRestClient { } private: - void Request(const std::string& method, - const std::string& url, - const std::string& content, - HttpResponseHandler response_handler); + void Request(const std::string& method, const std::string& url, + std::string&& content, HttpResponseHandler response_handler); boost::asio::io_context& io_context_; diff --git a/webcc/globals.cc b/webcc/globals.cc index 0bd937e..60d397f 100644 --- a/webcc/globals.cc +++ b/webcc/globals.cc @@ -16,7 +16,7 @@ const std::string kContentLength = "Content-Length"; const std::string kSoapAction = "SOAPAction"; #endif // WEBCC_ENABLE_SOAP -const std::string kTextJsonUtf8 = "text/json; charset=utf-8"; +const std::string kAppJsonUtf8 = "application/json; charset=utf-8"; #ifdef WEBCC_ENABLE_SOAP // According to www.w3.org when placing SOAP messages in HTTP bodies, the HTTP diff --git a/webcc/globals.h b/webcc/globals.h index 970c3cb..6e36995 100644 --- a/webcc/globals.h +++ b/webcc/globals.h @@ -38,7 +38,7 @@ extern const std::string kContentLength; extern const std::string kSoapAction; #endif // WEBCC_ENABLE_SOAP -extern const std::string kTextJsonUtf8; +extern const std::string kAppJsonUtf8; #ifdef WEBCC_ENABLE_SOAP extern const std::string kTextXmlUtf8; diff --git a/webcc/http_connection.cc b/webcc/http_connection.cc index f563b85..8dea87c 100644 --- a/webcc/http_connection.cc +++ b/webcc/http_connection.cc @@ -29,9 +29,9 @@ void HttpConnection::Close() { } void HttpConnection::SetResponseContent(std::string&& content, - const std::string& content_type) { - response_.SetContent(std::move(content)); - response_.SetContentType(content_type); + const std::string& type) { + response_.SetContent(std::move(content), true); + response_.SetContentType(type); } void HttpConnection::SendResponse(HttpStatus::Enum status) { diff --git a/webcc/http_connection.h b/webcc/http_connection.h index 644cbcd..bc98810 100644 --- a/webcc/http_connection.h +++ b/webcc/http_connection.h @@ -35,8 +35,7 @@ class HttpConnection : public std::enable_shared_from_this { // Close the socket. void Close(); - void SetResponseContent(std::string&& content, - const std::string& content_type); + void SetResponseContent(std::string&& content, const std::string& type); // Send response to client with the given status. void SendResponse(HttpStatus::Enum status); diff --git a/webcc/http_message.h b/webcc/http_message.h index 3afcf73..08a74f3 100644 --- a/webcc/http_message.h +++ b/webcc/http_message.h @@ -38,19 +38,16 @@ class HttpMessage { void SetHeader(std::string&& name, std::string&& value); - // E.g., "text/xml; charset=utf-8" + // E.g., "application/json; charset=utf-8" void SetContentType(const std::string& content_type) { SetHeader(kContentType, content_type); } - void SetContent(std::string&& content) { + void SetContent(std::string&& content, bool set_length) { content_ = std::move(content); - SetContentLength(content_.size()); - } - - void SetContent(const std::string& content) { - content_ = content; - SetContentLength(content_.size()); + if (set_length) { + SetContentLength(content_.size()); + } } // Set start line according to other informations. diff --git a/webcc/http_parser.cc b/webcc/http_parser.cc index 1124740..1e26362 100644 --- a/webcc/http_parser.cc +++ b/webcc/http_parser.cc @@ -123,51 +123,19 @@ bool HttpParser::ParseHeader(const std::string& line) { LOG_ERRO("Failed to reserve content memory: %s.", e.what()); return false; } - } else { - message_->SetHeader(std::move(name), std::move(value)); } + message_->SetHeader(std::move(name), std::move(value)); + return true; } -// -//void HttpParser::ParseContentLength(const std::string& line) { -// std::size_t pos = line.find(':'); -// if (pos == std::string::npos) { -// return; -// } -// -// std::string name = line.substr(0, pos); -// -// if (boost::iequals(name, kContentLength)) { -// content_length_parsed_ = true; -// -// ++pos; // Skip ':'. -// while (line[pos] == ' ') { // Skip spaces. -// ++pos; -// } -// -// std::string value = line.substr(pos); -// -// try { -// content_length_ = static_cast(std::stoul(value)); -// } catch (const std::exception&) { -// LOG_ERRO("Invalid content length: %s.", value.c_str()); -// } -// -// LOG_INFO("Content length: %u.", content_length_); -// -// try { -// // Reserve memory to avoid frequent reallocation when append. -// content_.reserve(content_length_); -// } catch (const std::exception& e) { -// LOG_ERRO("Failed to reserve content memory: %s.", e.what()); -// } -// } -//} void HttpParser::Finish() { - // Move content to message. - message_->SetContent(std::move(content_)); + if (!content_.empty()) { + // Move content to message. + // "Content-Length" already set in ParseHeader(). + message_->SetContent(std::move(content_), /*set_length*/false); + } finished_ = true; } diff --git a/webcc/http_parser.h b/webcc/http_parser.h index ad75875..4e38333 100644 --- a/webcc/http_parser.h +++ b/webcc/http_parser.h @@ -30,8 +30,6 @@ class HttpParser { bool ParseHeader(const std::string& line); - //void ParseContentLength(const std::string& line); - void Finish(); void AppendContent(const char* data, std::size_t count); diff --git a/webcc/rest_client.cc b/webcc/rest_client.cc index 545f0bc..511fe95 100644 --- a/webcc/rest_client.cc +++ b/webcc/rest_client.cc @@ -27,8 +27,8 @@ bool RestClient::Request(const std::string& method, const std::string& url, request.SetHost(host_, port_); if (!content.empty()) { - request.SetContent(std::move(content)); - request.SetContentType(kTextJsonUtf8); + request.SetContent(std::move(content), true); + request.SetContentType(kAppJsonUtf8); } request.UpdateStartLine(); diff --git a/webcc/rest_request_handler.cc b/webcc/rest_request_handler.cc index d464b09..f0cafee 100644 --- a/webcc/rest_request_handler.cc +++ b/webcc/rest_request_handler.cc @@ -8,8 +8,7 @@ namespace webcc { -bool RestRequestHandler::Bind(RestServicePtr service, - const std::string& url, +bool RestRequestHandler::Bind(RestServicePtr service, const std::string& url, bool is_regex) { return service_manager_.AddService(service, url, is_regex); } @@ -45,7 +44,9 @@ void RestRequestHandler::HandleConnection(HttpConnectionPtr connection) { return; } - connection->SetResponseContent(std::move(content), kTextJsonUtf8); + if (!content.empty()) { + connection->SetResponseContent(std::move(content), kAppJsonUtf8); + } connection->SendResponse(HttpStatus::kOK); } diff --git a/webcc/soap_client.cc b/webcc/soap_client.cc index 33b8e12..4879302 100644 --- a/webcc/soap_client.cc +++ b/webcc/soap_client.cc @@ -40,8 +40,8 @@ Error SoapClient::Call(const std::string& operation, http_request.set_method(kHttpPost); http_request.set_url(url_); + http_request.SetContent(std::move(http_content), true); http_request.SetContentType(kTextXmlUtf8); - http_request.SetContent(std::move(http_content)); http_request.SetHost(host_, port_); http_request.SetHeader(kSoapAction, operation); http_request.UpdateStartLine();