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,
|
void AsyncRestClient::Request(const std::string& method,
|
||||||
const std::string& url,
|
const std::string& url,
|
||||||
const std::string& content,
|
std::string&& content,
|
||||||
HttpResponseHandler response_handler) {
|
HttpResponseHandler response_handler) {
|
||||||
response_handler_ = response_handler;
|
response_handler_ = response_handler;
|
||||||
|
|
||||||
@@ -21,7 +21,8 @@ void AsyncRestClient::Request(const std::string& method,
|
|||||||
request->SetHost(host_, port_);
|
request->SetHost(host_, port_);
|
||||||
|
|
||||||
if (!content.empty()) {
|
if (!content.empty()) {
|
||||||
request->SetContent(content);
|
request->SetContent(std::move(content), true);
|
||||||
|
request->SetContentType(kAppJsonUtf8);
|
||||||
}
|
}
|
||||||
|
|
||||||
request->UpdateStartLine();
|
request->UpdateStartLine();
|
||||||
|
|||||||
+10
-15
@@ -2,6 +2,7 @@
|
|||||||
#define WEBCC_ASYNC_REST_CLIENT_H_
|
#define WEBCC_ASYNC_REST_CLIENT_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility> // for move()
|
||||||
|
|
||||||
#include "webcc/async_http_client.h"
|
#include "webcc/async_http_client.h"
|
||||||
|
|
||||||
@@ -10,8 +11,7 @@ namespace webcc {
|
|||||||
class AsyncRestClient {
|
class AsyncRestClient {
|
||||||
public:
|
public:
|
||||||
AsyncRestClient(boost::asio::io_context& io_context, // NOLINT
|
AsyncRestClient(boost::asio::io_context& io_context, // NOLINT
|
||||||
const std::string& host,
|
const std::string& host, const std::string& port);
|
||||||
const std::string& port);
|
|
||||||
|
|
||||||
void set_timeout_seconds(int timeout_seconds) {
|
void set_timeout_seconds(int timeout_seconds) {
|
||||||
timeout_seconds_ = timeout_seconds;
|
timeout_seconds_ = timeout_seconds;
|
||||||
@@ -22,22 +22,19 @@ class AsyncRestClient {
|
|||||||
Request(kHttpGet, url, "", response_handler);
|
Request(kHttpGet, url, "", response_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Post(const std::string& url,
|
void Post(const std::string& url, std::string&& content,
|
||||||
const std::string& content,
|
|
||||||
HttpResponseHandler response_handler) {
|
HttpResponseHandler response_handler) {
|
||||||
Request(kHttpPost, url, content, response_handler);
|
Request(kHttpPost, url, std::move(content), response_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Put(const std::string& url,
|
void Put(const std::string& url, std::string&& content,
|
||||||
const std::string& content,
|
|
||||||
HttpResponseHandler response_handler) {
|
HttpResponseHandler response_handler) {
|
||||||
Request(kHttpPut, url, content, response_handler);
|
Request(kHttpPut, url, std::move(content), response_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Patch(const std::string& url,
|
void Patch(const std::string& url, std::string&& content,
|
||||||
const std::string& content,
|
|
||||||
HttpResponseHandler response_handler) {
|
HttpResponseHandler response_handler) {
|
||||||
Request(kHttpPatch, url, content, response_handler);
|
Request(kHttpPatch, url, std::move(content), response_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Delete(const std::string& url,
|
void Delete(const std::string& url,
|
||||||
@@ -46,10 +43,8 @@ class AsyncRestClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Request(const std::string& method,
|
void Request(const std::string& method, const std::string& url,
|
||||||
const std::string& url,
|
std::string&& content, HttpResponseHandler response_handler);
|
||||||
const std::string& content,
|
|
||||||
HttpResponseHandler response_handler);
|
|
||||||
|
|
||||||
boost::asio::io_context& io_context_;
|
boost::asio::io_context& io_context_;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ const std::string kContentLength = "Content-Length";
|
|||||||
const std::string kSoapAction = "SOAPAction";
|
const std::string kSoapAction = "SOAPAction";
|
||||||
#endif // WEBCC_ENABLE_SOAP
|
#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
|
#ifdef WEBCC_ENABLE_SOAP
|
||||||
// According to www.w3.org when placing SOAP messages in HTTP bodies, the HTTP
|
// 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;
|
extern const std::string kSoapAction;
|
||||||
#endif // WEBCC_ENABLE_SOAP
|
#endif // WEBCC_ENABLE_SOAP
|
||||||
|
|
||||||
extern const std::string kTextJsonUtf8;
|
extern const std::string kAppJsonUtf8;
|
||||||
|
|
||||||
#ifdef WEBCC_ENABLE_SOAP
|
#ifdef WEBCC_ENABLE_SOAP
|
||||||
extern const std::string kTextXmlUtf8;
|
extern const std::string kTextXmlUtf8;
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ void HttpConnection::Close() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void HttpConnection::SetResponseContent(std::string&& content,
|
void HttpConnection::SetResponseContent(std::string&& content,
|
||||||
const std::string& content_type) {
|
const std::string& type) {
|
||||||
response_.SetContent(std::move(content));
|
response_.SetContent(std::move(content), true);
|
||||||
response_.SetContentType(content_type);
|
response_.SetContentType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpConnection::SendResponse(HttpStatus::Enum status) {
|
void HttpConnection::SendResponse(HttpStatus::Enum status) {
|
||||||
|
|||||||
@@ -35,8 +35,7 @@ class HttpConnection : public std::enable_shared_from_this<HttpConnection> {
|
|||||||
// Close the socket.
|
// Close the socket.
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
void SetResponseContent(std::string&& content,
|
void SetResponseContent(std::string&& content, const std::string& type);
|
||||||
const std::string& content_type);
|
|
||||||
|
|
||||||
// Send response to client with the given status.
|
// Send response to client with the given status.
|
||||||
void SendResponse(HttpStatus::Enum status);
|
void SendResponse(HttpStatus::Enum status);
|
||||||
|
|||||||
@@ -38,19 +38,16 @@ class HttpMessage {
|
|||||||
|
|
||||||
void SetHeader(std::string&& name, std::string&& value);
|
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) {
|
void SetContentType(const std::string& content_type) {
|
||||||
SetHeader(kContentType, content_type);
|
SetHeader(kContentType, content_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetContent(std::string&& content) {
|
void SetContent(std::string&& content, bool set_length) {
|
||||||
content_ = std::move(content);
|
content_ = std::move(content);
|
||||||
SetContentLength(content_.size());
|
if (set_length) {
|
||||||
}
|
SetContentLength(content_.size());
|
||||||
|
}
|
||||||
void SetContent(const std::string& content) {
|
|
||||||
content_ = content;
|
|
||||||
SetContentLength(content_.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set start line according to other informations.
|
// 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());
|
LOG_ERRO("Failed to reserve content memory: %s.", e.what());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
message_->SetHeader(std::move(name), std::move(value));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message_->SetHeader(std::move(name), std::move(value));
|
||||||
|
|
||||||
return true;
|
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() {
|
void HttpParser::Finish() {
|
||||||
// Move content to message.
|
if (!content_.empty()) {
|
||||||
message_->SetContent(std::move(content_));
|
// Move content to message.
|
||||||
|
// "Content-Length" already set in ParseHeader().
|
||||||
|
message_->SetContent(std::move(content_), /*set_length*/false);
|
||||||
|
}
|
||||||
finished_ = true;
|
finished_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,6 @@ class HttpParser {
|
|||||||
|
|
||||||
bool ParseHeader(const std::string& line);
|
bool ParseHeader(const std::string& line);
|
||||||
|
|
||||||
//void ParseContentLength(const std::string& line);
|
|
||||||
|
|
||||||
void Finish();
|
void Finish();
|
||||||
|
|
||||||
void AppendContent(const char* data, std::size_t count);
|
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_);
|
request.SetHost(host_, port_);
|
||||||
|
|
||||||
if (!content.empty()) {
|
if (!content.empty()) {
|
||||||
request.SetContent(std::move(content));
|
request.SetContent(std::move(content), true);
|
||||||
request.SetContentType(kTextJsonUtf8);
|
request.SetContentType(kAppJsonUtf8);
|
||||||
}
|
}
|
||||||
|
|
||||||
request.UpdateStartLine();
|
request.UpdateStartLine();
|
||||||
|
|||||||
@@ -8,8 +8,7 @@
|
|||||||
|
|
||||||
namespace webcc {
|
namespace webcc {
|
||||||
|
|
||||||
bool RestRequestHandler::Bind(RestServicePtr service,
|
bool RestRequestHandler::Bind(RestServicePtr service, const std::string& url,
|
||||||
const std::string& url,
|
|
||||||
bool is_regex) {
|
bool is_regex) {
|
||||||
return service_manager_.AddService(service, url, is_regex);
|
return service_manager_.AddService(service, url, is_regex);
|
||||||
}
|
}
|
||||||
@@ -45,7 +44,9 @@ void RestRequestHandler::HandleConnection(HttpConnectionPtr connection) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
connection->SetResponseContent(std::move(content), kTextJsonUtf8);
|
if (!content.empty()) {
|
||||||
|
connection->SetResponseContent(std::move(content), kAppJsonUtf8);
|
||||||
|
}
|
||||||
connection->SendResponse(HttpStatus::kOK);
|
connection->SendResponse(HttpStatus::kOK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ Error SoapClient::Call(const std::string& operation,
|
|||||||
|
|
||||||
http_request.set_method(kHttpPost);
|
http_request.set_method(kHttpPost);
|
||||||
http_request.set_url(url_);
|
http_request.set_url(url_);
|
||||||
|
http_request.SetContent(std::move(http_content), true);
|
||||||
http_request.SetContentType(kTextXmlUtf8);
|
http_request.SetContentType(kTextXmlUtf8);
|
||||||
http_request.SetContent(std::move(http_content));
|
|
||||||
http_request.SetHost(host_, port_);
|
http_request.SetHost(host_, port_);
|
||||||
http_request.SetHeader(kSoapAction, operation);
|
http_request.SetHeader(kSoapAction, operation);
|
||||||
http_request.UpdateStartLine();
|
http_request.UpdateStartLine();
|
||||||
|
|||||||
Reference in New Issue
Block a user