Refine the handling of content and content length.
This commit is contained in:
@@ -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();
|
||||
|
||||
+10
-15
@@ -2,6 +2,7 @@
|
||||
#define WEBCC_ASYNC_REST_CLIENT_H_
|
||||
|
||||
#include <string>
|
||||
#include <utility> // 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_;
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -35,8 +35,7 @@ class HttpConnection : public std::enable_shared_from_this<HttpConnection> {
|
||||
// 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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
+7
-39
@@ -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::size_t>(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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user