accept-encoding default to identity even if gzip is enabled.
This commit is contained in:
+38
-52
@@ -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");
|
||||||
|
|||||||
+42
-32
@@ -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());
|
headers_.Set(headers::kAccept, "*/*");
|
||||||
|
|
||||||
// Content-Encoding Tokens:
|
// Accept-Encoding is always default to "identity", even if GZIP is enabled.
|
||||||
// (https://en.wikipedia.org/wiki/HTTP_compression)
|
// Please overwrite with AcceptGzip().
|
||||||
//
|
headers_.Set(headers::kAcceptEncoding, "identity");
|
||||||
// * 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, "*/*");
|
headers_.Set(headers::kConnection, "Keep-Alive");
|
||||||
|
|
||||||
#if WEBCC_ENABLE_GZIP
|
|
||||||
headers_.Set(kAcceptEncoding, "gzip, deflate");
|
|
||||||
#else
|
|
||||||
headers_.Set(kAcceptEncoding, "identity");
|
|
||||||
#endif // WEBCC_ENABLE_GZIP
|
|
||||||
|
|
||||||
headers_.Set(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) {
|
||||||
|
|||||||
+14
-5
@@ -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
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user