@@ -193,6 +193,7 @@ using ssize_t = long;
193
193
#endif
194
194
195
195
using socket_t = SOCKET;
196
+ using socklen_t = int ;
196
197
#ifdef CPPHTTPLIB_USE_POLL
197
198
#define poll (fds, nfds, timeout ) WSAPoll(fds, nfds, timeout)
198
199
#endif
@@ -848,6 +849,16 @@ using Logger = std::function<void(const Request &, const Response &)>;
848
849
849
850
using SocketOptions = std::function<void (socket_t sock)>;
850
851
852
+ namespace detail {
853
+
854
+ bool set_socket_opt_impl (socket_t sock, int level, int optname,
855
+ const void *optval, socklen_t optlen);
856
+ bool set_socket_opt (socket_t sock, int level, int optname, int opt);
857
+ bool set_socket_opt_time (socket_t sock, int level, int optname, time_t sec,
858
+ time_t usec);
859
+
860
+ } // namespace detail
861
+
851
862
void default_socket_options (socket_t sock);
852
863
853
864
const char *status_message (int status);
@@ -2075,20 +2086,45 @@ inline uint64_t Response::get_header_value_u64(const std::string &key,
2075
2086
return detail::get_header_value_u64 (headers, key, def, id);
2076
2087
}
2077
2088
2078
- inline void default_socket_options (socket_t sock) {
2079
- int opt = 1 ;
2089
+ namespace detail {
2090
+
2091
+ inline bool set_socket_opt_impl (socket_t sock, int level, int optname,
2092
+ const void *optval, socklen_t optlen) {
2093
+ return setsockopt (sock, level, optname,
2080
2094
#ifdef _WIN32
2081
- setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
2082
- reinterpret_cast <const char *>(&opt), sizeof (opt));
2095
+ reinterpret_cast <const char *>(optval),
2083
2096
#else
2084
- #ifdef SO_REUSEPORT
2085
- setsockopt (sock, SOL_SOCKET, SO_REUSEPORT,
2086
- reinterpret_cast <const void *>(&opt), sizeof (opt));
2097
+ optval,
2098
+ #endif
2099
+ optlen) == 0 ;
2100
+ }
2101
+
2102
+ inline bool set_socket_opt (socket_t sock, int level, int optname, int optval) {
2103
+ return set_socket_opt_impl (sock, level, optname, &optval, sizeof (optval));
2104
+ }
2105
+
2106
+ inline bool set_socket_opt_time (socket_t sock, int level, int optname,
2107
+ time_t sec, time_t usec) {
2108
+ #ifdef _WIN32
2109
+ auto timeout = static_cast <uint32_t >(sec * 1000 + usec / 1000 );
2087
2110
#else
2088
- setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
2089
- reinterpret_cast <const void *>(&opt), sizeof (opt));
2111
+ timeval timeout;
2112
+ timeout.tv_sec = static_cast <long >(sec);
2113
+ timeout.tv_usec = static_cast <decltype (timeout.tv_usec )>(usec);
2090
2114
#endif
2115
+ return set_socket_opt_impl (sock, level, optname, &timeout, sizeof (timeout));
2116
+ }
2117
+
2118
+ } // namespace detail
2119
+
2120
+ inline void default_socket_options (socket_t sock) {
2121
+ detail::set_socket_opt (sock, SOL_SOCKET,
2122
+ #ifdef SO_REUSEPORT
2123
+ SO_REUSEPORT,
2124
+ #else
2125
+ SO_REUSEADDR,
2091
2126
#endif
2127
+ 1 );
2092
2128
}
2093
2129
2094
2130
inline const char *status_message (int status) {
@@ -3605,26 +3641,10 @@ socket_t create_socket(const std::string &host, const std::string &ip, int port,
3605
3641
}
3606
3642
#endif
3607
3643
3608
- if (tcp_nodelay) {
3609
- auto opt = 1 ;
3610
- #ifdef _WIN32
3611
- setsockopt (sock, IPPROTO_TCP, TCP_NODELAY,
3612
- reinterpret_cast <const char *>(&opt), sizeof (opt));
3613
- #else
3614
- setsockopt (sock, IPPROTO_TCP, TCP_NODELAY,
3615
- reinterpret_cast <const void *>(&opt), sizeof (opt));
3616
- #endif
3617
- }
3644
+ if (tcp_nodelay) { set_socket_opt (sock, IPPROTO_TCP, TCP_NODELAY, 1 ); }
3618
3645
3619
3646
if (rp->ai_family == AF_INET6) {
3620
- auto opt = ipv6_v6only ? 1 : 0 ;
3621
- #ifdef _WIN32
3622
- setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY,
3623
- reinterpret_cast <const char *>(&opt), sizeof (opt));
3624
- #else
3625
- setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY,
3626
- reinterpret_cast <const void *>(&opt), sizeof (opt));
3627
- #endif
3647
+ set_socket_opt (sock, IPPROTO_IPV6, IPV6_V6ONLY, ipv6_v6only ? 1 : 0 );
3628
3648
}
3629
3649
3630
3650
if (socket_options) { socket_options (sock); }
@@ -3767,36 +3787,10 @@ inline socket_t create_client_socket(
3767
3787
}
3768
3788
3769
3789
set_nonblocking (sock2, false );
3770
-
3771
- {
3772
- #ifdef _WIN32
3773
- auto timeout = static_cast <uint32_t >(read_timeout_sec * 1000 +
3774
- read_timeout_usec / 1000 );
3775
- setsockopt (sock2, SOL_SOCKET, SO_RCVTIMEO,
3776
- reinterpret_cast <const char *>(&timeout), sizeof (timeout));
3777
- #else
3778
- timeval tv;
3779
- tv.tv_sec = static_cast <long >(read_timeout_sec);
3780
- tv.tv_usec = static_cast <decltype (tv.tv_usec )>(read_timeout_usec);
3781
- setsockopt (sock2, SOL_SOCKET, SO_RCVTIMEO,
3782
- reinterpret_cast <const void *>(&tv), sizeof (tv));
3783
- #endif
3784
- }
3785
- {
3786
-
3787
- #ifdef _WIN32
3788
- auto timeout = static_cast <uint32_t >(write_timeout_sec * 1000 +
3789
- write_timeout_usec / 1000 );
3790
- setsockopt (sock2, SOL_SOCKET, SO_SNDTIMEO,
3791
- reinterpret_cast <const char *>(&timeout), sizeof (timeout));
3792
- #else
3793
- timeval tv;
3794
- tv.tv_sec = static_cast <long >(write_timeout_sec);
3795
- tv.tv_usec = static_cast <decltype (tv.tv_usec )>(write_timeout_usec);
3796
- setsockopt (sock2, SOL_SOCKET, SO_SNDTIMEO,
3797
- reinterpret_cast <const void *>(&tv), sizeof (tv));
3798
- #endif
3799
- }
3790
+ set_socket_opt_time (sock2, SOL_SOCKET, SO_RCVTIMEO, read_timeout_sec,
3791
+ read_timeout_usec);
3792
+ set_socket_opt_time (sock2, SOL_SOCKET, SO_SNDTIMEO, write_timeout_sec,
3793
+ write_timeout_usec);
3800
3794
3801
3795
error = Error::Success;
3802
3796
return true ;
@@ -6946,35 +6940,10 @@ inline bool Server::listen_internal() {
6946
6940
break ;
6947
6941
}
6948
6942
6949
- {
6950
- #ifdef _WIN32
6951
- auto timeout = static_cast <uint32_t >(read_timeout_sec_ * 1000 +
6952
- read_timeout_usec_ / 1000 );
6953
- setsockopt (sock, SOL_SOCKET, SO_RCVTIMEO,
6954
- reinterpret_cast <const char *>(&timeout), sizeof (timeout));
6955
- #else
6956
- timeval tv;
6957
- tv.tv_sec = static_cast <long >(read_timeout_sec_);
6958
- tv.tv_usec = static_cast <decltype (tv.tv_usec )>(read_timeout_usec_);
6959
- setsockopt (sock, SOL_SOCKET, SO_RCVTIMEO,
6960
- reinterpret_cast <const void *>(&tv), sizeof (tv));
6961
- #endif
6962
- }
6963
- {
6964
-
6965
- #ifdef _WIN32
6966
- auto timeout = static_cast <uint32_t >(write_timeout_sec_ * 1000 +
6967
- write_timeout_usec_ / 1000 );
6968
- setsockopt (sock, SOL_SOCKET, SO_SNDTIMEO,
6969
- reinterpret_cast <const char *>(&timeout), sizeof (timeout));
6970
- #else
6971
- timeval tv;
6972
- tv.tv_sec = static_cast <long >(write_timeout_sec_);
6973
- tv.tv_usec = static_cast <decltype (tv.tv_usec )>(write_timeout_usec_);
6974
- setsockopt (sock, SOL_SOCKET, SO_SNDTIMEO,
6975
- reinterpret_cast <const void *>(&tv), sizeof (tv));
6976
- #endif
6977
- }
6943
+ detail::set_socket_opt_time (sock, SOL_SOCKET, SO_RCVTIMEO,
6944
+ read_timeout_sec_, read_timeout_usec_);
6945
+ detail::set_socket_opt_time (sock, SOL_SOCKET, SO_SNDTIMEO,
6946
+ write_timeout_sec_, write_timeout_usec_);
6978
6947
6979
6948
if (!task_queue->enqueue (
6980
6949
[this , sock]() { process_and_close_socket (sock); })) {
@@ -9097,11 +9066,7 @@ inline void ssl_delete(std::mutex &ctx_mutex, SSL *ssl, socket_t sock,
9097
9066
(void )(sock);
9098
9067
SSL_shutdown (ssl);
9099
9068
#else
9100
- timeval tv;
9101
- tv.tv_sec = 1 ;
9102
- tv.tv_usec = 0 ;
9103
- setsockopt (sock, SOL_SOCKET, SO_RCVTIMEO,
9104
- reinterpret_cast <const void *>(&tv), sizeof (tv));
9069
+ detail::set_socket_opt_time (sock, SOL_SOCKET, SO_RCVTIMEO, 1 , 0 );
9105
9070
9106
9071
auto ret = SSL_shutdown (ssl);
9107
9072
while (ret == 0 ) {
0 commit comments