Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
yhirose committed Jul 15, 2021
1 parent 3d83cbb commit 06bfa7e
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 18 deletions.
13 changes: 8 additions & 5 deletions httplib.h
Original file line number Diff line number Diff line change
Expand Up @@ -5611,7 +5611,7 @@ inline bool ClientImpl::redirect(Request &req, Response &res, Error &error) {
if (location.empty()) { return false; }

const static std::regex re(
R"(^(?:(https?):)?(?://([^:/?#]*)(?::(\d+))?)?([^?#]*(?:\?[^#]*)?)(?:#.*)?)");
R"((?:(https?):)?(?://(?:\[([\d:]+)\]|([^:/?#]+))(?::(\d+))?)?([^?#]*(?:\?[^#]*)?)(?:#.*)?)");

std::smatch m;
if (!std::regex_match(location, m, re)) { return false; }
Expand All @@ -5620,8 +5620,9 @@ inline bool ClientImpl::redirect(Request &req, Response &res, Error &error) {

auto next_scheme = m[1].str();
auto next_host = m[2].str();
auto port_str = m[3].str();
auto next_path = m[4].str();
if (next_host.empty()) { next_host = m[3].str(); }
auto port_str = m[4].str();
auto next_path = m[5].str();

auto next_port = port_;
if (!port_str.empty()) {
Expand Down Expand Up @@ -7266,7 +7267,8 @@ 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_key_path) {
const static std::regex re(R"(^(?:([a-z]+)://)?([^:/?#]+)(?::(\d+))?)");
const static std::regex re(
R"((?:([a-z]+):\/\/)?(?:\[([\d:]+)\]|([^:/?#]+))(?::(\d+))?)");

std::cmatch m;
if (std::regex_match(scheme_host_port, m, re)) {
Expand All @@ -7285,8 +7287,9 @@ inline Client::Client(const char *scheme_host_port,
auto is_ssl = scheme == "https";

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);

if (is_ssl) {
Expand Down
84 changes: 71 additions & 13 deletions test/test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,18 @@ TEST(HttpsToHttpRedirectTest3, Redirect) {
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) {
Server svr8080;
Server svr8081;
Expand Down Expand Up @@ -878,16 +890,6 @@ TEST(RedirectToDifferentPort, Redirect) {
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) {
Server svr;

Expand Down Expand Up @@ -943,7 +945,61 @@ TEST(RedirectFromPageWithContent, Redirect) {
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) {
Server svr;
Expand Down Expand Up @@ -2717,10 +2773,12 @@ TEST_F(ServerTest, PutLargeFileWithGzip) {

TEST_F(ServerTest, PutLargeFileWithGzip2) {
#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);
#else
Client cli("http://localhost:1234");
std::string s = std::string("http://") + HOST + ":" + std::to_string(PORT);
Client cli(s.c_str());
#endif
cli.set_compress(true);

Expand Down

0 comments on commit 06bfa7e

Please sign in to comment.