mirror of
https://github.com/yhirose/cpp-httplib
synced 2026-06-08 18:30:49 +00:00
Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7231f6fe00 | |||
| cb11d9412e | |||
| 057a8a0fb9 | |||
| 2d30c59340 | |||
| 34651ef89b | |||
| 4f237af813 | |||
| eaffe68c1a | |||
| e0d327558d | |||
| dd20e4d418 | |||
| 7267b3f3e2 | |||
| 4c18ac2b18 | |||
| b5a1d52f36 | |||
| eaafa5d55c | |||
| 3d1ae3a3af | |||
| e4d3766ef2 | |||
| 6f663028e9 | |||
| 31cdadc4b1 | |||
| 849add5887 | |||
| fccb84f5e8 | |||
| 3541fe8330 | |||
| 63d0056826 | |||
| d1080087d3 | |||
| cb43980a70 | |||
| 2fdc41c323 | |||
| 74e9a0d17e | |||
| 30d73051ee | |||
| 6f5a3c97ec | |||
| bb537d93fe | |||
| bde3fd9f78 | |||
| 2aa35d5f53 | |||
| 0b2c506ca4 | |||
| 8098f88c90 | |||
| 49f21f74cb | |||
| cdc45c4601 | |||
| c1ca091b44 | |||
| 7f7d101440 |
@@ -5,6 +5,7 @@ example/client
|
||||
example/hello
|
||||
example/simplesvr
|
||||
example/benchmark
|
||||
example/redirect
|
||||
example/*.pem
|
||||
test/test
|
||||
test/test.xcodeproj/xcuser*
|
||||
|
||||
+4
-3
@@ -1,12 +1,13 @@
|
||||
# Environment
|
||||
language: cpp
|
||||
os: osx
|
||||
os:
|
||||
- osx
|
||||
|
||||
# Compiler selection
|
||||
compiler:
|
||||
- clang
|
||||
|
||||
# Build/test steps
|
||||
script:
|
||||
script:
|
||||
- cd ${TRAVIS_BUILD_DIR}/test
|
||||
- make all
|
||||
- make all
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ install(TARGETS ${PROJECT_NAME} EXPORT httplibConfig
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
|
||||
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME})
|
||||
install(FILES httplib.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME})
|
||||
|
||||
install(EXPORT httplibConfig DESTINATION share/httplib/cmake)
|
||||
|
||||
|
||||
@@ -4,12 +4,10 @@ cpp-httplib
|
||||
[](https://travis-ci.org/yhirose/cpp-httplib)
|
||||
[](https://ci.appveyor.com/project/yhirose/cpp-httplib)
|
||||
|
||||
A C++11 header-only HTTP library.
|
||||
A C++ single-file header-only cross platform HTTP/HTTPS library.
|
||||
|
||||
It's extremely easy to setup. Just include **httplib.h** file in your code!
|
||||
|
||||
Inspired by [Sinatra](http://www.sinatrarb.com/) and [express](https://github.com/visionmedia/express).
|
||||
|
||||
Server Example
|
||||
--------------
|
||||
|
||||
@@ -31,6 +29,10 @@ int main(void)
|
||||
res.set_content(numbers, "text/plain");
|
||||
});
|
||||
|
||||
svr.Get("/stop", [&](const Request& req, Response& res) {
|
||||
svr.stop();
|
||||
});
|
||||
|
||||
svr.listen("localhost", 1234);
|
||||
}
|
||||
```
|
||||
@@ -44,18 +46,6 @@ int port = svr.bind_to_any_port("0.0.0.0");
|
||||
svr.listen_after_bind();
|
||||
```
|
||||
|
||||
### Method Chain
|
||||
|
||||
```cpp
|
||||
svr.Get("/get", [](const auto& req, auto& res) {
|
||||
res.set_content("get", "text/plain");
|
||||
})
|
||||
.Post("/post", [](const auto& req, auto& res) {
|
||||
res.set_content(req.body(), "text/plain");
|
||||
})
|
||||
.listen("localhost", 1234);
|
||||
```
|
||||
|
||||
### Static File Server
|
||||
|
||||
```cpp
|
||||
@@ -114,6 +104,25 @@ int main(void)
|
||||
}
|
||||
```
|
||||
|
||||
### GET with HTTP headers
|
||||
|
||||
```c++
|
||||
httplib::Headers headers = {
|
||||
{ "Accept-Encoding", "gzip, deflate" }
|
||||
};
|
||||
auto res = cli.Get("/hi", headers);
|
||||
```
|
||||
|
||||
### GET with Content Receiver
|
||||
|
||||
```c++
|
||||
std::string body;
|
||||
auto res = cli.Get("/large-data", [&](const char *data, size_t len) {
|
||||
body.append(data, len);
|
||||
});
|
||||
assert(res->body.empty());
|
||||
```
|
||||
|
||||
### POST
|
||||
|
||||
```c++
|
||||
@@ -141,6 +150,20 @@ httplib::Params params{
|
||||
auto res = cli.Post("/post", params);
|
||||
```
|
||||
|
||||
### POST with Multipart Form Data
|
||||
|
||||
```c++
|
||||
httplib::MultipartFormDataItems items = {
|
||||
{ "text1", "text default", "", "" },
|
||||
{ "text2", "aωb", "", "" },
|
||||
{ "file1", "h\ne\n\nl\nl\no\n", "hello.txt", "text/plain" },
|
||||
{ "file2", "{\n \"world\", true\n}\n", "world.json", "application/json" },
|
||||
{ "file3", "", "", "application/octet-stream" },
|
||||
};
|
||||
|
||||
auto res = cli.Post("/multipart", items);
|
||||
```
|
||||
|
||||
### PUT
|
||||
|
||||
```c++
|
||||
@@ -185,15 +208,26 @@ std::shared_ptr<httplib::Response> res =
|
||||
|
||||
This feature was contributed by [underscorediscovery](https://github.com/yhirose/cpp-httplib/pull/23).
|
||||
|
||||
### Basic Authentication
|
||||
|
||||
```cpp
|
||||
httplib::Client cli("httplib.org");
|
||||
|
||||
auto res = cli.Get("/basic-auth/hello/world", {
|
||||
httplib::make_basic_authentication_header("hello", "world")
|
||||
});
|
||||
// res->status should be 200
|
||||
// res->body should be "{\n \"authenticated\": true, \n \"user\": \"hello\"\n}\n".
|
||||
```
|
||||
|
||||
### Range
|
||||
|
||||
```cpp
|
||||
httplib::Client cli("httpbin.org", 80);
|
||||
httplib::Client cli("httpbin.org");
|
||||
|
||||
// 'Range: bytes=1-10'
|
||||
httplib::Headers headers = { httplib::make_range_header(1, 10) };
|
||||
|
||||
auto res = cli.Get("/range/32", headers);
|
||||
auto res = cli.Get("/range/32", {
|
||||
httplib::make_range_header(1, 10) // 'Range: bytes=1-10'
|
||||
});
|
||||
// res->status should be 206.
|
||||
// res->body should be "bcdefghijk".
|
||||
```
|
||||
|
||||
+12
-9
@@ -1,29 +1,32 @@
|
||||
|
||||
CC = clang++
|
||||
CFLAGS = -std=c++14 -I.. -Wall -Wextra -lpthread
|
||||
#CXX = clang++
|
||||
CXXFLAGS = -std=c++14 -I.. -Wall -Wextra -pthread
|
||||
OPENSSL_SUPPORT = -DCPPHTTPLIB_OPENSSL_SUPPORT -I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib -lssl -lcrypto
|
||||
ZLIB_SUPPORT = -DCPPHTTPLIB_ZLIB_SUPPORT -lz
|
||||
|
||||
all: server client hello simplesvr benchmark
|
||||
all: server client hello simplesvr redirect benchmark
|
||||
|
||||
server : server.cc ../httplib.h Makefile
|
||||
$(CC) -o server $(CFLAGS) server.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT)
|
||||
$(CXX) -o server $(CXXFLAGS) server.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT)
|
||||
|
||||
client : client.cc ../httplib.h Makefile
|
||||
$(CC) -o client $(CFLAGS) client.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT)
|
||||
$(CXX) -o client $(CXXFLAGS) client.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT)
|
||||
|
||||
hello : hello.cc ../httplib.h Makefile
|
||||
$(CC) -o hello $(CFLAGS) hello.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT)
|
||||
$(CXX) -o hello $(CXXFLAGS) hello.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT)
|
||||
|
||||
simplesvr : simplesvr.cc ../httplib.h Makefile
|
||||
$(CC) -o simplesvr $(CFLAGS) simplesvr.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT)
|
||||
$(CXX) -o simplesvr $(CXXFLAGS) simplesvr.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT)
|
||||
|
||||
redirect : redirect.cc ../httplib.h Makefile
|
||||
$(CXX) -o redirect $(CXXFLAGS) redirect.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT)
|
||||
|
||||
benchmark : benchmark.cc ../httplib.h Makefile
|
||||
$(CC) -o benchmark $(CFLAGS) benchmark.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT)
|
||||
$(CXX) -o benchmark $(CXXFLAGS) benchmark.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT)
|
||||
|
||||
pem:
|
||||
openssl genrsa 2048 > key.pem
|
||||
openssl req -new -key key.pem | openssl x509 -days 3650 -req -signkey key.pem > cert.pem
|
||||
|
||||
clean:
|
||||
rm server client hello simplesvr *.pem
|
||||
rm server client hello simplesvr redirect *.pem
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
//
|
||||
// client.cc
|
||||
//
|
||||
// Copyright (c) 2012 Yuji Hirose. All rights reserved.
|
||||
// The Boost Software License 1.0
|
||||
// Copyright (c) 2019 Yuji Hirose. All rights reserved.
|
||||
// MIT License
|
||||
//
|
||||
|
||||
#include <httplib.h>
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
//
|
||||
// hello.cc
|
||||
//
|
||||
// Copyright (c) 2012 Yuji Hirose. All rights reserved.
|
||||
// The Boost Software License 1.0
|
||||
// Copyright (c) 2019 Yuji Hirose. All rights reserved.
|
||||
// MIT License
|
||||
//
|
||||
|
||||
#include <httplib.h>
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
//
|
||||
// redirect.cc
|
||||
//
|
||||
// Copyright (c) 2019 Yuji Hirose. All rights reserved.
|
||||
// MIT License
|
||||
//
|
||||
|
||||
#include <httplib.h>
|
||||
|
||||
#define SERVER_CERT_FILE "./cert.pem"
|
||||
#define SERVER_PRIVATE_KEY_FILE "./key.pem"
|
||||
|
||||
using namespace httplib;
|
||||
|
||||
int main(void) {
|
||||
// HTTP server
|
||||
Server http;
|
||||
|
||||
http.Get("/test", [](const Request & /*req*/, Response &res) {
|
||||
res.set_content("Test\n", "text/plain");
|
||||
});
|
||||
|
||||
http.set_error_handler([](const Request & /*req*/, Response &res) {
|
||||
res.set_redirect("https://localhost:8081/");
|
||||
});
|
||||
|
||||
// HTTPS server
|
||||
SSLServer https(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE);
|
||||
|
||||
https.Get("/", [=](const Request & /*req*/, Response &res) {
|
||||
res.set_redirect("/hi");
|
||||
});
|
||||
|
||||
https.Get("/hi", [](const Request & /*req*/, Response &res) {
|
||||
res.set_content("Hello World!\n", "text/plain");
|
||||
});
|
||||
|
||||
https.Get("/stop", [&](const Request & /*req*/, Response & /*res*/) {
|
||||
https.stop();
|
||||
http.stop();
|
||||
});
|
||||
|
||||
// Run servers
|
||||
auto httpThread = std::thread([&]() {
|
||||
http.listen("localhost", 8080);
|
||||
});
|
||||
|
||||
auto httpsThread = std::thread([&]() {
|
||||
https.listen("localhost", 8081);
|
||||
});
|
||||
|
||||
httpThread.join();
|
||||
httpsThread.join();
|
||||
|
||||
return 0;
|
||||
}
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
//
|
||||
// sample.cc
|
||||
//
|
||||
// Copyright (c) 2012 Yuji Hirose. All rights reserved.
|
||||
// The Boost Software License 1.0
|
||||
// Copyright (c) 2019 Yuji Hirose. All rights reserved.
|
||||
// MIT License
|
||||
//
|
||||
|
||||
#include <chrono>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
//
|
||||
// simplesvr.cc
|
||||
//
|
||||
// Copyright (c) 2013 Yuji Hirose. All rights reserved.
|
||||
// The Boost Software License 1.0
|
||||
// Copyright (c) 2019 Yuji Hirose. All rights reserved.
|
||||
// MIT License
|
||||
//
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
+3
-5
@@ -1,8 +1,6 @@
|
||||
|
||||
CC = clang++
|
||||
#CC = g++
|
||||
|
||||
CFLAGS = -ggdb -O0 -std=c++11 -DGTEST_USE_OWN_TR1_TUPLE -I.. -I. -Wall -Wextra -Wtype-limits
|
||||
#CXX = clang++
|
||||
CXXFLAGS = -ggdb -O0 -std=c++11 -DGTEST_USE_OWN_TR1_TUPLE -I.. -I. -Wall -Wextra -Wtype-limits
|
||||
OPENSSL_SUPPORT = -DCPPHTTPLIB_OPENSSL_SUPPORT -I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib -lssl -lcrypto
|
||||
ZLIB_SUPPORT = -DCPPHTTPLIB_ZLIB_SUPPORT -lz
|
||||
|
||||
@@ -10,7 +8,7 @@ all : test
|
||||
./test
|
||||
|
||||
test : test.cc ../httplib.h Makefile cert.pem
|
||||
$(CC) -o test $(CFLAGS) test.cc gtest/gtest-all.cc gtest/gtest_main.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) -lpthread
|
||||
$(CXX) -o test $(CXXFLAGS) test.cc gtest/gtest-all.cc gtest/gtest_main.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) -pthread
|
||||
|
||||
cert.pem:
|
||||
openssl genrsa 2048 > key.pem
|
||||
|
||||
+80
-46
@@ -142,6 +142,31 @@ TEST(ChunkedEncodingTest, FromHTTPWatch) {
|
||||
EXPECT_EQ(out, res->body);
|
||||
}
|
||||
|
||||
TEST(ChunkedEncodingTest, WithContentReceiver) {
|
||||
auto host = "www.httpwatch.com";
|
||||
auto sec = 2;
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
auto port = 443;
|
||||
httplib::SSLClient cli(host, port, sec);
|
||||
#else
|
||||
auto port = 80;
|
||||
httplib::Client cli(host, port, sec);
|
||||
#endif
|
||||
|
||||
std::string body;
|
||||
auto res =
|
||||
cli.Get("/httpgallery/chunked/chunkedimage.aspx?0.4153841143030137",
|
||||
[&](const char *data, size_t len) { body.append(data, len); });
|
||||
ASSERT_TRUE(res != nullptr);
|
||||
|
||||
std::string out;
|
||||
httplib::detail::read_file("./image.jpg", out);
|
||||
|
||||
EXPECT_EQ(200, res->status);
|
||||
EXPECT_EQ(out, body);
|
||||
}
|
||||
|
||||
TEST(RangeTest, FromHTTPBin) {
|
||||
auto host = "httpbin.org";
|
||||
auto sec = 5;
|
||||
@@ -239,9 +264,8 @@ TEST(CancelTest, NoCancel) {
|
||||
httplib::Client cli(host, port, sec);
|
||||
#endif
|
||||
|
||||
httplib::Headers headers;
|
||||
auto res =
|
||||
cli.Get("/range/32", headers, [](uint64_t, uint64_t) { return true; });
|
||||
cli.Get("/range/32", [](uint64_t, uint64_t) { return true; });
|
||||
ASSERT_TRUE(res != nullptr);
|
||||
EXPECT_EQ(res->body, "abcdefghijklmnopqrstuvwxyzabcdef");
|
||||
EXPECT_EQ(200, res->status);
|
||||
@@ -259,9 +283,8 @@ TEST(CancelTest, WithCancelSmallPayload) {
|
||||
httplib::Client cli(host, port, sec);
|
||||
#endif
|
||||
|
||||
httplib::Headers headers;
|
||||
auto res =
|
||||
cli.Get("/range/32", headers, [](uint64_t, uint64_t) { return false; });
|
||||
cli.Get("/range/32", [](uint64_t, uint64_t) { return false; });
|
||||
ASSERT_TRUE(res == nullptr);
|
||||
}
|
||||
|
||||
@@ -302,8 +325,9 @@ TEST(BaseAuthTest, FromHTTPWatch) {
|
||||
}
|
||||
|
||||
{
|
||||
httplib::Headers headers = {{"Authorization", "Basic aGVsbG86d29ybGQ="}};
|
||||
auto res = cli.Get("/basic-auth/hello/world", headers);
|
||||
auto res = cli.Get("/basic-auth/hello/world", {
|
||||
httplib::make_basic_authentication_header("hello", "world")
|
||||
});
|
||||
ASSERT_TRUE(res != nullptr);
|
||||
EXPECT_EQ(res->body,
|
||||
"{\n \"authenticated\": true, \n \"user\": \"hello\"\n}\n");
|
||||
@@ -380,7 +404,7 @@ protected:
|
||||
})
|
||||
.Get("/streamedchunked",
|
||||
[&](const Request & /*req*/, Response &res) {
|
||||
res.streamcb = [](uint64_t offset) {
|
||||
res.content_producer = [](uint64_t offset) {
|
||||
if (offset < 3) return "a";
|
||||
if (offset < 6) return "b";
|
||||
return "";
|
||||
@@ -389,7 +413,7 @@ protected:
|
||||
.Get("/streamed",
|
||||
[&](const Request & /*req*/, Response &res) {
|
||||
res.set_header("Content-Length", "6");
|
||||
res.streamcb = [](uint64_t offset) {
|
||||
res.content_producer = [](uint64_t offset) {
|
||||
if (offset < 3) return "a";
|
||||
if (offset < 6) return "b";
|
||||
return "";
|
||||
@@ -938,44 +962,17 @@ TEST_F(ServerTest, EndWithPercentCharacterInQuery) {
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, MultipartFormData) {
|
||||
Request req;
|
||||
req.method = "POST";
|
||||
req.path = "/multipart";
|
||||
MultipartFormDataItems items = {
|
||||
{ "text1", "text default", "", "" },
|
||||
{ "text2", "aωb", "", "" },
|
||||
{ "file1", "h\ne\n\nl\nl\no\n", "hello.txt", "text/plain" },
|
||||
{ "file2", "{\n \"world\", true\n}\n", "world.json", "application/json" },
|
||||
{ "file3", "", "", "application/octet-stream" },
|
||||
};
|
||||
|
||||
std::string host_and_port;
|
||||
host_and_port += HOST;
|
||||
host_and_port += ":";
|
||||
host_and_port += std::to_string(PORT);
|
||||
auto res = cli_.Post("/multipart", items);
|
||||
|
||||
req.headers.emplace("Host", host_and_port.c_str());
|
||||
req.headers.emplace("Accept", "*/*");
|
||||
req.headers.emplace("User-Agent", "cpp-httplib/0.1");
|
||||
req.headers.emplace(
|
||||
"Content-Type",
|
||||
"multipart/form-data; boundary=----WebKitFormBoundarysBREP3G013oUrLB4");
|
||||
|
||||
req.body =
|
||||
"------WebKitFormBoundarysBREP3G013oUrLB4\r\nContent-Disposition: "
|
||||
"form-data; name=\"text1\"\r\n\r\ntext "
|
||||
"default\r\n------WebKitFormBoundarysBREP3G013oUrLB4\r\nContent-"
|
||||
"Disposition: form-data; "
|
||||
"name=\"text2\"\r\n\r\naωb\r\n------"
|
||||
"WebKitFormBoundarysBREP3G013oUrLB4\r\nContent-Disposition: form-data; "
|
||||
"name=\"file1\"; filename=\"hello.txt\"\r\nContent-Type: "
|
||||
"text/"
|
||||
"plain\r\n\r\nh\ne\n\nl\nl\no\n\r\n------"
|
||||
"WebKitFormBoundarysBREP3G013oUrLB4\r\nContent-Disposition: form-data; "
|
||||
"name=\"file2\"; filename=\"world.json\"\r\nContent-Type: "
|
||||
"application/json\r\n\r\n{\n \"world\", "
|
||||
"true\n}\n\r\n------WebKitFormBoundarysBREP3G013oUrLB4\r\ncontent-"
|
||||
"disposition: form-data; name=\"file3\"; filename=\"\"\r\ncontent-type: "
|
||||
"application/"
|
||||
"octet-stream\r\n\r\n\r\n------WebKitFormBoundarysBREP3G013oUrLB4--\r\n";
|
||||
|
||||
auto res = std::make_shared<Response>();
|
||||
auto ret = cli_.send(req, *res);
|
||||
|
||||
ASSERT_TRUE(ret);
|
||||
ASSERT_TRUE(res != nullptr);
|
||||
EXPECT_EQ(200, res->status);
|
||||
}
|
||||
|
||||
@@ -1122,8 +1119,9 @@ TEST_F(ServerTest, ArrayParam) {
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, NoMultipleHeaders) {
|
||||
Headers headers;
|
||||
headers.emplace("Content-Length", "5");
|
||||
Headers headers = {
|
||||
{ "Content-Length", "5" }
|
||||
};
|
||||
auto res = cli_.Post("/validate-no-multiple-headers", headers, "hello",
|
||||
"text/plain");
|
||||
ASSERT_TRUE(res != nullptr);
|
||||
@@ -1146,6 +1144,24 @@ TEST_F(ServerTest, Gzip) {
|
||||
EXPECT_EQ(200, res->status);
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, GzipWithContentReceiver) {
|
||||
Headers headers;
|
||||
headers.emplace("Accept-Encoding", "gzip, deflate");
|
||||
std::string body;
|
||||
auto res = cli_.Get("/gzip", headers, [&](const char *data, size_t len) {
|
||||
body.append(data, len);
|
||||
});
|
||||
|
||||
ASSERT_TRUE(res != nullptr);
|
||||
EXPECT_EQ("gzip", res->get_header_value("Content-Encoding"));
|
||||
EXPECT_EQ("text/plain", res->get_header_value("Content-Type"));
|
||||
EXPECT_EQ("33", res->get_header_value("Content-Length"));
|
||||
EXPECT_EQ("123456789012345678901234567890123456789012345678901234567890123456"
|
||||
"7890123456789012345678901234567890",
|
||||
body);
|
||||
EXPECT_EQ(200, res->status);
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, NoGzip) {
|
||||
Headers headers;
|
||||
headers.emplace("Accept-Encoding", "gzip, deflate");
|
||||
@@ -1161,6 +1177,24 @@ TEST_F(ServerTest, NoGzip) {
|
||||
EXPECT_EQ(200, res->status);
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, NoGzipWithContentReceiver) {
|
||||
Headers headers;
|
||||
headers.emplace("Accept-Encoding", "gzip, deflate");
|
||||
std::string body;
|
||||
auto res = cli_.Get("/nogzip", headers, [&](const char *data, size_t len) {
|
||||
body.append(data, len);
|
||||
});
|
||||
|
||||
ASSERT_TRUE(res != nullptr);
|
||||
EXPECT_EQ(false, res->has_header("Content-Encoding"));
|
||||
EXPECT_EQ("application/octet-stream", res->get_header_value("Content-Type"));
|
||||
EXPECT_EQ("100", res->get_header_value("Content-Length"));
|
||||
EXPECT_EQ("123456789012345678901234567890123456789012345678901234567890123456"
|
||||
"7890123456789012345678901234567890",
|
||||
body);
|
||||
EXPECT_EQ(200, res->status);
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, MultipartFormDataGzip) {
|
||||
Request req;
|
||||
req.method = "POST";
|
||||
|
||||
Reference in New Issue
Block a user