Fix #979
This commit is contained in:
parent
3d83cbb872
commit
06bfa7e08b
13
httplib.h
13
httplib.h
@ -5611,7 +5611,7 @@ inline bool ClientImpl::redirect(Request &req, Response &res, Error &error) {
|
|||||||
if (location.empty()) { return false; }
|
if (location.empty()) { return false; }
|
||||||
|
|
||||||
const static std::regex re(
|
const static std::regex re(
|
||||||
R"(^(?:(https?):)?(?://([^:/?#]*)(?::(\d+))?)?([^?#]*(?:\?[^#]*)?)(?:#.*)?)");
|
R"((?:(https?):)?(?://(?:\[([\d:]+)\]|([^:/?#]+))(?::(\d+))?)?([^?#]*(?:\?[^#]*)?)(?:#.*)?)");
|
||||||
|
|
||||||
std::smatch m;
|
std::smatch m;
|
||||||
if (!std::regex_match(location, m, re)) { return false; }
|
if (!std::regex_match(location, m, re)) { return false; }
|
||||||
@ -5620,8 +5620,9 @@ inline bool ClientImpl::redirect(Request &req, Response &res, Error &error) {
|
|||||||
|
|
||||||
auto next_scheme = m[1].str();
|
auto next_scheme = m[1].str();
|
||||||
auto next_host = m[2].str();
|
auto next_host = m[2].str();
|
||||||
auto port_str = m[3].str();
|
if (next_host.empty()) { next_host = m[3].str(); }
|
||||||
auto next_path = m[4].str();
|
auto port_str = m[4].str();
|
||||||
|
auto next_path = m[5].str();
|
||||||
|
|
||||||
auto next_port = port_;
|
auto next_port = port_;
|
||||||
if (!port_str.empty()) {
|
if (!port_str.empty()) {
|
||||||
@ -7266,7 +7267,8 @@ inline Client::Client(const char *scheme_host_port)
|
|||||||
inline Client::Client(const char *scheme_host_port,
|
inline Client::Client(const char *scheme_host_port,
|
||||||
const std::string &client_cert_path,
|
const std::string &client_cert_path,
|
||||||
const std::string &client_key_path) {
|
const std::string &client_key_path) {
|
||||||
const static std::regex re(R"(^(?:([a-z]+)://)?([^:/?#]+)(?::(\d+))?)");
|
const static std::regex re(
|
||||||
|
R"((?:([a-z]+):\/\/)?(?:\[([\d:]+)\]|([^:/?#]+))(?::(\d+))?)");
|
||||||
|
|
||||||
std::cmatch m;
|
std::cmatch m;
|
||||||
if (std::regex_match(scheme_host_port, m, re)) {
|
if (std::regex_match(scheme_host_port, m, re)) {
|
||||||
@ -7285,8 +7287,9 @@ inline Client::Client(const char *scheme_host_port,
|
|||||||
auto is_ssl = scheme == "https";
|
auto is_ssl = scheme == "https";
|
||||||
|
|
||||||
auto host = m[2].str();
|
auto host = m[2].str();
|
||||||
|
if (host.empty()) { host = m[3].str(); }
|
||||||
|
|
||||||
auto port_str = m[3].str();
|
auto port_str = m[4].str();
|
||||||
auto port = !port_str.empty() ? std::stoi(port_str) : (is_ssl ? 443 : 80);
|
auto port = !port_str.empty() ? std::stoi(port_str) : (is_ssl ? 443 : 80);
|
||||||
|
|
||||||
if (is_ssl) {
|
if (is_ssl) {
|
||||||
|
84
test/test.cc
84
test/test.cc
@ -839,6 +839,18 @@ TEST(HttpsToHttpRedirectTest3, Redirect) {
|
|||||||
EXPECT_EQ(200, res->status);
|
EXPECT_EQ(200, res->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(UrlWithSpace, Redirect) {
|
||||||
|
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"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
TEST(RedirectToDifferentPort, Redirect) {
|
TEST(RedirectToDifferentPort, Redirect) {
|
||||||
Server svr8080;
|
Server svr8080;
|
||||||
Server svr8081;
|
Server svr8081;
|
||||||
@ -878,16 +890,6 @@ TEST(RedirectToDifferentPort, Redirect) {
|
|||||||
ASSERT_FALSE(svr8081.is_running());
|
ASSERT_FALSE(svr8081.is_running());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(UrlWithSpace, Redirect) {
|
|
||||||
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"));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(RedirectFromPageWithContent, Redirect) {
|
TEST(RedirectFromPageWithContent, Redirect) {
|
||||||
Server svr;
|
Server svr;
|
||||||
|
|
||||||
@ -943,7 +945,61 @@ TEST(RedirectFromPageWithContent, Redirect) {
|
|||||||
ASSERT_FALSE(svr.is_running());
|
ASSERT_FALSE(svr.is_running());
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
TEST(RedirectFromPageWithContentIP6, Redirect) {
|
||||||
|
Server svr;
|
||||||
|
|
||||||
|
svr.Get("/1", [&](const Request & /*req*/, Response &res) {
|
||||||
|
res.set_content("___", "text/plain");
|
||||||
|
// res.set_redirect("/2");
|
||||||
|
res.set_redirect("http://[::1]:1234/2");
|
||||||
|
});
|
||||||
|
|
||||||
|
svr.Get("/2", [&](const Request & /*req*/, Response &res) {
|
||||||
|
res.set_content("Hello World!", "text/plain");
|
||||||
|
});
|
||||||
|
|
||||||
|
auto th = std::thread([&]() { svr.listen("::1", 1234); });
|
||||||
|
|
||||||
|
while (!svr.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("http://[::1]:1234");
|
||||||
|
cli.set_follow_location(true);
|
||||||
|
|
||||||
|
std::string body;
|
||||||
|
auto res = cli.Get("/1", [&](const char *data, size_t data_length) {
|
||||||
|
body.append(data, data_length);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
ASSERT_TRUE(res);
|
||||||
|
EXPECT_EQ(200, res->status);
|
||||||
|
EXPECT_EQ("Hello World!", body);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Client cli("http://[::1]:1234");
|
||||||
|
|
||||||
|
std::string body;
|
||||||
|
auto res = cli.Get("/1", [&](const char *data, size_t data_length) {
|
||||||
|
body.append(data, data_length);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
ASSERT_TRUE(res);
|
||||||
|
EXPECT_EQ(302, res->status);
|
||||||
|
EXPECT_EQ("___", body);
|
||||||
|
}
|
||||||
|
|
||||||
|
svr.stop();
|
||||||
|
th.join();
|
||||||
|
ASSERT_FALSE(svr.is_running());
|
||||||
|
}
|
||||||
|
|
||||||
TEST(PathUrlEncodeTest, PathUrlEncode) {
|
TEST(PathUrlEncodeTest, PathUrlEncode) {
|
||||||
Server svr;
|
Server svr;
|
||||||
@ -2717,10 +2773,12 @@ TEST_F(ServerTest, PutLargeFileWithGzip) {
|
|||||||
|
|
||||||
TEST_F(ServerTest, PutLargeFileWithGzip2) {
|
TEST_F(ServerTest, PutLargeFileWithGzip2) {
|
||||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||||
Client cli("https://localhost:1234");
|
std::string s = std::string("https://") + HOST + ":" + std::to_string(PORT);
|
||||||
|
Client cli(s.c_str());
|
||||||
cli.enable_server_certificate_verification(false);
|
cli.enable_server_certificate_verification(false);
|
||||||
#else
|
#else
|
||||||
Client cli("http://localhost:1234");
|
std::string s = std::string("http://") + HOST + ":" + std::to_string(PORT);
|
||||||
|
Client cli(s.c_str());
|
||||||
#endif
|
#endif
|
||||||
cli.set_compress(true);
|
cli.set_compress(true);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user