@@ -54,6 +54,166 @@ MultipartFormData &get_file_value(MultipartFormDataItems &files,
54
54
#endif
55
55
}
56
56
57
+ #ifndef _WIN32
58
+ class UnixSocketTest : public ::testing::Test {
59
+ protected:
60
+ void TearDown () override { std::remove (pathname_.c_str ()); }
61
+
62
+ void client_GET (const std::string &addr) {
63
+ httplib::Client cli{addr};
64
+ cli.set_address_family (AF_UNIX);
65
+ ASSERT_TRUE (cli.is_valid ());
66
+
67
+ const auto &result = cli.Get (pattern_);
68
+ ASSERT_TRUE (result) << " error: " << result.error ();
69
+
70
+ const auto &resp = result.value ();
71
+ EXPECT_EQ (resp.status , StatusCode::OK_200);
72
+ EXPECT_EQ (resp.body , content_);
73
+ }
74
+
75
+ const std::string pathname_{" ./httplib-server.sock" };
76
+ const std::string pattern_{" /hi" };
77
+ const std::string content_{" Hello World!" };
78
+ };
79
+
80
+ TEST_F (UnixSocketTest, pathname) {
81
+ httplib::Server svr;
82
+ svr.Get (pattern_, [&](const httplib::Request &, httplib::Response &res) {
83
+ res.set_content (content_, " text/plain" );
84
+ });
85
+
86
+ std::thread t{[&] {
87
+ ASSERT_TRUE (svr.set_address_family (AF_UNIX).listen (pathname_, 80 ));
88
+ }};
89
+ auto se = detail::scope_exit ([&] {
90
+ svr.stop ();
91
+ t.join ();
92
+ ASSERT_FALSE (svr.is_running ());
93
+ });
94
+
95
+ svr.wait_until_ready ();
96
+ ASSERT_TRUE (svr.is_running ());
97
+
98
+ client_GET (pathname_);
99
+ }
100
+
101
+ #if defined(__linux__) || \
102
+ /* __APPLE__ */ (defined(SOL_LOCAL) && defined(SO_PEERPID))
103
+ TEST_F (UnixSocketTest, PeerPid) {
104
+ httplib::Server svr;
105
+ std::string remote_port_val;
106
+ svr.Get (pattern_, [&](const httplib::Request &req, httplib::Response &res) {
107
+ res.set_content (content_, " text/plain" );
108
+ remote_port_val = req.get_header_value (" REMOTE_PORT" );
109
+ });
110
+
111
+ std::thread t{[&] {
112
+ ASSERT_TRUE (svr.set_address_family (AF_UNIX).listen (pathname_, 80 ));
113
+ }};
114
+ auto se = detail::scope_exit ([&] {
115
+ svr.stop ();
116
+ t.join ();
117
+ ASSERT_FALSE (svr.is_running ());
118
+ });
119
+
120
+ svr.wait_until_ready ();
121
+ ASSERT_TRUE (svr.is_running ());
122
+
123
+ client_GET (pathname_);
124
+ EXPECT_EQ (std::to_string (getpid ()), remote_port_val);
125
+ }
126
+ #endif
127
+
128
+ #ifdef __linux__
129
+ TEST_F (UnixSocketTest, abstract) {
130
+ constexpr char svr_path[]{" \x00 httplib-server.sock" };
131
+ const std::string abstract_addr{svr_path, sizeof (svr_path) - 1 };
132
+
133
+ httplib::Server svr;
134
+ svr.Get (pattern_, [&](const httplib::Request &, httplib::Response &res) {
135
+ res.set_content (content_, " text/plain" );
136
+ });
137
+
138
+ std::thread t{[&] {
139
+ ASSERT_TRUE (svr.set_address_family (AF_UNIX).listen (abstract_addr, 80 ));
140
+ }};
141
+ auto se = detail::scope_exit ([&] {
142
+ svr.stop ();
143
+ t.join ();
144
+ ASSERT_FALSE (svr.is_running ());
145
+ });
146
+
147
+ svr.wait_until_ready ();
148
+ ASSERT_TRUE (svr.is_running ());
149
+
150
+ client_GET (abstract_addr);
151
+ }
152
+ #endif
153
+
154
+ TEST (SocketStream, is_writable_UNIX) {
155
+ int fds[2 ];
156
+ ASSERT_EQ (0 , socketpair (AF_UNIX, SOCK_STREAM, 0 , fds));
157
+
158
+ const auto asSocketStream = [&](socket_t fd,
159
+ std::function<bool (Stream &)> func) {
160
+ return detail::process_client_socket (fd, 0 , 0 , 0 , 0 , func);
161
+ };
162
+ asSocketStream (fds[0 ], [&](Stream &s0) {
163
+ EXPECT_EQ (s0.socket (), fds[0 ]);
164
+ EXPECT_TRUE (s0.is_writable ());
165
+
166
+ EXPECT_EQ (0 , close (fds[1 ]));
167
+ EXPECT_FALSE (s0.is_writable ());
168
+
169
+ return true ;
170
+ });
171
+ EXPECT_EQ (0 , close (fds[0 ]));
172
+ }
173
+
174
+ TEST (SocketStream, is_writable_INET) {
175
+ sockaddr_in addr;
176
+ memset (&addr, 0 , sizeof (addr));
177
+ addr.sin_family = AF_INET;
178
+ addr.sin_port = htons (PORT + 1 );
179
+ addr.sin_addr .s_addr = htonl (INADDR_LOOPBACK);
180
+
181
+ int disconnected_svr_sock = -1 ;
182
+ std::thread svr{[&] {
183
+ const int s = socket (AF_INET, SOCK_STREAM, 0 );
184
+ ASSERT_LE (0 , s);
185
+ ASSERT_EQ (0 , ::bind (s, reinterpret_cast <sockaddr *>(&addr), sizeof (addr)));
186
+ ASSERT_EQ (0 , listen (s, 1 ));
187
+ ASSERT_LE (0 , disconnected_svr_sock = accept (s, nullptr , nullptr ));
188
+ ASSERT_EQ (0 , close (s));
189
+ }};
190
+ std::this_thread::sleep_for (std::chrono::milliseconds (100 ));
191
+
192
+ std::thread cli{[&] {
193
+ const int s = socket (AF_INET, SOCK_STREAM, 0 );
194
+ ASSERT_LE (0 , s);
195
+ ASSERT_EQ (0 , connect (s, reinterpret_cast <sockaddr *>(&addr), sizeof (addr)));
196
+ ASSERT_EQ (0 , close (s));
197
+ }};
198
+ cli.join ();
199
+ svr.join ();
200
+ ASSERT_NE (disconnected_svr_sock, -1 );
201
+
202
+ const auto asSocketStream = [&](socket_t fd,
203
+ std::function<bool (Stream &)> func) {
204
+ return detail::process_client_socket (fd, 0 , 0 , 0 , 0 , func);
205
+ };
206
+ asSocketStream (disconnected_svr_sock, [&](Stream &ss) {
207
+ EXPECT_EQ (ss.socket (), disconnected_svr_sock);
208
+ EXPECT_FALSE (ss.is_writable ());
209
+
210
+ return true ;
211
+ });
212
+
213
+ ASSERT_EQ (0 , close (disconnected_svr_sock));
214
+ }
215
+ #endif // #ifndef _WIN32
216
+
57
217
TEST (ClientTest, MoveConstructible) {
58
218
EXPECT_FALSE (std::is_copy_constructible<Client>::value);
59
219
EXPECT_TRUE (std::is_nothrow_move_constructible<Client>::value);
@@ -7024,166 +7184,6 @@ TEST(MultipartFormDataTest, ContentLength) {
7024
7184
7025
7185
#endif
7026
7186
7027
- #ifndef _WIN32
7028
- class UnixSocketTest : public ::testing::Test {
7029
- protected:
7030
- void TearDown () override { std::remove (pathname_.c_str ()); }
7031
-
7032
- void client_GET (const std::string &addr) {
7033
- httplib::Client cli{addr};
7034
- cli.set_address_family (AF_UNIX);
7035
- ASSERT_TRUE (cli.is_valid ());
7036
-
7037
- const auto &result = cli.Get (pattern_);
7038
- ASSERT_TRUE (result) << " error: " << result.error ();
7039
-
7040
- const auto &resp = result.value ();
7041
- EXPECT_EQ (resp.status , StatusCode::OK_200);
7042
- EXPECT_EQ (resp.body , content_);
7043
- }
7044
-
7045
- const std::string pathname_{" ./httplib-server.sock" };
7046
- const std::string pattern_{" /hi" };
7047
- const std::string content_{" Hello World!" };
7048
- };
7049
-
7050
- TEST_F (UnixSocketTest, pathname) {
7051
- httplib::Server svr;
7052
- svr.Get (pattern_, [&](const httplib::Request &, httplib::Response &res) {
7053
- res.set_content (content_, " text/plain" );
7054
- });
7055
-
7056
- std::thread t{[&] {
7057
- ASSERT_TRUE (svr.set_address_family (AF_UNIX).listen (pathname_, 80 ));
7058
- }};
7059
- auto se = detail::scope_exit ([&] {
7060
- svr.stop ();
7061
- t.join ();
7062
- ASSERT_FALSE (svr.is_running ());
7063
- });
7064
-
7065
- svr.wait_until_ready ();
7066
- ASSERT_TRUE (svr.is_running ());
7067
-
7068
- client_GET (pathname_);
7069
- }
7070
-
7071
- #if defined(__linux__) || \
7072
- /* __APPLE__ */ (defined (SOL_LOCAL) && defined (SO_PEERPID))
7073
- TEST_F (UnixSocketTest, PeerPid) {
7074
- httplib::Server svr;
7075
- std::string remote_port_val;
7076
- svr.Get (pattern_, [&](const httplib::Request &req, httplib::Response &res) {
7077
- res.set_content (content_, " text/plain" );
7078
- remote_port_val = req.get_header_value (" REMOTE_PORT" );
7079
- });
7080
-
7081
- std::thread t{[&] {
7082
- ASSERT_TRUE (svr.set_address_family (AF_UNIX).listen (pathname_, 80 ));
7083
- }};
7084
- auto se = detail::scope_exit ([&] {
7085
- svr.stop ();
7086
- t.join ();
7087
- ASSERT_FALSE (svr.is_running ());
7088
- });
7089
-
7090
- svr.wait_until_ready ();
7091
- ASSERT_TRUE (svr.is_running ());
7092
-
7093
- client_GET (pathname_);
7094
- EXPECT_EQ (std::to_string (getpid ()), remote_port_val);
7095
- }
7096
- #endif
7097
-
7098
- #ifdef __linux__
7099
- TEST_F (UnixSocketTest, abstract) {
7100
- constexpr char svr_path[]{" \x00 httplib-server.sock" };
7101
- const std::string abstract_addr{svr_path, sizeof (svr_path) - 1 };
7102
-
7103
- httplib::Server svr;
7104
- svr.Get (pattern_, [&](const httplib::Request &, httplib::Response &res) {
7105
- res.set_content (content_, " text/plain" );
7106
- });
7107
-
7108
- std::thread t{[&] {
7109
- ASSERT_TRUE (svr.set_address_family (AF_UNIX).listen (abstract_addr, 80 ));
7110
- }};
7111
- auto se = detail::scope_exit ([&] {
7112
- svr.stop ();
7113
- t.join ();
7114
- ASSERT_FALSE (svr.is_running ());
7115
- });
7116
-
7117
- svr.wait_until_ready ();
7118
- ASSERT_TRUE (svr.is_running ());
7119
-
7120
- client_GET (abstract_addr);
7121
- }
7122
- #endif
7123
-
7124
- TEST (SocketStream, is_writable_UNIX) {
7125
- int fds[2 ];
7126
- ASSERT_EQ (0 , socketpair (AF_UNIX, SOCK_STREAM, 0 , fds));
7127
-
7128
- const auto asSocketStream = [&](socket_t fd,
7129
- std::function<bool (Stream &)> func) {
7130
- return detail::process_client_socket (fd, 0 , 0 , 0 , 0 , func);
7131
- };
7132
- asSocketStream (fds[0 ], [&](Stream &s0) {
7133
- EXPECT_EQ (s0.socket (), fds[0 ]);
7134
- EXPECT_TRUE (s0.is_writable ());
7135
-
7136
- EXPECT_EQ (0 , close (fds[1 ]));
7137
- EXPECT_FALSE (s0.is_writable ());
7138
-
7139
- return true ;
7140
- });
7141
- EXPECT_EQ (0 , close (fds[0 ]));
7142
- }
7143
-
7144
- TEST (SocketStream, is_writable_INET) {
7145
- sockaddr_in addr;
7146
- memset (&addr, 0 , sizeof (addr));
7147
- addr.sin_family = AF_INET;
7148
- addr.sin_port = htons (PORT + 1 );
7149
- addr.sin_addr .s_addr = htonl (INADDR_LOOPBACK);
7150
-
7151
- int disconnected_svr_sock = -1 ;
7152
- std::thread svr{[&] {
7153
- const int s = socket (AF_INET, SOCK_STREAM, 0 );
7154
- ASSERT_LE (0 , s);
7155
- ASSERT_EQ (0 , ::bind (s, reinterpret_cast <sockaddr *>(&addr), sizeof (addr)));
7156
- ASSERT_EQ (0 , listen (s, 1 ));
7157
- ASSERT_LE (0 , disconnected_svr_sock = accept (s, nullptr , nullptr ));
7158
- ASSERT_EQ (0 , close (s));
7159
- }};
7160
- std::this_thread::sleep_for (std::chrono::milliseconds (100 ));
7161
-
7162
- std::thread cli{[&] {
7163
- const int s = socket (AF_INET, SOCK_STREAM, 0 );
7164
- ASSERT_LE (0 , s);
7165
- ASSERT_EQ (0 , connect (s, reinterpret_cast <sockaddr *>(&addr), sizeof (addr)));
7166
- ASSERT_EQ (0 , close (s));
7167
- }};
7168
- cli.join ();
7169
- svr.join ();
7170
- ASSERT_NE (disconnected_svr_sock, -1 );
7171
-
7172
- const auto asSocketStream = [&](socket_t fd,
7173
- std::function<bool (Stream &)> func) {
7174
- return detail::process_client_socket (fd, 0 , 0 , 0 , 0 , func);
7175
- };
7176
- asSocketStream (disconnected_svr_sock, [&](Stream &ss) {
7177
- EXPECT_EQ (ss.socket (), disconnected_svr_sock);
7178
- EXPECT_FALSE (ss.is_writable ());
7179
-
7180
- return true ;
7181
- });
7182
-
7183
- ASSERT_EQ (0 , close (disconnected_svr_sock));
7184
- }
7185
- #endif // #ifndef _WIN32
7186
-
7187
7187
TEST (TaskQueueTest, IncreaseAtomicInteger) {
7188
7188
static constexpr unsigned int number_of_tasks{1000000 };
7189
7189
std::atomic_uint count{0 };
0 commit comments