mirror of
https://github.com/yhirose/cpp-httplib
synced 2026-06-08 18:30:49 +00:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ab477b5631 | |||
| 0823d5c7f2 | |||
| 1cc6930363 | |||
| 4297500928 | |||
| a58f042614 | |||
| 469c6bc2b6 | |||
| 887074efd2 | |||
| 9c2c15ca45 | |||
| 1b3b098329 | |||
| 6f7075e3aa | |||
| ccbddd8842 | |||
| 879dd261c2 | |||
| 52f5eb5980 | |||
| ea2f69a0d7 | |||
| 9f2064a8ed | |||
| e3750d9ddf | |||
| c1eee3012e | |||
| 6b08babbd2 |
@@ -26,7 +26,7 @@ jobs:
|
||||
run: brew install brotli
|
||||
- name: make
|
||||
if: matrix.os != 'windows-latest'
|
||||
run: cd test && make
|
||||
run: cd test && make -j2
|
||||
- name: check fuzz test target
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
run: cd test && make -f Makefile.fuzz_test
|
||||
|
||||
@@ -10,8 +10,11 @@ example/redirect
|
||||
example/sse*
|
||||
example/upload
|
||||
example/*.pem
|
||||
test/httplib.cc
|
||||
test/httplib.h
|
||||
test/test
|
||||
test/test_proxy
|
||||
test/test_split
|
||||
test/test.xcodeproj/xcuser*
|
||||
test/test.xcodeproj/*/xcuser*
|
||||
test/*.pem
|
||||
|
||||
@@ -256,6 +256,7 @@ svr.Post("/multipart", [&](const auto& req, auto& res) {
|
||||
svr.Post("/content_receiver",
|
||||
[&](const Request &req, Response &res, const ContentReader &content_reader) {
|
||||
if (req.is_multipart_form_data()) {
|
||||
// NOTE: `content_reader` is blocking until every form data field is read
|
||||
MultipartFormDataItems files;
|
||||
content_reader(
|
||||
[&](const MultipartFormData &file) {
|
||||
@@ -272,7 +273,6 @@ svr.Post("/content_receiver",
|
||||
body.append(data, data_length);
|
||||
return true;
|
||||
});
|
||||
res.set_content(body, "text/plain");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -749,10 +749,20 @@ res->body; // Compressed data
|
||||
Split httplib.h into .h and .cc
|
||||
-------------------------------
|
||||
|
||||
```bash
|
||||
> python3 split.py
|
||||
> ls out
|
||||
httplib.h httplib.cc
|
||||
```console
|
||||
$ ./split.py -h
|
||||
usage: split.py [-h] [-e EXTENSION] [-o OUT]
|
||||
|
||||
This script splits httplib.h into .h and .cc parts.
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
-e EXTENSION, --extension EXTENSION
|
||||
extension of the implementation file (default: cc)
|
||||
-o OUT, --out OUT where to write the files (default: out)
|
||||
|
||||
$ ./split.py
|
||||
Wrote out/httplib.h and out/httplib.cc
|
||||
```
|
||||
|
||||
NOTE
|
||||
|
||||
@@ -1,32 +1,47 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""This script splits httplib.h into .h and .cc parts."""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
border = '// ----------------------------------------------------------------------------'
|
||||
|
||||
PythonVersion = sys.version_info[0];
|
||||
args_parser = argparse.ArgumentParser(description=__doc__)
|
||||
args_parser.add_argument(
|
||||
"-e", "--extension", help="extension of the implementation file (default: cc)",
|
||||
default="cc"
|
||||
)
|
||||
args_parser.add_argument(
|
||||
"-o", "--out", help="where to write the files (default: out)", default="out"
|
||||
)
|
||||
args = args_parser.parse_args()
|
||||
|
||||
with open('httplib.h') as f:
|
||||
cur_dir = os.path.dirname(sys.argv[0])
|
||||
with open(cur_dir + '/httplib.h') as f:
|
||||
lines = f.readlines()
|
||||
inImplementation = False
|
||||
|
||||
if PythonVersion < 3:
|
||||
os.makedirs('out')
|
||||
else:
|
||||
os.makedirs('out', exist_ok=True)
|
||||
|
||||
with open('out/httplib.h', 'w') as fh:
|
||||
with open('out/httplib.cc', 'w') as fc:
|
||||
fc.write('#include "httplib.h"\n')
|
||||
fc.write('namespace httplib {\n')
|
||||
for line in lines:
|
||||
isBorderLine = border in line
|
||||
if isBorderLine:
|
||||
inImplementation = not inImplementation
|
||||
else:
|
||||
if inImplementation:
|
||||
fc.write(line.replace('inline ', ''))
|
||||
pass
|
||||
else:
|
||||
fh.write(line)
|
||||
pass
|
||||
fc.write('} // namespace httplib\n')
|
||||
|
||||
python_version = sys.version_info[0]
|
||||
if python_version < 3:
|
||||
os.makedirs(args.out)
|
||||
else:
|
||||
os.makedirs(args.out, exist_ok=True)
|
||||
|
||||
in_implementation = False
|
||||
h_out = args.out + '/httplib.h'
|
||||
cc_out = args.out + '/httplib.' + args.extension
|
||||
with open(h_out, 'w') as fh, open(cc_out, 'w') as fc:
|
||||
fc.write('#include "httplib.h"\n')
|
||||
fc.write('namespace httplib {\n')
|
||||
for line in lines:
|
||||
is_border_line = border in line
|
||||
if is_border_line:
|
||||
in_implementation = not in_implementation
|
||||
elif in_implementation:
|
||||
fc.write(line.replace('inline ', ''))
|
||||
else:
|
||||
fh.write(line)
|
||||
fc.write('} // namespace httplib\n')
|
||||
|
||||
print("Wrote {} and {}".format(h_out, cc_out))
|
||||
|
||||
+16
-6
@@ -1,5 +1,5 @@
|
||||
#CXX = clang++
|
||||
CXXFLAGS = -g -std=c++11 -DGTEST_USE_OWN_TR1_TUPLE -I.. -I. -Wall -Wextra -Wtype-limits -Wconversion #-fsanitize=address
|
||||
CXXFLAGS = -g -std=c++11 -I. -Wall -Wextra -Wtype-limits -Wconversion #-fsanitize=address
|
||||
|
||||
OPENSSL_DIR = /usr/local/opt/openssl@1.1
|
||||
OPENSSL_SUPPORT = -DCPPHTTPLIB_OPENSSL_SUPPORT -I$(OPENSSL_DIR)/include -L$(OPENSSL_DIR)/lib -lssl -lcrypto
|
||||
@@ -9,17 +9,27 @@ ZLIB_SUPPORT = -DCPPHTTPLIB_ZLIB_SUPPORT -lz
|
||||
BROTLI_DIR = /usr/local/opt/brotli
|
||||
BROTLI_SUPPORT = -DCPPHTTPLIB_BROTLI_SUPPORT -I$(BROTLI_DIR)/include -L$(BROTLI_DIR)/lib -lbrotlicommon -lbrotlienc -lbrotlidec
|
||||
|
||||
all : test
|
||||
TEST_ARGS = gtest/gtest-all.cc gtest/gtest_main.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT) -pthread
|
||||
|
||||
all : test test_split
|
||||
./test
|
||||
# Note: The intention of test_split is to verify that it works to compile and
|
||||
# link the split httplib.h, so there is normally no need to execute it.
|
||||
|
||||
proxy : test_proxy
|
||||
./test_proxy
|
||||
|
||||
test : test.cc ../httplib.h Makefile cert.pem
|
||||
$(CXX) -o test $(CXXFLAGS) test.cc gtest/gtest-all.cc gtest/gtest_main.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT) -pthread
|
||||
test : test.cc include_httplib.cc ../httplib.h Makefile cert.pem
|
||||
$(CXX) -o $@ -I.. $(CXXFLAGS) test.cc include_httplib.cc $(TEST_ARGS)
|
||||
|
||||
test_split : test.cc ../httplib.h httplib.cc Makefile cert.pem
|
||||
$(CXX) -o $@ $(CXXFLAGS) test.cc httplib.cc $(TEST_ARGS)
|
||||
|
||||
test_proxy : test_proxy.cc ../httplib.h Makefile cert.pem
|
||||
$(CXX) -o test_proxy $(CXXFLAGS) test_proxy.cc gtest/gtest-all.cc gtest/gtest_main.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT) -pthread
|
||||
$(CXX) -o $@ -I.. $(CXXFLAGS) test_proxy.cc $(TEST_ARGS)
|
||||
|
||||
httplib.cc : ../httplib.h
|
||||
python3 ../split.py -o .
|
||||
|
||||
cert.pem:
|
||||
openssl genrsa 2048 > key.pem
|
||||
@@ -32,4 +42,4 @@ cert.pem:
|
||||
#c_rehash .
|
||||
|
||||
clean:
|
||||
rm -f test test_proxy pem *.0 *.1 *.srl
|
||||
rm -f test test_proxy pem *.0 *.1 *.srl httplib.h httplib.cc
|
||||
|
||||
+5790
-2421
File diff suppressed because it is too large
Load Diff
+6845
-14039
File diff suppressed because it is too large
Load Diff
@@ -27,13 +27,28 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <cstdio>
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
GTEST_API_ int main(int argc, char **argv) {
|
||||
std::cout << "Running main() from gtest_main.cc\n";
|
||||
#if GTEST_OS_ESP8266 || GTEST_OS_ESP32
|
||||
#if GTEST_OS_ESP8266
|
||||
extern "C" {
|
||||
#endif
|
||||
void setup() {
|
||||
testing::InitGoogleTest();
|
||||
}
|
||||
|
||||
void loop() { RUN_ALL_TESTS(); }
|
||||
|
||||
#if GTEST_OS_ESP8266
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
GTEST_API_ int main(int argc, char **argv) {
|
||||
printf("Running main() from %s\n", __FILE__);
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
// The sole purpose of this file is to include httplib.h in a separate
|
||||
// compilation unit, thus verifying that inline keywords have not been forgotten
|
||||
// when linked together with test.cc.
|
||||
|
||||
#include <httplib.h>
|
||||
+188
-96
@@ -172,7 +172,7 @@ TEST(GetHeaderValueTest, SetContent) {
|
||||
EXPECT_EQ("text/html", res.get_header_value("Content-Type"));
|
||||
|
||||
res.set_content("text", "text/plain");
|
||||
EXPECT_EQ(1, res.get_header_value_count("Content-Type"));
|
||||
EXPECT_EQ(1U, res.get_header_value_count("Content-Type"));
|
||||
EXPECT_EQ("text/plain", res.get_header_value("Content-Type"));
|
||||
}
|
||||
|
||||
@@ -354,7 +354,7 @@ TEST(BufferStreamTest, read) {
|
||||
EXPECT_EQ(0, strm.read(buf, 1));
|
||||
}
|
||||
|
||||
TEST(ChunkedEncodingTest, FromHTTPWatch) {
|
||||
TEST(ChunkedEncodingTest, FromHTTPWatch_Online) {
|
||||
auto host = "www.httpwatch.com";
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@@ -377,7 +377,7 @@ TEST(ChunkedEncodingTest, FromHTTPWatch) {
|
||||
EXPECT_EQ(out, res->body);
|
||||
}
|
||||
|
||||
TEST(ChunkedEncodingTest, WithContentReceiver) {
|
||||
TEST(ChunkedEncodingTest, WithContentReceiver_Online) {
|
||||
auto host = "www.httpwatch.com";
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@@ -405,7 +405,7 @@ TEST(ChunkedEncodingTest, WithContentReceiver) {
|
||||
EXPECT_EQ(out, body);
|
||||
}
|
||||
|
||||
TEST(ChunkedEncodingTest, WithResponseHandlerAndContentReceiver) {
|
||||
TEST(ChunkedEncodingTest, WithResponseHandlerAndContentReceiver_Online) {
|
||||
auto host = "www.httpwatch.com";
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@@ -437,7 +437,7 @@ TEST(ChunkedEncodingTest, WithResponseHandlerAndContentReceiver) {
|
||||
EXPECT_EQ(out, body);
|
||||
}
|
||||
|
||||
TEST(RangeTest, FromHTTPBin) {
|
||||
TEST(RangeTest, FromHTTPBin_Online) {
|
||||
auto host = "httpbin.org";
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@@ -542,7 +542,7 @@ TEST(ConnectionErrorTest, InvalidHostCheckResultErrorToString) {
|
||||
ASSERT_TRUE(!res);
|
||||
stringstream s;
|
||||
s << "error code: " << res.error();
|
||||
EXPECT_EQ("error code: 2", s.str());
|
||||
EXPECT_EQ("error code: Connection (2)", s.str());
|
||||
}
|
||||
|
||||
TEST(ConnectionErrorTest, InvalidPort) {
|
||||
@@ -578,7 +578,7 @@ TEST(ConnectionErrorTest, Timeout) {
|
||||
EXPECT_TRUE(res.error() == Error::Connection);
|
||||
}
|
||||
|
||||
TEST(CancelTest, NoCancel) {
|
||||
TEST(CancelTest, NoCancel_Online) {
|
||||
auto host = "httpbin.org";
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@@ -596,7 +596,7 @@ TEST(CancelTest, NoCancel) {
|
||||
EXPECT_EQ(200, res->status);
|
||||
}
|
||||
|
||||
TEST(CancelTest, WithCancelSmallPayload) {
|
||||
TEST(CancelTest, WithCancelSmallPayload_Online) {
|
||||
auto host = "httpbin.org";
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@@ -613,7 +613,7 @@ TEST(CancelTest, WithCancelSmallPayload) {
|
||||
EXPECT_EQ(Error::Canceled, res.error());
|
||||
}
|
||||
|
||||
TEST(CancelTest, WithCancelLargePayload) {
|
||||
TEST(CancelTest, WithCancelLargePayload_Online) {
|
||||
auto host = "httpbin.org";
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@@ -632,7 +632,7 @@ TEST(CancelTest, WithCancelLargePayload) {
|
||||
EXPECT_EQ(Error::Canceled, res.error());
|
||||
}
|
||||
|
||||
TEST(BaseAuthTest, FromHTTPWatch) {
|
||||
TEST(BaseAuthTest, FromHTTPWatch_Online) {
|
||||
auto host = "httpbin.org";
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@@ -683,7 +683,7 @@ TEST(BaseAuthTest, FromHTTPWatch) {
|
||||
}
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
TEST(DigestAuthTest, FromHTTPWatch) {
|
||||
TEST(DigestAuthTest, FromHTTPWatch_Online) {
|
||||
auto host = "httpbin.org";
|
||||
auto port = 443;
|
||||
SSLClient cli(host, port);
|
||||
@@ -730,7 +730,7 @@ TEST(DigestAuthTest, FromHTTPWatch) {
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(AbsoluteRedirectTest, Redirect) {
|
||||
TEST(AbsoluteRedirectTest, Redirect_Online) {
|
||||
auto host = "nghttp2.org";
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@@ -745,7 +745,7 @@ TEST(AbsoluteRedirectTest, Redirect) {
|
||||
EXPECT_EQ(200, res->status);
|
||||
}
|
||||
|
||||
TEST(RedirectTest, Redirect) {
|
||||
TEST(RedirectTest, Redirect_Online) {
|
||||
auto host = "nghttp2.org";
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@@ -760,7 +760,7 @@ TEST(RedirectTest, Redirect) {
|
||||
EXPECT_EQ(200, res->status);
|
||||
}
|
||||
|
||||
TEST(RelativeRedirectTest, Redirect) {
|
||||
TEST(RelativeRedirectTest, Redirect_Online) {
|
||||
auto host = "nghttp2.org";
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@@ -775,7 +775,7 @@ TEST(RelativeRedirectTest, Redirect) {
|
||||
EXPECT_EQ(200, res->status);
|
||||
}
|
||||
|
||||
TEST(TooManyRedirectTest, Redirect) {
|
||||
TEST(TooManyRedirectTest, Redirect_Online) {
|
||||
auto host = "nghttp2.org";
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@@ -791,7 +791,7 @@ TEST(TooManyRedirectTest, Redirect) {
|
||||
}
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
TEST(YahooRedirectTest, Redirect) {
|
||||
TEST(YahooRedirectTest, Redirect_Online) {
|
||||
Client cli("yahoo.com");
|
||||
|
||||
auto res = cli.Get("/");
|
||||
@@ -805,7 +805,7 @@ TEST(YahooRedirectTest, Redirect) {
|
||||
EXPECT_EQ("https://yahoo.com/", res->location);
|
||||
}
|
||||
|
||||
TEST(HttpsToHttpRedirectTest, Redirect) {
|
||||
TEST(HttpsToHttpRedirectTest, Redirect_Online) {
|
||||
SSLClient cli("nghttp2.org");
|
||||
cli.set_follow_location(true);
|
||||
auto res = cli.Get(
|
||||
@@ -814,7 +814,7 @@ TEST(HttpsToHttpRedirectTest, Redirect) {
|
||||
EXPECT_EQ(200, res->status);
|
||||
}
|
||||
|
||||
TEST(HttpsToHttpRedirectTest2, Redirect) {
|
||||
TEST(HttpsToHttpRedirectTest2, Redirect_Online) {
|
||||
SSLClient cli("nghttp2.org");
|
||||
cli.set_follow_location(true);
|
||||
|
||||
@@ -827,7 +827,7 @@ TEST(HttpsToHttpRedirectTest2, Redirect) {
|
||||
EXPECT_EQ(200, res->status);
|
||||
}
|
||||
|
||||
TEST(HttpsToHttpRedirectTest3, Redirect) {
|
||||
TEST(HttpsToHttpRedirectTest3, Redirect_Online) {
|
||||
SSLClient cli("nghttp2.org");
|
||||
cli.set_follow_location(true);
|
||||
|
||||
@@ -839,55 +839,62 @@ TEST(HttpsToHttpRedirectTest3, Redirect) {
|
||||
EXPECT_EQ(200, res->status);
|
||||
}
|
||||
|
||||
TEST(UrlWithSpace, Redirect) {
|
||||
TEST(UrlWithSpace, Redirect_Online) {
|
||||
SSLClient cli("edge.forgecdn.net");
|
||||
cli.set_follow_location(true);
|
||||
|
||||
auto res = cli.Get("/files/2595/310/Neat 1.4-17.jar");
|
||||
ASSERT_TRUE(res);
|
||||
EXPECT_EQ(200, res->status);
|
||||
EXPECT_EQ(18527, res->get_header_value<uint64_t>("Content-Length"));
|
||||
EXPECT_EQ(18527U, res->get_header_value<uint64_t>("Content-Length"));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
TEST(RedirectToDifferentPort, Redirect) {
|
||||
Server svr8080;
|
||||
Server svr8081;
|
||||
|
||||
svr8080.Get("/1", [&](const Request & /*req*/, Response &res) {
|
||||
res.set_redirect("http://localhost:8081/2");
|
||||
});
|
||||
|
||||
svr8081.Get("/2", [&](const Request & /*req*/, Response &res) {
|
||||
Server svr1;
|
||||
svr1.Get("/1", [&](const Request & /*req*/, Response &res) {
|
||||
res.set_content("Hello World!", "text/plain");
|
||||
});
|
||||
|
||||
auto thread8080 = std::thread([&]() { svr8080.listen("localhost", 8080); });
|
||||
int svr1_port = 0;
|
||||
auto thread1 = std::thread([&]() {
|
||||
svr1_port = svr1.bind_to_any_port("localhost");
|
||||
svr1.listen_after_bind();
|
||||
});
|
||||
|
||||
auto thread8081 = std::thread([&]() { svr8081.listen("localhost", 8081); });
|
||||
Server svr2;
|
||||
svr2.Get("/2", [&](const Request & /*req*/, Response &res) {
|
||||
res.set_redirect("http://localhost:" + std::to_string(svr1_port) + "/1");
|
||||
});
|
||||
|
||||
while (!svr8080.is_running() || !svr8081.is_running()) {
|
||||
int svr2_port = 0;
|
||||
auto thread2 = std::thread([&]() {
|
||||
svr2_port = svr2.bind_to_any_port("localhost");
|
||||
svr2.listen_after_bind();
|
||||
});
|
||||
|
||||
while (!svr1.is_running() || !svr2.is_running()) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
|
||||
// Give GET time to get a few messages.
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
|
||||
Client cli("localhost", 8080);
|
||||
Client cli("localhost", svr2_port);
|
||||
cli.set_follow_location(true);
|
||||
|
||||
auto res = cli.Get("/1");
|
||||
auto res = cli.Get("/2");
|
||||
ASSERT_TRUE(res);
|
||||
EXPECT_EQ(200, res->status);
|
||||
EXPECT_EQ("Hello World!", res->body);
|
||||
|
||||
svr8080.stop();
|
||||
svr8081.stop();
|
||||
thread8080.join();
|
||||
thread8081.join();
|
||||
ASSERT_FALSE(svr8080.is_running());
|
||||
ASSERT_FALSE(svr8081.is_running());
|
||||
svr1.stop();
|
||||
svr2.stop();
|
||||
thread1.join();
|
||||
thread2.join();
|
||||
ASSERT_FALSE(svr1.is_running());
|
||||
ASSERT_FALSE(svr2.is_running());
|
||||
}
|
||||
|
||||
TEST(RedirectFromPageWithContent, Redirect) {
|
||||
@@ -954,7 +961,11 @@ TEST(RedirectFromPageWithContentIP6, Redirect) {
|
||||
res.set_redirect("http://[::1]:1234/2");
|
||||
});
|
||||
|
||||
svr.Get("/2", [&](const Request & /*req*/, Response &res) {
|
||||
svr.Get("/2", [&](const Request &req, Response &res) {
|
||||
auto host_header = req.headers.find("Host");
|
||||
ASSERT_TRUE(host_header != req.headers.end());
|
||||
EXPECT_EQ("[::1]:1234", host_header->second);
|
||||
|
||||
res.set_content("Hello World!", "text/plain");
|
||||
});
|
||||
|
||||
@@ -1222,9 +1233,9 @@ TEST(RoutingHandlerTest, PreRoutingHandler) {
|
||||
ASSERT_TRUE(res);
|
||||
EXPECT_EQ(200, res->status);
|
||||
EXPECT_EQ("Routing Handler", res->body);
|
||||
EXPECT_EQ(1, res->get_header_value_count("PRE_ROUTING"));
|
||||
EXPECT_EQ(1U, res->get_header_value_count("PRE_ROUTING"));
|
||||
EXPECT_EQ("on", res->get_header_value("PRE_ROUTING"));
|
||||
EXPECT_EQ(1, res->get_header_value_count("POST_ROUTING"));
|
||||
EXPECT_EQ(1U, res->get_header_value_count("POST_ROUTING"));
|
||||
EXPECT_EQ("on", res->get_header_value("POST_ROUTING"));
|
||||
}
|
||||
|
||||
@@ -1235,8 +1246,8 @@ TEST(RoutingHandlerTest, PreRoutingHandler) {
|
||||
ASSERT_TRUE(res);
|
||||
EXPECT_EQ(200, res->status);
|
||||
EXPECT_EQ("Hello World!\n", res->body);
|
||||
EXPECT_EQ(0, res->get_header_value_count("PRE_ROUTING"));
|
||||
EXPECT_EQ(0, res->get_header_value_count("POST_ROUTING"));
|
||||
EXPECT_EQ(0U, res->get_header_value_count("PRE_ROUTING"));
|
||||
EXPECT_EQ(0U, res->get_header_value_count("POST_ROUTING"));
|
||||
}
|
||||
|
||||
{
|
||||
@@ -1246,8 +1257,8 @@ TEST(RoutingHandlerTest, PreRoutingHandler) {
|
||||
ASSERT_TRUE(res);
|
||||
EXPECT_EQ(404, res->status);
|
||||
EXPECT_EQ("Error", res->body);
|
||||
EXPECT_EQ(0, res->get_header_value_count("PRE_ROUTING"));
|
||||
EXPECT_EQ(0, res->get_header_value_count("POST_ROUTING"));
|
||||
EXPECT_EQ(0U, res->get_header_value_count("PRE_ROUTING"));
|
||||
EXPECT_EQ(0U, res->get_header_value_count("POST_ROUTING"));
|
||||
}
|
||||
|
||||
svr.stop();
|
||||
@@ -1306,31 +1317,31 @@ protected:
|
||||
.Get("/http_response_splitting",
|
||||
[&](const Request & /*req*/, Response &res) {
|
||||
res.set_header("a", "1\r\nSet-Cookie: a=1");
|
||||
EXPECT_EQ(0, res.headers.size());
|
||||
EXPECT_EQ(0U, res.headers.size());
|
||||
EXPECT_FALSE(res.has_header("a"));
|
||||
|
||||
res.set_header("a", "1\nSet-Cookie: a=1");
|
||||
EXPECT_EQ(0, res.headers.size());
|
||||
EXPECT_EQ(0U, res.headers.size());
|
||||
EXPECT_FALSE(res.has_header("a"));
|
||||
|
||||
res.set_header("a", "1\rSet-Cookie: a=1");
|
||||
EXPECT_EQ(0, res.headers.size());
|
||||
EXPECT_EQ(0U, res.headers.size());
|
||||
EXPECT_FALSE(res.has_header("a"));
|
||||
|
||||
res.set_header("a\r\nb", "0");
|
||||
EXPECT_EQ(0, res.headers.size());
|
||||
EXPECT_EQ(0U, res.headers.size());
|
||||
EXPECT_FALSE(res.has_header("a"));
|
||||
|
||||
res.set_header("a\rb", "0");
|
||||
EXPECT_EQ(0, res.headers.size());
|
||||
EXPECT_EQ(0U, res.headers.size());
|
||||
EXPECT_FALSE(res.has_header("a"));
|
||||
|
||||
res.set_header("a\nb", "0");
|
||||
EXPECT_EQ(0, res.headers.size());
|
||||
EXPECT_EQ(0U, res.headers.size());
|
||||
EXPECT_FALSE(res.has_header("a"));
|
||||
|
||||
res.set_redirect("1\r\nSet-Cookie: a=1");
|
||||
EXPECT_EQ(0, res.headers.size());
|
||||
EXPECT_EQ(0U, res.headers.size());
|
||||
EXPECT_FALSE(res.has_header("Location"));
|
||||
})
|
||||
.Get("/slow",
|
||||
@@ -1648,7 +1659,7 @@ protected:
|
||||
} else {
|
||||
std::string body;
|
||||
content_reader([&](const char *data, size_t data_length) {
|
||||
EXPECT_EQ(data_length, 7);
|
||||
EXPECT_EQ(7U, data_length);
|
||||
body.append(data, data_length);
|
||||
return true;
|
||||
});
|
||||
@@ -1696,7 +1707,7 @@ protected:
|
||||
})
|
||||
.Post("/binary",
|
||||
[&](const Request &req, Response &res) {
|
||||
EXPECT_EQ(4, req.body.size());
|
||||
EXPECT_EQ(4U, req.body.size());
|
||||
EXPECT_EQ("application/octet-stream",
|
||||
req.get_header_value("Content-Type"));
|
||||
EXPECT_EQ("4", req.get_header_value("Content-Length"));
|
||||
@@ -1704,7 +1715,7 @@ protected:
|
||||
})
|
||||
.Put("/binary",
|
||||
[&](const Request &req, Response &res) {
|
||||
EXPECT_EQ(4, req.body.size());
|
||||
EXPECT_EQ(4U, req.body.size());
|
||||
EXPECT_EQ("application/octet-stream",
|
||||
req.get_header_value("Content-Type"));
|
||||
EXPECT_EQ("4", req.get_header_value("Content-Length"));
|
||||
@@ -1712,7 +1723,7 @@ protected:
|
||||
})
|
||||
.Patch("/binary",
|
||||
[&](const Request &req, Response &res) {
|
||||
EXPECT_EQ(4, req.body.size());
|
||||
EXPECT_EQ(4U, req.body.size());
|
||||
EXPECT_EQ("application/octet-stream",
|
||||
req.get_header_value("Content-Type"));
|
||||
EXPECT_EQ("4", req.get_header_value("Content-Length"));
|
||||
@@ -1720,7 +1731,7 @@ protected:
|
||||
})
|
||||
.Delete("/binary",
|
||||
[&](const Request &req, Response &res) {
|
||||
EXPECT_EQ(4, req.body.size());
|
||||
EXPECT_EQ(4U, req.body.size());
|
||||
EXPECT_EQ("application/octet-stream",
|
||||
req.get_header_value("Content-Type"));
|
||||
EXPECT_EQ("4", req.get_header_value("Content-Length"));
|
||||
@@ -1800,7 +1811,7 @@ TEST_F(ServerTest, GetMethod200) {
|
||||
EXPECT_EQ(200, res->status);
|
||||
EXPECT_EQ("OK", res->reason);
|
||||
EXPECT_EQ("text/plain", res->get_header_value("Content-Type"));
|
||||
EXPECT_EQ(1, res->get_header_value_count("Content-Type"));
|
||||
EXPECT_EQ(1U, res->get_header_value_count("Content-Type"));
|
||||
EXPECT_EQ("Hello World!", res->body);
|
||||
}
|
||||
|
||||
@@ -1810,7 +1821,7 @@ TEST_F(ServerTest, GetMethod200withPercentEncoding) {
|
||||
EXPECT_EQ("HTTP/1.1", res->version);
|
||||
EXPECT_EQ(200, res->status);
|
||||
EXPECT_EQ("text/plain", res->get_header_value("Content-Type"));
|
||||
EXPECT_EQ(1, res->get_header_value_count("Content-Type"));
|
||||
EXPECT_EQ(1U, res->get_header_value_count("Content-Type"));
|
||||
EXPECT_EQ("Hello World!", res->body);
|
||||
}
|
||||
|
||||
@@ -2088,25 +2099,25 @@ TEST_F(ServerTest, Binary) {
|
||||
"application/octet-stream");
|
||||
ASSERT_TRUE(res);
|
||||
ASSERT_EQ(200, res->status);
|
||||
ASSERT_EQ(4, res->body.size());
|
||||
ASSERT_EQ(4U, res->body.size());
|
||||
|
||||
res = cli_.Put("/binary", binary.data(), binary.size(),
|
||||
"application/octet-stream");
|
||||
ASSERT_TRUE(res);
|
||||
ASSERT_EQ(200, res->status);
|
||||
ASSERT_EQ(4, res->body.size());
|
||||
ASSERT_EQ(4U, res->body.size());
|
||||
|
||||
res = cli_.Patch("/binary", binary.data(), binary.size(),
|
||||
"application/octet-stream");
|
||||
ASSERT_TRUE(res);
|
||||
ASSERT_EQ(200, res->status);
|
||||
ASSERT_EQ(4, res->body.size());
|
||||
ASSERT_EQ(4U, res->body.size());
|
||||
|
||||
res = cli_.Delete("/binary", binary.data(), binary.size(),
|
||||
"application/octet-stream");
|
||||
ASSERT_TRUE(res);
|
||||
ASSERT_EQ(200, res->status);
|
||||
ASSERT_EQ(4, res->body.size());
|
||||
ASSERT_EQ(4U, res->body.size());
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, BinaryString) {
|
||||
@@ -2115,22 +2126,22 @@ TEST_F(ServerTest, BinaryString) {
|
||||
auto res = cli_.Post("/binary", binary, "application/octet-stream");
|
||||
ASSERT_TRUE(res);
|
||||
ASSERT_EQ(200, res->status);
|
||||
ASSERT_EQ(4, res->body.size());
|
||||
ASSERT_EQ(4U, res->body.size());
|
||||
|
||||
res = cli_.Put("/binary", binary, "application/octet-stream");
|
||||
ASSERT_TRUE(res);
|
||||
ASSERT_EQ(200, res->status);
|
||||
ASSERT_EQ(4, res->body.size());
|
||||
ASSERT_EQ(4U, res->body.size());
|
||||
|
||||
res = cli_.Patch("/binary", binary, "application/octet-stream");
|
||||
ASSERT_TRUE(res);
|
||||
ASSERT_EQ(200, res->status);
|
||||
ASSERT_EQ(4, res->body.size());
|
||||
ASSERT_EQ(4U, res->body.size());
|
||||
|
||||
res = cli_.Delete("/binary", binary, "application/octet-stream");
|
||||
ASSERT_TRUE(res);
|
||||
ASSERT_EQ(200, res->status);
|
||||
ASSERT_EQ(4, res->body.size());
|
||||
ASSERT_EQ(4U, res->body.size());
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, EmptyRequest) {
|
||||
@@ -2446,7 +2457,7 @@ TEST_F(ServerTest, GetStreamedWithRangeMultipart) {
|
||||
EXPECT_EQ(206, res->status);
|
||||
EXPECT_EQ("269", res->get_header_value("Content-Length"));
|
||||
EXPECT_EQ(false, res->has_header("Content-Range"));
|
||||
EXPECT_EQ(269, res->body.size());
|
||||
EXPECT_EQ(269U, res->body.size());
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, GetStreamedEndless) {
|
||||
@@ -2533,7 +2544,7 @@ TEST_F(ServerTest, GetWithRangeMultipart) {
|
||||
EXPECT_EQ(206, res->status);
|
||||
EXPECT_EQ("269", res->get_header_value("Content-Length"));
|
||||
EXPECT_EQ(false, res->has_header("Content-Range"));
|
||||
EXPECT_EQ(269, res->body.size());
|
||||
EXPECT_EQ(269U, res->body.size());
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, GetWithRangeMultipartOffsetGreaterThanContent) {
|
||||
@@ -2864,6 +2875,54 @@ TEST(GzipDecompressor, ChunkedDecompression) {
|
||||
}
|
||||
ASSERT_EQ(data, decompressed_data);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
TEST(GzipDecompressor, LargeRandomData) {
|
||||
|
||||
// prepare large random data that is difficult to be compressed and is
|
||||
// expected to have large size even when compressed
|
||||
std::random_device seed_gen;
|
||||
std::mt19937 random(seed_gen());
|
||||
constexpr auto large_size_byte = 4294967296UL; // 4GiB
|
||||
constexpr auto data_size = large_size_byte + 134217728UL; // + 128MiB
|
||||
std::vector<std::uint32_t> data(data_size / sizeof(std::uint32_t));
|
||||
std::generate(data.begin(), data.end(), [&]() { return random(); });
|
||||
|
||||
// compress data over 4GiB
|
||||
std::string compressed_data;
|
||||
compressed_data.reserve(large_size_byte + 536870912UL); // + 512MiB reserved
|
||||
httplib::detail::gzip_compressor compressor;
|
||||
auto result = compressor.compress(reinterpret_cast<const char *>(data.data()),
|
||||
data.size() * sizeof(std::uint32_t), true,
|
||||
[&](const char *data, size_t size) {
|
||||
compressed_data.insert(
|
||||
compressed_data.size(), data, size);
|
||||
return true;
|
||||
});
|
||||
ASSERT_TRUE(result);
|
||||
|
||||
// FIXME: compressed data size is expected to be greater than 4GiB,
|
||||
// but there is no guarantee
|
||||
// ASSERT_TRUE(compressed_data.size() >= large_size_byte);
|
||||
|
||||
// decompress data over 4GiB
|
||||
std::string decompressed_data;
|
||||
decompressed_data.reserve(data_size);
|
||||
httplib::detail::gzip_decompressor decompressor;
|
||||
result = decompressor.decompress(
|
||||
compressed_data.data(), compressed_data.size(),
|
||||
[&](const char *data, size_t size) {
|
||||
decompressed_data.insert(decompressed_data.size(), data, size);
|
||||
return true;
|
||||
});
|
||||
ASSERT_TRUE(result);
|
||||
|
||||
// compare
|
||||
ASSERT_EQ(data_size, decompressed_data.size());
|
||||
ASSERT_TRUE(std::memcmp(data.data(), decompressed_data.data(), data_size) ==
|
||||
0);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CPPHTTPLIB_BROTLI_SUPPORT
|
||||
@@ -3124,7 +3183,7 @@ TEST_F(ServerTest, GzipWithContentReceiver) {
|
||||
std::string body;
|
||||
auto res = cli_.Get("/compress", headers,
|
||||
[&](const char *data, uint64_t data_length) {
|
||||
EXPECT_EQ(data_length, 100);
|
||||
EXPECT_EQ(100U, data_length);
|
||||
body.append(data, data_length);
|
||||
return true;
|
||||
});
|
||||
@@ -3150,14 +3209,14 @@ TEST_F(ServerTest, GzipWithoutDecompressing) {
|
||||
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(33, res->body.size());
|
||||
EXPECT_EQ(33U, res->body.size());
|
||||
EXPECT_EQ(200, res->status);
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, GzipWithContentReceiverWithoutAcceptEncoding) {
|
||||
std::string body;
|
||||
auto res = cli_.Get("/compress", [&](const char *data, uint64_t data_length) {
|
||||
EXPECT_EQ(data_length, 100);
|
||||
EXPECT_EQ(100U, data_length);
|
||||
body.append(data, data_length);
|
||||
return true;
|
||||
});
|
||||
@@ -3193,7 +3252,7 @@ TEST_F(ServerTest, NoGzipWithContentReceiver) {
|
||||
std::string body;
|
||||
auto res = cli_.Get("/nocompress", headers,
|
||||
[&](const char *data, uint64_t data_length) {
|
||||
EXPECT_EQ(data_length, 100);
|
||||
EXPECT_EQ(100U, data_length);
|
||||
body.append(data, data_length);
|
||||
return true;
|
||||
});
|
||||
@@ -3289,14 +3348,14 @@ TEST(ServerRequestParsingTest, TrimWhitespaceFromHeaderValues) {
|
||||
// Only space and horizontal tab are whitespace. Make sure other whitespace-
|
||||
// like characters are not treated the same - use vertical tab and escape.
|
||||
const std::string req = "GET /validate-ws-in-headers HTTP/1.1\r\n"
|
||||
"foo: \t \v bar \e\t \r\n"
|
||||
"foo: \t \v bar \x1B\t \r\n"
|
||||
"Connection: close\r\n"
|
||||
"\r\n";
|
||||
|
||||
ASSERT_TRUE(send_request(5, req));
|
||||
svr.stop();
|
||||
t.join();
|
||||
EXPECT_EQ(header_value, "\v bar \e");
|
||||
EXPECT_EQ(header_value, "\v bar \x1B");
|
||||
}
|
||||
|
||||
// Sends a raw request and verifies that there isn't a crash or exception.
|
||||
@@ -3448,7 +3507,7 @@ TEST(ServerStopTest, StopServerWithChunkedTransmission) {
|
||||
res.set_chunked_content_provider("text/event-stream", [](size_t offset,
|
||||
DataSink &sink) {
|
||||
char buffer[27];
|
||||
auto size = static_cast<size_t>(sprintf(buffer, "data:%ld\n\n", offset));
|
||||
auto size = static_cast<size_t>(sprintf(buffer, "data:%zd\n\n", offset));
|
||||
auto ret = sink.write(buffer, size);
|
||||
EXPECT_TRUE(ret);
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
@@ -3705,19 +3764,19 @@ TEST(ErrorHandlerWithContentProviderTest, ErrorHandler) {
|
||||
TEST(GetWithParametersTest, GetWithParameters) {
|
||||
Server svr;
|
||||
|
||||
svr.Get("/", [&](const Request &req, Response &res) {
|
||||
svr.Get("/", [&](const Request &req, Response &) {
|
||||
EXPECT_EQ("world", req.get_param_value("hello"));
|
||||
EXPECT_EQ("world2", req.get_param_value("hello2"));
|
||||
EXPECT_EQ("world3", req.get_param_value("hello3"));
|
||||
});
|
||||
|
||||
svr.Get("/params", [&](const Request &req, Response &res) {
|
||||
svr.Get("/params", [&](const Request &req, Response &) {
|
||||
EXPECT_EQ("world", req.get_param_value("hello"));
|
||||
EXPECT_EQ("world2", req.get_param_value("hello2"));
|
||||
EXPECT_EQ("world3", req.get_param_value("hello3"));
|
||||
});
|
||||
|
||||
svr.Get(R"(/resources/([a-z0-9\\-]+))", [&](const Request& req, Response& res) {
|
||||
svr.Get(R"(/resources/([a-z0-9\\-]+))", [&](const Request &req, Response &) {
|
||||
EXPECT_EQ("resource-id", req.matches[1]);
|
||||
EXPECT_EQ("foo", req.get_param_value("param1"));
|
||||
EXPECT_EQ("bar", req.get_param_value("param2"));
|
||||
@@ -3800,7 +3859,7 @@ TEST(GetWithParametersTest, GetWithParameters2) {
|
||||
ASSERT_FALSE(svr.is_running());
|
||||
}
|
||||
|
||||
TEST(ClientDefaultHeadersTest, DefaultHeaders) {
|
||||
TEST(ClientDefaultHeadersTest, DefaultHeaders_Online) {
|
||||
Client cli("httpbin.org");
|
||||
cli.set_default_headers({make_range_header({{1, 10}})});
|
||||
cli.set_connection_timeout(5);
|
||||
@@ -4037,21 +4096,21 @@ TEST(SSLClientTest, UpdateCAStore) {
|
||||
httplib_client.set_ca_cert_store(ca_store_2);
|
||||
}
|
||||
|
||||
TEST(SSLClientTest, ServerNameIndication) {
|
||||
TEST(SSLClientTest, ServerNameIndication_Online) {
|
||||
SSLClient cli("httpbin.org", 443);
|
||||
auto res = cli.Get("/get");
|
||||
ASSERT_TRUE(res);
|
||||
ASSERT_EQ(200, res->status);
|
||||
}
|
||||
|
||||
TEST(SSLClientTest, ServerCertificateVerification1) {
|
||||
TEST(SSLClientTest, ServerCertificateVerification1_Online) {
|
||||
SSLClient cli("google.com");
|
||||
auto res = cli.Get("/");
|
||||
ASSERT_TRUE(res);
|
||||
ASSERT_EQ(301, res->status);
|
||||
}
|
||||
|
||||
TEST(SSLClientTest, ServerCertificateVerification2) {
|
||||
TEST(SSLClientTest, ServerCertificateVerification2_Online) {
|
||||
SSLClient cli("google.com");
|
||||
cli.enable_server_certificate_verification(true);
|
||||
cli.set_ca_cert_path("hello");
|
||||
@@ -4060,7 +4119,7 @@ TEST(SSLClientTest, ServerCertificateVerification2) {
|
||||
EXPECT_EQ(Error::SSLLoadingCerts, res.error());
|
||||
}
|
||||
|
||||
TEST(SSLClientTest, ServerCertificateVerification3) {
|
||||
TEST(SSLClientTest, ServerCertificateVerification3_Online) {
|
||||
SSLClient cli("google.com");
|
||||
cli.set_ca_cert_path(CA_CERT_FILE);
|
||||
auto res = cli.Get("/");
|
||||
@@ -4093,7 +4152,7 @@ TEST(SSLClientTest, ServerCertificateVerification4) {
|
||||
t.join();
|
||||
}
|
||||
|
||||
TEST(SSLClientTest, WildcardHostNameMatch) {
|
||||
TEST(SSLClientTest, WildcardHostNameMatch_Online) {
|
||||
SSLClient cli("www.youtube.com");
|
||||
|
||||
cli.set_ca_cert_path(CA_CERT_FILE);
|
||||
@@ -4338,7 +4397,7 @@ TEST(NoScheme, SimpleInterface) {
|
||||
ASSERT_TRUE(cli.is_valid());
|
||||
}
|
||||
|
||||
TEST(SendAPI, SimpleInterface) {
|
||||
TEST(SendAPI, SimpleInterface_Online) {
|
||||
Client cli("http://yahoo.com");
|
||||
|
||||
Request req;
|
||||
@@ -4351,7 +4410,7 @@ TEST(SendAPI, SimpleInterface) {
|
||||
}
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
TEST(YahooRedirectTest2, SimpleInterface) {
|
||||
TEST(YahooRedirectTest2, SimpleInterface_Online) {
|
||||
Client cli("http://yahoo.com");
|
||||
|
||||
auto res = cli.Get("/");
|
||||
@@ -4365,7 +4424,7 @@ TEST(YahooRedirectTest2, SimpleInterface) {
|
||||
EXPECT_EQ("https://yahoo.com/", res->location);
|
||||
}
|
||||
|
||||
TEST(YahooRedirectTest3, SimpleInterface) {
|
||||
TEST(YahooRedirectTest3, SimpleInterface_Online) {
|
||||
Client cli("https://yahoo.com");
|
||||
|
||||
auto res = cli.Get("/");
|
||||
@@ -4379,7 +4438,7 @@ TEST(YahooRedirectTest3, SimpleInterface) {
|
||||
EXPECT_EQ("https://www.yahoo.com/", res->location);
|
||||
}
|
||||
|
||||
TEST(YahooRedirectTest3, NewResultInterface) {
|
||||
TEST(YahooRedirectTest3, NewResultInterface_Online) {
|
||||
Client cli("https://yahoo.com");
|
||||
|
||||
auto res = cli.Get("/");
|
||||
@@ -4404,20 +4463,20 @@ TEST(YahooRedirectTest3, NewResultInterface) {
|
||||
}
|
||||
|
||||
#ifdef CPPHTTPLIB_BROTLI_SUPPORT
|
||||
TEST(DecodeWithChunkedEncoding, BrotliEncoding) {
|
||||
TEST(DecodeWithChunkedEncoding, BrotliEncoding_Online) {
|
||||
Client cli("https://cdnjs.cloudflare.com");
|
||||
auto res =
|
||||
cli.Get("/ajax/libs/jquery/3.5.1/jquery.js", {{"Accept-Encoding", "br"}});
|
||||
|
||||
ASSERT_TRUE(res);
|
||||
EXPECT_EQ(200, res->status);
|
||||
EXPECT_EQ(287630, res->body.size());
|
||||
EXPECT_EQ(287630U, res->body.size());
|
||||
EXPECT_EQ("application/javascript; charset=utf-8",
|
||||
res->get_header_value("Content-Type"));
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(HttpsToHttpRedirectTest, SimpleInterface) {
|
||||
TEST(HttpsToHttpRedirectTest, SimpleInterface_Online) {
|
||||
Client cli("https://nghttp2.org");
|
||||
cli.set_follow_location(true);
|
||||
auto res =
|
||||
@@ -4428,7 +4487,7 @@ TEST(HttpsToHttpRedirectTest, SimpleInterface) {
|
||||
EXPECT_EQ(200, res->status);
|
||||
}
|
||||
|
||||
TEST(HttpsToHttpRedirectTest2, SimpleInterface) {
|
||||
TEST(HttpsToHttpRedirectTest2, SimpleInterface_Online) {
|
||||
Client cli("https://nghttp2.org");
|
||||
cli.set_follow_location(true);
|
||||
|
||||
@@ -4441,7 +4500,7 @@ TEST(HttpsToHttpRedirectTest2, SimpleInterface) {
|
||||
EXPECT_EQ(200, res->status);
|
||||
}
|
||||
|
||||
TEST(HttpsToHttpRedirectTest3, SimpleInterface) {
|
||||
TEST(HttpsToHttpRedirectTest3, SimpleInterface_Online) {
|
||||
Client cli("https://nghttp2.org");
|
||||
cli.set_follow_location(true);
|
||||
|
||||
@@ -4452,4 +4511,37 @@ TEST(HttpsToHttpRedirectTest3, SimpleInterface) {
|
||||
ASSERT_TRUE(res);
|
||||
EXPECT_EQ(200, res->status);
|
||||
}
|
||||
|
||||
TEST(HttpToHttpsRedirectTest, CertFile) {
|
||||
Server svr;
|
||||
ASSERT_TRUE(svr.is_valid());
|
||||
svr.Get("/index", [&](const Request &, Response &res) {
|
||||
res.set_redirect("https://127.0.0.1:1235/index");
|
||||
svr.stop();
|
||||
});
|
||||
|
||||
SSLServer ssl_svr(SERVER_CERT2_FILE, SERVER_PRIVATE_KEY_FILE);
|
||||
ASSERT_TRUE(ssl_svr.is_valid());
|
||||
ssl_svr.Get("/index", [&](const Request &, Response &res) {
|
||||
res.set_content("test", "text/plain");
|
||||
ssl_svr.stop();
|
||||
});
|
||||
|
||||
thread t = thread([&]() { ASSERT_TRUE(svr.listen("127.0.0.1", PORT)); });
|
||||
thread t2 = thread([&]() { ASSERT_TRUE(ssl_svr.listen("127.0.0.1", 1235)); });
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
|
||||
Client cli("127.0.0.1", PORT);
|
||||
cli.set_ca_cert_path(SERVER_CERT2_FILE);
|
||||
cli.enable_server_certificate_verification(true);
|
||||
cli.set_follow_location(true);
|
||||
cli.set_connection_timeout(30);
|
||||
|
||||
auto res = cli.Get("/index");
|
||||
ASSERT_TRUE(res);
|
||||
ASSERT_EQ(200, res->status);
|
||||
|
||||
t.join();
|
||||
t2.join();
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user