Skip to content

Commit ec4bdbc

Browse files
authored
When Java Servlet parses the request header host, it will split the IP and port. When using the default port (not passed by default), if there is no [] distinction, Java will use the last colon of IPv6 as the port delimiter, and Java parsing will report an error
1 parent 959c883 commit ec4bdbc

File tree

2 files changed

+40
-11
lines changed

2 files changed

+40
-11
lines changed

httplib.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8510,8 +8510,8 @@ inline ClientImpl::ClientImpl(const std::string &host, int port)
85108510
inline ClientImpl::ClientImpl(const std::string &host, int port,
85118511
const std::string &client_cert_path,
85128512
const std::string &client_key_path)
8513-
: host_(adjust_host_string(detail::escape_abstract_namespace_unix_domain(host))), port_(port),
8514-
host_and_port_(host_ + ":" + std::to_string(port)),
8513+
: host_(detail::escape_abstract_namespace_unix_domain(host)), port_(port),
8514+
host_and_port_(adjust_host_string(host_) + ":" + std::to_string(port)),
85158515
client_cert_path_(client_cert_path), client_key_path_(client_key_path) {}
85168516

85178517
inline ClientImpl::~ClientImpl() {
@@ -9122,13 +9122,13 @@ inline bool ClientImpl::write_request(Stream &strm, Request &req,
91229122
req.set_header("Host", "localhost");
91239123
} else if (is_ssl()) {
91249124
if (port_ == 443) {
9125-
req.set_header("Host", host_);
9125+
req.set_header("Host", adjust_host_string(host_));
91269126
} else {
91279127
req.set_header("Host", host_and_port_);
91289128
}
91299129
} else {
91309130
if (port_ == 80) {
9131-
req.set_header("Host", host_);
9131+
req.set_header("Host", adjust_host_string(host_));
91329132
} else {
91339133
req.set_header("Host", host_and_port_);
91349134
}

test/test.cc

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4987,15 +4987,15 @@ TEST_F(ServerTest, GetMethodRemoteAddr) {
49874987
ASSERT_TRUE(res);
49884988
EXPECT_EQ(StatusCode::OK_200, res->status);
49894989
EXPECT_EQ("text/plain", res->get_header_value("Content-Type"));
4990-
EXPECT_TRUE(res->body == "[::1]" || res->body == "127.0.0.1");
4990+
EXPECT_TRUE(res->body == "::1" || res->body == "127.0.0.1");
49914991
}
49924992

49934993
TEST_F(ServerTest, GetMethodLocalAddr) {
49944994
auto res = cli_.Get("/local_addr");
49954995
ASSERT_TRUE(res);
49964996
EXPECT_EQ(StatusCode::OK_200, res->status);
49974997
EXPECT_EQ("text/plain", res->get_header_value("Content-Type"));
4998-
EXPECT_TRUE(res->body == std::string("[::1]:").append(to_string(PORT)) ||
4998+
EXPECT_TRUE(res->body == std::string("::1:").append(to_string(PORT)) ||
49994999
res->body == std::string("127.0.0.1:").append(to_string(PORT)));
50005000
}
50015001

@@ -10285,12 +10285,41 @@ TEST(UniversalClientImplTest, Ipv6LiteralAddress) {
1028510285
EXPECT_EQ(cli.port(), port);
1028610286
}
1028710287

10288-
TEST(UniversalClientImplTest, Ipv6LiteralAddressHost) {
10289-
std::string host = "[::1]";
10290-
std::string ipV6TestURL = "http://" + host;
10288+
TEST(UniversalClientImplTest, Ipv6LiteralAddressHostDefaultPort) {
10289+
/*
10290+
When Java Servlet parses the request header host, it will split the IP and port.
10291+
When using the default port (not passed by default), if there is no [] distinction,
10292+
Java will use the last colon of IPv6 as the port delimiter, and Java parsing will report an error
10293+
*/
10294+
httplib::Server svr;
10295+
svr.Get("/", [&](const httplib::Request & req, httplib::Response &res) {
10296+
res.status = httplib::StatusCode::OK_200;
10297+
res.set_content(req.get_header_value("Host", ""), "text/plain");
10298+
});
10299+
10300+
auto thread = std::thread([&]() { svr.listen("[::1]", 80); });
10301+
auto se = httplib::detail::scope_exit([&] {
10302+
svr.stop();
10303+
thread.join();
10304+
ASSERT_FALSE(svr.is_running());
10305+
});
1029110306

10292-
Client cli(ipV6TestURL);
10293-
EXPECT_EQ(cli.host(), host);
10307+
svr.wait_until_ready();
10308+
10309+
{
10310+
httplib::Client cli("http://[::1]");
10311+
cli.set_keep_alive(true);
10312+
10313+
EXPECT_EQ(cli.socket(), INVALID_SOCKET);
10314+
10315+
auto res = cli.Get("/");
10316+
ASSERT_TRUE(res);
10317+
10318+
std::cout << "status:" << res->status << ", body:" << res->body << std::endl;
10319+
10320+
EXPECT_EQ(httplib::StatusCode::OK_200, res->status);
10321+
EXPECT_EQ("[::1]", res->body);
10322+
}
1029410323
}
1029510324

1029610325
TEST(FileSystemTest, FileAndDirExistenceCheck) {

0 commit comments

Comments
 (0)