Skip to content

Commit 21c5292

Browse files
committed
Fixed timeout issues
1 parent 63643e6 commit 21c5292

File tree

2 files changed

+48
-11
lines changed

2 files changed

+48
-11
lines changed

httplib.h

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2091,8 +2091,9 @@ socket_t create_socket(const char *host, int port, int address_family,
20912091
for (auto rp = result; rp; rp = rp->ai_next) {
20922092
// Create a socket
20932093
#ifdef _WIN32
2094-
auto sock = WSASocketW(rp->ai_family, rp->ai_socktype, rp->ai_protocol,
2095-
nullptr, 0, WSA_FLAG_NO_HANDLE_INHERIT);
2094+
auto sock =
2095+
WSASocketW(rp->ai_family, rp->ai_socktype, rp->ai_protocol, nullptr, 0,
2096+
WSA_FLAG_NO_HANDLE_INHERIT | WSA_FLAG_OVERLAPPED);
20962097
/**
20972098
* Since the WSA_FLAG_NO_HANDLE_INHERIT is only supported on Windows 7 SP1
20982099
* and above the socket creation fails on older Windows Systems.
@@ -2214,11 +2215,12 @@ inline std::string if2ip(const std::string &ifn) {
22142215
}
22152216
#endif
22162217

2217-
inline socket_t create_client_socket(const char *host, int port,
2218-
int address_family, bool tcp_nodelay,
2219-
SocketOptions socket_options,
2220-
time_t timeout_sec, time_t timeout_usec,
2221-
const std::string &intf, Error &error) {
2218+
inline socket_t create_client_socket(
2219+
const char *host, int port, int address_family, bool tcp_nodelay,
2220+
SocketOptions socket_options, time_t connection_timeout_sec,
2221+
time_t connection_timeout_usec, time_t read_timeout_sec,
2222+
time_t read_timeout_usec, time_t write_timeout_sec,
2223+
time_t write_timeout_usec, const std::string &intf, Error &error) {
22222224
auto sock = create_socket(
22232225
host, port, address_family, 0, tcp_nodelay, std::move(socket_options),
22242226
[&](socket_t sock, struct addrinfo &ai) -> bool {
@@ -2240,14 +2242,30 @@ inline socket_t create_client_socket(const char *host, int port,
22402242

22412243
if (ret < 0) {
22422244
if (is_connection_error() ||
2243-
!wait_until_socket_is_ready(sock, timeout_sec, timeout_usec)) {
2245+
!wait_until_socket_is_ready(sock, connection_timeout_sec,
2246+
connection_timeout_usec)) {
22442247
close_socket(sock);
22452248
error = Error::Connection;
22462249
return false;
22472250
}
22482251
}
22492252

22502253
set_nonblocking(sock, false);
2254+
2255+
{
2256+
timeval tv;
2257+
tv.tv_sec = static_cast<long>(read_timeout_sec);
2258+
tv.tv_usec = static_cast<decltype(tv.tv_usec)>(read_timeout_usec);
2259+
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
2260+
}
2261+
{
2262+
timeval tv;
2263+
tv.tv_sec = static_cast<long>(write_timeout_sec);
2264+
tv.tv_usec =
2265+
static_cast<decltype(tv.tv_usec)>(write_timeout_usec);
2266+
setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(tv));
2267+
}
2268+
22512269
error = Error::Success;
22522270
return true;
22532271
});
@@ -4847,6 +4865,19 @@ inline bool Server::listen_internal() {
48474865
break;
48484866
}
48494867

4868+
{
4869+
timeval tv;
4870+
tv.tv_sec = static_cast<long>(read_timeout_sec_);
4871+
tv.tv_usec = static_cast<decltype(tv.tv_usec)>(read_timeout_usec_);
4872+
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
4873+
}
4874+
{
4875+
timeval tv;
4876+
tv.tv_sec = static_cast<long>(write_timeout_sec_);
4877+
tv.tv_usec = static_cast<decltype(tv.tv_usec)>(write_timeout_usec_);
4878+
setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(tv));
4879+
}
4880+
48504881
#if __cplusplus > 201703L
48514882
task_queue->enqueue([=, this]() { process_and_close_socket(sock); });
48524883
#else
@@ -5263,11 +5294,14 @@ inline socket_t ClientImpl::create_client_socket(Error &error) const {
52635294
return detail::create_client_socket(
52645295
proxy_host_.c_str(), proxy_port_, address_family_, tcp_nodelay_,
52655296
socket_options_, connection_timeout_sec_, connection_timeout_usec_,
5266-
interface_, error);
5297+
read_timeout_sec_, read_timeout_usec_, write_timeout_sec_,
5298+
write_timeout_usec_, interface_, error);
52675299
}
52685300
return detail::create_client_socket(
52695301
host_.c_str(), port_, address_family_, tcp_nodelay_, socket_options_,
5270-
connection_timeout_sec_, connection_timeout_usec_, interface_, error);
5302+
connection_timeout_sec_, connection_timeout_usec_, read_timeout_sec_,
5303+
read_timeout_usec_, write_timeout_sec_, write_timeout_usec_, interface_,
5304+
error);
52715305
}
52725306

52735307
inline bool ClientImpl::create_and_connect_socket(Socket &socket,

test/test.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3145,7 +3145,10 @@ static bool send_request(time_t read_timeout_sec, const std::string &req,
31453145

31463146
auto client_sock =
31473147
detail::create_client_socket(HOST, PORT, AF_UNSPEC, false, nullptr,
3148-
/*timeout_sec=*/5, 0, std::string(), error);
3148+
/*connection_timeout_sec=*/5, 0,
3149+
/*read_timeout_sec=*/5, 0,
3150+
/*write_timeout_sec=*/5, 0,
3151+
std::string(), error);
31493152

31503153
if (client_sock == INVALID_SOCKET) { return false; }
31513154

0 commit comments

Comments
 (0)