mirror of
https://github.com/yhirose/cpp-httplib
synced 2024-11-21 14:29:10 -07:00
Get client process id over ip/port when server runs on UNIX socket. (#1418)
* handle socket options for UNIX socket same as others * set FD_CLOEXEC by default * invoke `socket_options` callback if set * Offer Client info even on UNIX socket based Server HTTP Request header "REMOTE_PORT" contains client process id if possible when Server works on UNIX socket. * retrigger checks * retrigger checks * add support macOS Co-authored-by: Changbin Park <changbin.park@ahnlab.com>
This commit is contained in:
parent
ad7edc7b27
commit
93a51979c4
2 changed files with 46 additions and 0 deletions
21
httplib.h
21
httplib.h
|
@ -2601,6 +2601,9 @@ socket_t create_socket(const std::string &host, const std::string &ip, int port,
|
||||||
hints.ai_addrlen = static_cast<socklen_t>(
|
hints.ai_addrlen = static_cast<socklen_t>(
|
||||||
sizeof(addr) - sizeof(addr.sun_path) + addrlen);
|
sizeof(addr) - sizeof(addr.sun_path) + addrlen);
|
||||||
|
|
||||||
|
fcntl(sock, F_SETFD, FD_CLOEXEC);
|
||||||
|
if (socket_options) { socket_options(sock); }
|
||||||
|
|
||||||
if (!bind_or_connect(sock, hints)) {
|
if (!bind_or_connect(sock, hints)) {
|
||||||
close_socket(sock);
|
close_socket(sock);
|
||||||
sock = INVALID_SOCKET;
|
sock = INVALID_SOCKET;
|
||||||
|
@ -2871,6 +2874,24 @@ inline void get_remote_ip_and_port(socket_t sock, std::string &ip, int &port) {
|
||||||
|
|
||||||
if (!getpeername(sock, reinterpret_cast<struct sockaddr *>(&addr),
|
if (!getpeername(sock, reinterpret_cast<struct sockaddr *>(&addr),
|
||||||
&addr_len)) {
|
&addr_len)) {
|
||||||
|
#ifndef _WIN32
|
||||||
|
if (addr.ss_family == AF_UNIX) {
|
||||||
|
#if defined(__linux__)
|
||||||
|
struct ucred ucred;
|
||||||
|
socklen_t len = sizeof(ucred);
|
||||||
|
if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == 0) {
|
||||||
|
port = ucred.pid;
|
||||||
|
}
|
||||||
|
#elif defined(SOL_LOCAL) && defined(SO_PEERPID) // __APPLE__
|
||||||
|
pid_t pid;
|
||||||
|
socklen_t len = sizeof(pid);
|
||||||
|
if (getsockopt(sock, SOL_LOCAL, SO_PEERPID, &pid, &len) == 0) {
|
||||||
|
port = pid;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
get_remote_ip_and_port(addr, addr_len, ip, port);
|
get_remote_ip_and_port(addr, addr_len, ip, port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
25
test/test.cc
25
test/test.cc
|
@ -5344,6 +5344,31 @@ TEST_F(UnixSocketTest, pathname) {
|
||||||
t.join();
|
t.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__linux__) \
|
||||||
|
|| /* __APPLE__ */ (defined(SOL_LOCAL) && defined(SO_PEERPID))
|
||||||
|
TEST_F(UnixSocketTest, PeerPid) {
|
||||||
|
httplib::Server svr;
|
||||||
|
std::string remote_port_val;
|
||||||
|
svr.Get(pattern_, [&](const httplib::Request &req, httplib::Response &res) {
|
||||||
|
res.set_content(content_, "text/plain");
|
||||||
|
remote_port_val = req.get_header_value("REMOTE_PORT");
|
||||||
|
});
|
||||||
|
|
||||||
|
std::thread t {[&] {
|
||||||
|
ASSERT_TRUE(svr.set_address_family(AF_UNIX).listen(pathname_, 80)); }};
|
||||||
|
while (!svr.is_running()) {
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
|
}
|
||||||
|
ASSERT_TRUE(svr.is_running());
|
||||||
|
|
||||||
|
client_GET(pathname_);
|
||||||
|
EXPECT_EQ(std::to_string(getpid()), remote_port_val);
|
||||||
|
|
||||||
|
svr.stop();
|
||||||
|
t.join();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
TEST_F(UnixSocketTest, abstract) {
|
TEST_F(UnixSocketTest, abstract) {
|
||||||
constexpr char svr_path[] {"\x00httplib-server.sock"};
|
constexpr char svr_path[] {"\x00httplib-server.sock"};
|
||||||
|
|
Loading…
Reference in a new issue