Move data decompression to StringBody.

master
Chunting Gu 6 years ago
parent effe302faa
commit 3077f21549

@ -284,7 +284,6 @@ TEST(ClientTest, KeepAlive) {
TEST(ClientTest, GetImageJpeg) { TEST(ClientTest, GetImageJpeg) {
webcc::ClientSession session; webcc::ClientSession session;
std::string url = "http://httpbin.org/get";
try { try {
auto r = session.Get("http://httpbin.org/image/jpeg"); auto r = session.Get("http://httpbin.org/image/jpeg");

Binary file not shown.

@ -17,7 +17,12 @@ namespace webcc {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#if WEBCC_ENABLE_GZIP #if WEBCC_ENABLE_GZIP
bool StringBody::Compress() { bool StringBody::Compress() {
if (compressed_) {
return true; // Already compressed.
}
if (data_.size() <= kGzipThreshold) { if (data_.size() <= kGzipThreshold) {
return false; return false;
} }
@ -25,12 +30,30 @@ bool StringBody::Compress() {
std::string compressed; std::string compressed;
if (gzip::Compress(data_, &compressed)) { if (gzip::Compress(data_, &compressed)) {
data_ = std::move(compressed); data_ = std::move(compressed);
compressed_ = true;
return true; return true;
} }
LOG_WARN("Failed to compress the body data!"); LOG_WARN("Failed to compress the body data!");
return false; return false;
} }
bool StringBody::Decompress() {
if (!compressed_) {
return true; // Already decompressed.
}
std::string decompressed;
if (gzip::Decompress(data_, &decompressed)) {
data_ = std::move(decompressed);
compressed_ = false;
return true;
}
LOG_WARN("Failed to decompress the body data!");
return false;
}
#endif // WEBCC_ENABLE_GZIP #endif // WEBCC_ENABLE_GZIP
void StringBody::InitPayload() { void StringBody::InitPayload() {

@ -28,12 +28,19 @@ public:
} }
#if WEBCC_ENABLE_GZIP #if WEBCC_ENABLE_GZIP
// Compress with Gzip.
// If the body size <= the threshold (1400 bytes), no compression will be done // Compress the data with Gzip.
// and just return false. // If data size <= threshold (1400 bytes), no compression will be taken
// and false will be simply returned.
virtual bool Compress() { virtual bool Compress() {
return false; return false;
} }
// Decompress the data.
virtual bool Decompress() {
return false;
}
#endif // WEBCC_ENABLE_GZIP #endif // WEBCC_ENABLE_GZIP
// Initialize the payload for iteration. // Initialize the payload for iteration.
@ -61,10 +68,12 @@ using BodyPtr = std::shared_ptr<Body>;
class StringBody : public Body { class StringBody : public Body {
public: public:
explicit StringBody(const std::string& data) : data_(data) { explicit StringBody(const std::string& data, bool compressed)
: data_(data), compressed_(compressed) {
} }
explicit StringBody(std::string&& data) : data_(std::move(data)) { explicit StringBody(std::string&& data, bool compressed)
: data_(std::move(data)), compressed_(compressed) {
} }
std::size_t GetSize() const override { std::size_t GetSize() const override {
@ -76,8 +85,12 @@ public:
} }
#if WEBCC_ENABLE_GZIP #if WEBCC_ENABLE_GZIP
bool Compress() override; bool Compress() override;
#endif
bool Decompress() override;
#endif // WEBCC_ENABLE_GZIP
void InitPayload() override; void InitPayload() override;
@ -88,6 +101,9 @@ public:
private: private:
std::string data_; std::string data_;
// Is the data compressed?
bool compressed_;
// Index for (not really) iterating the payload. // Index for (not really) iterating the payload.
std::size_t index_ = 0; std::size_t index_ = 0;
}; };

@ -305,37 +305,21 @@ bool Parser::Finish() {
// Could be kInvalidLength when chunked. // Could be kInvalidLength when chunked.
message_->set_content_length(content_length_); message_->set_content_length(content_length_);
if (!IsContentCompressed()) { bool compressed = IsContentCompressed();
auto body = std::make_shared<StringBody>(std::move(content_)); auto body = std::make_shared<StringBody>(std::move(content_), compressed);
message_->SetBody(body, false);
return true;
}
#if WEBCC_ENABLE_GZIP #if WEBCC_ENABLE_GZIP
LOG_INFO("Decompress the HTTP content..."); LOG_INFO("Decompress the HTTP content...");
if (!body->Decompress()) {
std::string decompressed;
if (!gzip::Decompress(content_, &decompressed)) {
LOG_ERRO("Cannot decompress the HTTP content!"); LOG_ERRO("Cannot decompress the HTTP content!");
return false; return false;
} }
auto body = std::make_shared<StringBody>(std::move(decompressed));
message_->SetBody(body, false);
return true;
#else #else
LOG_WARN("Compressed HTTP content remains untouched."); LOG_WARN("Compressed HTTP content remains untouched.");
#endif // WEBCC_ENABLE_GZIP
auto body = std::make_shared<StringBody>(std::move(content_));
message_->SetBody(body, false); message_->SetBody(body, false);
return true; return true;
#endif // WEBCC_ENABLE_GZIP
} }
void Parser::AppendContent(const char* data, std::size_t count) { void Parser::AppendContent(const char* data, std::size_t count) {

@ -86,12 +86,12 @@ public:
} }
RequestBuilder& Body(const std::string& data) { RequestBuilder& Body(const std::string& data) {
body_.reset(new StringBody{ data }); body_.reset(new StringBody{ data, false });
return *this; return *this;
} }
RequestBuilder& Body(std::string&& data) { RequestBuilder& Body(std::string&& data) {
body_.reset(new StringBody{ std::move(data) }); body_.reset(new StringBody{ std::move(data), false });
return *this; return *this;
} }

@ -87,12 +87,12 @@ public:
} }
ResponseBuilder& Body(const std::string& data) { ResponseBuilder& Body(const std::string& data) {
body_.reset(new StringBody{ data }); body_.reset(new StringBody{ data, false });
return *this; return *this;
} }
ResponseBuilder& Body(std::string&& data) { ResponseBuilder& Body(std::string&& data) {
body_.reset(new StringBody{ std::move(data) }); body_.reset(new StringBody{ std::move(data), false });
return *this; return *this;
} }

Loading…
Cancel
Save