Skip to content

Commit ca1bed5

Browse files
committed
Fix #2021
1 parent 8b28577 commit ca1bed5

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-1
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,8 @@ cli.set_address_family(AF_UNIX);
10841084
10851085
"my-socket.sock" can be a relative path or an absolute path. Your application must have the appropriate permissions for the path. You can also use an abstract socket address on Linux. To use an abstract socket address, prepend a null byte ('\x00') to the path.
10861086
1087+
This library automatically sets the Host header to "localhost" for Unix socket connections, similar to curl's behavior:
1088+
10871089
10881090
URI Encoding/Decoding Utilities
10891091
-------------------------------

httplib.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8844,7 +8844,11 @@ inline bool ClientImpl::write_request(Stream &strm, Request &req,
88448844
}
88458845

88468846
if (!req.has_header("Host")) {
8847-
if (is_ssl()) {
8847+
// For Unix socket connections, use "localhost" as Host header (similar to
8848+
// curl behavior)
8849+
if (address_family_ == AF_UNIX) {
8850+
req.set_header("Host", "localhost");
8851+
} else if (is_ssl()) {
88488852
if (port_ == 443) {
88498853
req.set_header("Host", host_);
88508854
} else {

test/test.cc

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,48 @@ TEST_F(UnixSocketTest, abstract) {
173173
}
174174
#endif
175175

176+
TEST_F(UnixSocketTest, HostHeaderAutoSet) {
177+
httplib::Server svr;
178+
std::string received_host_header;
179+
180+
svr.Get(pattern_, [&](const httplib::Request &req, httplib::Response &res) {
181+
// Capture the Host header sent by the client
182+
auto host_iter = req.headers.find("Host");
183+
if (host_iter != req.headers.end()) {
184+
received_host_header = host_iter->second;
185+
}
186+
res.set_content(content_, "text/plain");
187+
});
188+
189+
std::thread t{[&] {
190+
ASSERT_TRUE(svr.set_address_family(AF_UNIX).listen(pathname_, 80));
191+
}};
192+
auto se = detail::scope_exit([&] {
193+
svr.stop();
194+
t.join();
195+
ASSERT_FALSE(svr.is_running());
196+
});
197+
198+
svr.wait_until_ready();
199+
ASSERT_TRUE(svr.is_running());
200+
201+
// Test that Host header is automatically set to "localhost" for Unix socket
202+
// connections
203+
httplib::Client cli{pathname_};
204+
cli.set_address_family(AF_UNIX);
205+
ASSERT_TRUE(cli.is_valid());
206+
207+
const auto &result = cli.Get(pattern_);
208+
ASSERT_TRUE(result) << "error: " << result.error();
209+
210+
const auto &resp = result.value();
211+
EXPECT_EQ(resp.status, StatusCode::OK_200);
212+
EXPECT_EQ(resp.body, content_);
213+
214+
// Verify that Host header was automatically set to "localhost"
215+
EXPECT_EQ(received_host_header, "localhost");
216+
}
217+
176218
#ifndef _WIN32
177219
TEST(SocketStream, wait_writable_UNIX) {
178220
int fds[2];

0 commit comments

Comments
 (0)