UNIX domain socket support (#1346)

* Add support UNIX domain socket

* `set_address_family(AF_UNIX)` is required

* add unittest for UNIX domain socket

* add support UNIX domain socket with abstract address

Abstract address of AF_UNIX begins with null(0x00) which can't be
delivered via .c_str() method.

* add unittest for UNIX domain socket with abstract address

Co-authored-by: Changbin Park <changbin.park@ahnlab.com>
This commit is contained in:
Changbin Park 2022-08-01 19:57:25 +09:00 committed by GitHub
parent 1bd88de2e5
commit 362d064afa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 95 additions and 2 deletions

View file

@ -183,6 +183,7 @@ using socket_t = SOCKET;
#include <pthread.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
using socket_t = int;
@ -2570,6 +2571,30 @@ socket_t create_socket(const std::string &host, const std::string &ip, int port,
hints.ai_flags = socket_flags;
}
#ifndef _WIN32
if (hints.ai_family == AF_UNIX) {
const auto addrlen = host.length();
if (addrlen > sizeof(sockaddr_un::sun_path)) return INVALID_SOCKET;
auto sock = socket(hints.ai_family, hints.ai_socktype, hints.ai_protocol);
if (sock != INVALID_SOCKET) {
sockaddr_un addr;
addr.sun_family = AF_UNIX;
std::copy(host.begin(), host.end(), addr.sun_path);
hints.ai_addr = reinterpret_cast<sockaddr*>(&addr);
hints.ai_addrlen = static_cast<socklen_t>(
sizeof(addr) - sizeof(addr.sun_path) + addrlen);
if (!bind_or_connect(sock, hints)) {
close_socket(sock);
sock = INVALID_SOCKET;
}
}
return sock;
}
#endif
auto service = std::to_string(port);
if (getaddrinfo(node, service.c_str(), &hints, &result)) {
@ -7858,12 +7883,12 @@ inline Client::Client(const std::string &scheme_host_port,
if (is_ssl) {
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
cli_ = detail::make_unique<SSLClient>(host.c_str(), port,
cli_ = detail::make_unique<SSLClient>(host, port,
client_cert_path, client_key_path);
is_ssl_ = is_ssl;
#endif
} else {
cli_ = detail::make_unique<ClientImpl>(host.c_str(), port,
cli_ = detail::make_unique<ClientImpl>(host, port,
client_cert_path, client_key_path);
}
} else {