Skip to content

Commit 73c048d

Browse files
committed
Fix #2111
1 parent caf9a08 commit 73c048d

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

httplib.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3218,13 +3218,31 @@ inline int poll_wrapper(struct pollfd *fds, nfds_t nfds, int timeout) {
32183218

32193219
template <bool Read>
32203220
inline ssize_t select_impl(socket_t sock, time_t sec, time_t usec) {
3221+
#ifdef __APPLE__
3222+
if (sock >= FD_SETSIZE) { return -1; }
3223+
3224+
fd_set fds, *rfds, *wfds;
3225+
FD_ZERO(&fds);
3226+
FD_SET(sock, &fds);
3227+
rfds = (Read ? &fds : nullptr);
3228+
wfds = (Read ? nullptr : &fds);
3229+
3230+
timeval tv;
3231+
tv.tv_sec = static_cast<long>(sec);
3232+
tv.tv_usec = static_cast<decltype(tv.tv_usec)>(usec);
3233+
3234+
return handle_EINTR([&]() {
3235+
return select(static_cast<int>(sock + 1), rfds, wfds, nullptr, &tv);
3236+
});
3237+
#else
32213238
struct pollfd pfd;
32223239
pfd.fd = sock;
32233240
pfd.events = (Read ? POLLIN : POLLOUT);
32243241

32253242
auto timeout = static_cast<int>(sec * 1000 + usec / 1000);
32263243

32273244
return handle_EINTR([&]() { return poll_wrapper(&pfd, 1, timeout); });
3245+
#endif
32283246
}
32293247

32303248
inline ssize_t select_read(socket_t sock, time_t sec, time_t usec) {
@@ -3237,6 +3255,36 @@ inline ssize_t select_write(socket_t sock, time_t sec, time_t usec) {
32373255

32383256
inline Error wait_until_socket_is_ready(socket_t sock, time_t sec,
32393257
time_t usec) {
3258+
#ifdef __APPLE__
3259+
if (sock >= FD_SETSIZE) { return Error::Connection; }
3260+
3261+
fd_set fdsr, fdsw;
3262+
FD_ZERO(&fdsr);
3263+
FD_ZERO(&fdsw);
3264+
FD_SET(sock, &fdsr);
3265+
FD_SET(sock, &fdsw);
3266+
3267+
timeval tv;
3268+
tv.tv_sec = static_cast<long>(sec);
3269+
tv.tv_usec = static_cast<decltype(tv.tv_usec)>(usec);
3270+
3271+
auto ret = handle_EINTR([&]() {
3272+
return select(static_cast<int>(sock + 1), &fdsr, &fdsw, nullptr, &tv);
3273+
});
3274+
3275+
if (ret == 0) { return Error::ConnectionTimeout; }
3276+
3277+
if (ret > 0 && (FD_ISSET(sock, &fdsr) || FD_ISSET(sock, &fdsw))) {
3278+
auto error = 0;
3279+
socklen_t len = sizeof(error);
3280+
auto res = getsockopt(sock, SOL_SOCKET, SO_ERROR,
3281+
reinterpret_cast<char *>(&error), &len);
3282+
auto successful = res >= 0 && !error;
3283+
return successful ? Error::Success : Error::Connection;
3284+
}
3285+
3286+
return Error::Connection;
3287+
#else
32403288
struct pollfd pfd_read;
32413289
pfd_read.fd = sock;
32423290
pfd_read.events = POLLIN | POLLOUT;
@@ -3258,6 +3306,7 @@ inline Error wait_until_socket_is_ready(socket_t sock, time_t sec,
32583306
}
32593307

32603308
return Error::Connection;
3309+
#endif
32613310
}
32623311

32633312
inline bool is_socket_alive(socket_t sock) {
@@ -7894,6 +7943,16 @@ Server::process_request(Stream &strm, const std::string &remote_addr,
78947943
res.version = "HTTP/1.1";
78957944
res.headers = default_headers_;
78967945

7946+
#ifdef __APPLE__
7947+
// Socket file descriptor exceeded FD_SETSIZE...
7948+
if (strm.socket() >= FD_SETSIZE) {
7949+
Headers dummy;
7950+
detail::read_headers(strm, dummy);
7951+
res.status = StatusCode::InternalServerError_500;
7952+
return write_response(strm, close_connection, req, res, Error::Read);
7953+
}
7954+
#endif
7955+
78977956
// Request line and headers
78987957
if (!parse_request_line(line_reader.ptr(), req) ||
78997958
!detail::read_headers(strm, req.headers)) {

0 commit comments

Comments
 (0)