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) {
webcc::ClientSession session;
std::string url = "http://httpbin.org/get";
try {
auto r = session.Get("http://httpbin.org/image/jpeg");

Binary file not shown.

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

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

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

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

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

Loading…
Cancel
Save