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

@ -5064,3 +5064,71 @@ TEST(MultipartFormDataTest, WithPreamble) {
#endif
#ifndef _WIN32
class UnixSocketTest : public ::testing::Test {
protected:
void TearDown() override {
std::remove(pathname_.c_str());
}
void client_GET(const std::string &addr) {
httplib::Client cli{addr};
cli.set_address_family(AF_UNIX);
ASSERT_TRUE(cli.is_valid());
const auto &result = cli.Get(pattern_);
ASSERT_TRUE(result) << "error: " << result.error();
const auto &resp = result.value();
EXPECT_EQ(resp.status, 200);
EXPECT_EQ(resp.body, content_);
}
const std::string pathname_ {"./httplib-server.sock"};
const std::string pattern_ {"/hi"};
const std::string content_ {"Hello World!"};
};
TEST_F(UnixSocketTest, pathname) {
httplib::Server svr;
svr.Get(pattern_, [&](const httplib::Request &, httplib::Response &res) {
res.set_content(content_, "text/plain");
});
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_);
svr.stop();
t.join();
}
#ifdef __linux__
TEST_F(UnixSocketTest, abstract) {
constexpr char svr_path[] {"\x00httplib-server.sock"};
const std::string abstract_addr {svr_path, sizeof(svr_path) - 1};
httplib::Server svr;
svr.Get(pattern_, [&](const httplib::Request &, httplib::Response &res) {
res.set_content(content_, "text/plain");
});
std::thread t {[&] {
ASSERT_TRUE(svr.set_address_family(AF_UNIX).listen(abstract_addr, 80)); }};
while (!svr.is_running()) {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
ASSERT_TRUE(svr.is_running());
client_GET(abstract_addr);
svr.stop();
t.join();
}
#endif
#endif // #ifndef _WIN32