accept-encoding default to identity even if gzip is enabled.

master
Chunting Gu 5 years ago
parent a827f4cfe2
commit 7a09d47e8f

@ -44,31 +44,9 @@ TEST(ClientTest, Head) {
EXPECT_EQ(webcc::Status::kOK, r->status()); EXPECT_EQ(webcc::Status::kOK, r->status());
EXPECT_EQ("OK", r->reason()); EXPECT_EQ("OK", r->reason());
EXPECT_EQ("", r->data());
} catch (const webcc::Error& error) {
std::cerr << error << std::endl;
}
}
// Force Accept-Encoding to be "identity" so that HttpBin.org will include
// a Content-Length header in the response.
// This tests that the response with Content-Length while no body could be
// correctly parsed.
TEST(ClientTest, Head_AcceptEncodingIdentity) {
webcc::ClientSession session;
try {
auto r = session.Send(webcc::RequestBuilder{}.
Head("http://httpbin.org/get").
Header("Accept-Encoding", "identity")
());
EXPECT_EQ(webcc::Status::kOK, r->status());
EXPECT_EQ("OK", r->reason());
EXPECT_TRUE(r->HasHeader(webcc::headers::kContentLength)); EXPECT_TRUE(r->HasHeader(webcc::headers::kContentLength));
// The response of HTTP HEAD method has no body.
EXPECT_EQ("", r->data()); EXPECT_EQ("", r->data());
} catch (const webcc::Error& error) { } catch (const webcc::Error& error) {
@ -78,30 +56,6 @@ TEST(ClientTest, Head_AcceptEncodingIdentity) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
static void AssertGet(webcc::ResponsePtr r) {
EXPECT_EQ(webcc::Status::kOK, r->status());
EXPECT_EQ("OK", r->reason());
Json::Value json = StringToJson(r->data());
Json::Value args = json["args"];
EXPECT_EQ(2, args.size());
EXPECT_EQ("value1", args["key1"].asString());
EXPECT_EQ("value2", args["key2"].asString());
Json::Value headers = json["headers"];
EXPECT_EQ("application/json", headers["Accept"].asString());
EXPECT_EQ("httpbin.org", headers["Host"].asString());
#if WEBCC_ENABLE_GZIP
EXPECT_EQ("gzip, deflate", headers["Accept-Encoding"].asString());
#else
EXPECT_EQ("identity", headers["Accept-Encoding"].asString());
#endif // WEBCC_ENABLE_GZIP
}
TEST(ClientTest, Get) { TEST(ClientTest, Get) {
webcc::ClientSession session; webcc::ClientSession session;
@ -112,7 +66,22 @@ TEST(ClientTest, Get) {
Header("Accept", "application/json") Header("Accept", "application/json")
()); ());
AssertGet(r); EXPECT_EQ(webcc::Status::kOK, r->status());
EXPECT_EQ("OK", r->reason());
Json::Value json = StringToJson(r->data());
Json::Value args = json["args"];
EXPECT_EQ(2, args.size());
EXPECT_EQ("value1", args["key1"].asString());
EXPECT_EQ("value2", args["key2"].asString());
Json::Value headers = json["headers"];
EXPECT_EQ("application/json", headers["Accept"].asString());
EXPECT_EQ("identity", headers["Accept-Encoding"].asString());
EXPECT_EQ("httpbin.org", headers["Host"].asString());
} catch (const webcc::Error& error) { } catch (const webcc::Error& error) {
std::cerr << error << std::endl; std::cerr << error << std::endl;
@ -152,10 +121,25 @@ TEST(ClientTest, Get_SSL) {
auto r = session.Send(webcc::RequestBuilder{}. auto r = session.Send(webcc::RequestBuilder{}.
Get("https://httpbin.org/get"). Get("https://httpbin.org/get").
Query("key1", "value1").Query("key2", "value2"). Query("key1", "value1").Query("key2", "value2").
Header("Accept", "application/json") Accept("application/json")
()); ());
AssertGet(r); EXPECT_EQ(webcc::Status::kOK, r->status());
EXPECT_EQ("OK", r->reason());
Json::Value json = StringToJson(r->data());
Json::Value args = json["args"];
EXPECT_EQ(2, args.size());
EXPECT_EQ("value1", args["key1"].asString());
EXPECT_EQ("value2", args["key2"].asString());
Json::Value headers = json["headers"];
EXPECT_EQ("application/json", headers["Accept"].asString());
EXPECT_EQ("identity", headers["Accept-Encoding"].asString());
EXPECT_EQ("httpbin.org", headers["Host"].asString());
} catch (const webcc::Error& error) { } catch (const webcc::Error& error) {
std::cerr << error << std::endl; std::cerr << error << std::endl;
@ -248,9 +232,11 @@ TEST(ClientTest, Get_Jpeg_Stream_NoMove) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#if WEBCC_ENABLE_GZIP #if WEBCC_ENABLE_GZIP
// Test Gzip compressed response. // Test Gzip compressed response.
TEST(ClientTest, Get_Gzip) { TEST(ClientTest, Get_Gzip) {
webcc::ClientSession session; webcc::ClientSession session;
session.AcceptGzip();
try { try {
auto r = session.Send(webcc::RequestBuilder{}. auto r = session.Send(webcc::RequestBuilder{}.
@ -265,12 +251,11 @@ TEST(ClientTest, Get_Gzip) {
std::cerr << error << std::endl; std::cerr << error << std::endl;
} }
} }
#endif // WEBCC_ENABLE_GZIP
#if WEBCC_ENABLE_GZIP
// Test Deflate compressed response. // Test Deflate compressed response.
TEST(ClientTest, Get_Deflate) { TEST(ClientTest, Get_Deflate) {
webcc::ClientSession session; webcc::ClientSession session;
session.AcceptGzip();
try { try {
auto r = session.Send(webcc::RequestBuilder{}. auto r = session.Send(webcc::RequestBuilder{}.
@ -285,6 +270,7 @@ TEST(ClientTest, Get_Deflate) {
std::cerr << error << std::endl; std::cerr << error << std::endl;
} }
} }
#endif // WEBCC_ENABLE_GZIP #endif // WEBCC_ENABLE_GZIP
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

@ -128,6 +128,10 @@ int main() {
webcc::ClientSession session; webcc::ClientSession session;
#if WEBCC_ENABLE_GZIP
session.AcceptGzip();
#endif
ListEvents(session); ListEvents(session);
//ListUserFollowers(session, "sprinfall"); //ListUserFollowers(session, "sprinfall");

@ -19,6 +19,40 @@ void ClientSession::Accept(const std::string& content_types) {
} }
} }
#if WEBCC_ENABLE_GZIP
// Content-Encoding Tokens:
// (https://en.wikipedia.org/wiki/HTTP_compression)
//
// * compress ¨C UNIX "compress" program method (historic; deprecated in most
// applications and replaced by gzip or deflate);
// * deflate ¨C compression based on the deflate algorithm, a combination of
// the LZ77 algorithm and Huffman coding, wrapped inside the
// zlib data format;
// * gzip ¨C GNU zip format. Uses the deflate algorithm for compression,
// but the data format and the checksum algorithm differ from
// the "deflate" content-encoding. This method is the most
// broadly supported as of March 2011.
// * identity ¨C No transformation is used. This is the default value for
// content coding.
//
// A note about "deflate":
// "gzip" is the gzip format, and "deflate" is the zlib format. They should
// probably have called the second one "zlib" instead to avoid confusion with
// the raw deflate compressed data format.
// Simply put, "deflate" is not recommended for HTTP 1.1 encoding.
// (https://www.zlib.net/zlib_faq.html#faq39)
void ClientSession::AcceptGzip(bool gzip) {
if (gzip) {
headers_.Set(headers::kAcceptEncoding, "gzip, deflate");
} else {
headers_.Set(headers::kAcceptEncoding, "identity");
}
}
#endif // WEBCC_ENABLE_GZIP
void ClientSession::Auth(const std::string& type, void ClientSession::Auth(const std::string& type,
const std::string& credentials) { const std::string& credentials) {
headers_.Set(headers::kAuthorization, type + " " + credentials); headers_.Set(headers::kAuthorization, type + " " + credentials);
@ -54,41 +88,15 @@ ResponsePtr ClientSession::Send(RequestPtr request, bool stream) {
} }
void ClientSession::InitHeaders() { void ClientSession::InitHeaders() {
using namespace headers; headers_.Set(headers::kUserAgent, utility::UserAgent());
headers_.Set(kUserAgent, utility::UserAgent());
// Content-Encoding Tokens:
// (https://en.wikipedia.org/wiki/HTTP_compression)
//
// * compress ¨C UNIX "compress" program method (historic; deprecated in most
// applications and replaced by gzip or deflate);
// * deflate ¨C compression based on the deflate algorithm, a combination of
// the LZ77 algorithm and Huffman coding, wrapped inside the
// zlib data format;
// * gzip ¨C GNU zip format. Uses the deflate algorithm for compression,
// but the data format and the checksum algorithm differ from
// the "deflate" content-encoding. This method is the most
// broadly supported as of March 2011.
// * identity ¨C No transformation is used. This is the default value for
// content coding.
//
// A note about "deflate":
// "gzip" is the gzip format, and "deflate" is the zlib format. They should
// probably have called the second one "zlib" instead to avoid confusion with
// the raw deflate compressed data format.
// Simply put, "deflate" is not recommended for HTTP 1.1 encoding.
// (https://www.zlib.net/zlib_faq.html#faq39)
headers_.Set(kAccept, "*/*");
#if WEBCC_ENABLE_GZIP headers_.Set(headers::kAccept, "*/*");
headers_.Set(kAcceptEncoding, "gzip, deflate");
#else
headers_.Set(kAcceptEncoding, "identity");
#endif // WEBCC_ENABLE_GZIP
headers_.Set(kConnection, "Keep-Alive"); // Accept-Encoding is always default to "identity", even if GZIP is enabled.
// Please overwrite with AcceptGzip().
headers_.Set(headers::kAcceptEncoding, "identity");
headers_.Set(headers::kConnection, "Keep-Alive");
} }
ResponsePtr ClientSession::DoSend(RequestPtr request, bool stream) { ResponsePtr ClientSession::DoSend(RequestPtr request, bool stream) {
@ -141,9 +149,11 @@ ResponsePtr ClientSession::DoSend(RequestPtr request, bool stream) {
} }
auto response = client->response(); auto response = client->response();
// The client object might be cached in the pool. // The client object might be cached in the pool.
// Reset to make sure it won't keep a reference to the response object. // Reset to make sure it won't keep a reference to the response object.
client->Reset(); client->Reset();
return response; return response;
} }

@ -51,6 +51,13 @@ public:
// Set content types to accept. // Set content types to accept.
void Accept(const std::string& content_types); void Accept(const std::string& content_types);
#if WEBCC_ENABLE_GZIP
// Accept Gzip compressed response data or not.
void AcceptGzip(bool gzip = true);
#endif // WEBCC_ENABLE_GZIP
// Set authorization. // Set authorization.
void Auth(const std::string& type, const std::string& credentials); void Auth(const std::string& type, const std::string& credentials);

@ -54,6 +54,19 @@ RequestPtr RequestBuilder::operator()() {
return request; return request;
} }
#if WEBCC_ENABLE_GZIP
// Accept Gzip compressed response data or not.
RequestBuilder& RequestBuilder::AcceptGzip(bool gzip) {
if (gzip) {
return Header(headers::kAcceptEncoding, "gzip, deflate");
} else {
return Header(headers::kAcceptEncoding, "identity");
}
}
#endif // WEBCC_ENABLE_GZIP
RequestBuilder& RequestBuilder::File(const bfs::path& path, RequestBuilder& RequestBuilder::File(const bfs::path& path,
bool infer_media_type, bool infer_media_type,
std::size_t chunk_size) { std::size_t chunk_size) {

@ -124,6 +124,13 @@ public:
return Header(headers::kAccept, content_types); return Header(headers::kAccept, content_types);
} }
#if WEBCC_ENABLE_GZIP
// Accept Gzip compressed response data or not.
RequestBuilder& AcceptGzip(bool gzip = true);
#endif // WEBCC_ENABLE_GZIP
RequestBuilder& Body(const std::string& data) { RequestBuilder& Body(const std::string& data) {
body_.reset(new StringBody{ data, false }); body_.reset(new StringBody{ data, false });
return *this; return *this;
@ -173,10 +180,17 @@ public:
RequestBuilder& Date(); RequestBuilder& Date();
#if WEBCC_ENABLE_GZIP #if WEBCC_ENABLE_GZIP
// Compress the body data (only for string body).
// NOTE:
// Most servers don't support compressed requests.
// Even the requests module from Python doesn't have a built-in support.
// See: https://github.com/kennethreitz/requests/issues/1753
RequestBuilder& Gzip(bool gzip = true) { RequestBuilder& Gzip(bool gzip = true) {
gzip_ = gzip; gzip_ = gzip;
return *this; return *this;
} }
#endif // WEBCC_ENABLE_GZIP #endif // WEBCC_ENABLE_GZIP
private: private:
@ -207,11 +221,6 @@ private:
bool keep_alive_ = true; bool keep_alive_ = true;
#if WEBCC_ENABLE_GZIP #if WEBCC_ENABLE_GZIP
// Compress the body data (only for string body).
// NOTE:
// Most servers don't support compressed requests.
// Even the requests module from Python doesn't have a built-in support.
// See: https://github.com/kennethreitz/requests/issues/1753
bool gzip_ = false; bool gzip_ = false;
#endif // WEBCC_ENABLE_GZIP #endif // WEBCC_ENABLE_GZIP
}; };

Loading…
Cancel
Save