diff options
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r-- | src/microhttpd/daemon.c | 89 |
1 files changed, 63 insertions, 26 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index 00ad2ed6..a6b1af89 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c | |||
@@ -428,9 +428,12 @@ recv_tls_adapter (struct MHD_Connection *connection, | |||
428 | { | 428 | { |
429 | ssize_t res; | 429 | ssize_t res; |
430 | 430 | ||
431 | if (i > SSIZE_MAX) | ||
432 | i = SSIZE_MAX; | ||
433 | |||
431 | res = gnutls_record_recv (connection->tls_session, | 434 | res = gnutls_record_recv (connection->tls_session, |
432 | other, | 435 | other, |
433 | (i > SSIZE_MAX) ? SSIZE_MAX : i); | 436 | i); |
434 | if ( (GNUTLS_E_AGAIN == res) || | 437 | if ( (GNUTLS_E_AGAIN == res) || |
435 | (GNUTLS_E_INTERRUPTED == res) ) | 438 | (GNUTLS_E_INTERRUPTED == res) ) |
436 | { | 439 | { |
@@ -451,6 +454,12 @@ recv_tls_adapter (struct MHD_Connection *connection, | |||
451 | return res; | 454 | return res; |
452 | } | 455 | } |
453 | 456 | ||
457 | #ifdef EPOLL_SUPPORT | ||
458 | /* If data not available to fill whole buffer - socket is not read ready anymore. */ | ||
459 | if (i > (size_t)res) | ||
460 | connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY; | ||
461 | #endif /* EPOLL_SUPPORT */ | ||
462 | |||
454 | /* Check whether TLS buffers still have some unread data. */ | 463 | /* Check whether TLS buffers still have some unread data. */ |
455 | connection->tls_read_ready = ( ((size_t)res == i) && | 464 | connection->tls_read_ready = ( ((size_t)res == i) && |
456 | (0 != gnutls_record_check_pending (connection->tls_session)) ); | 465 | (0 != gnutls_record_check_pending (connection->tls_session)) ); |
@@ -471,11 +480,14 @@ send_tls_adapter (struct MHD_Connection *connection, | |||
471 | const void *other, | 480 | const void *other, |
472 | size_t i) | 481 | size_t i) |
473 | { | 482 | { |
474 | int res; | 483 | ssize_t res; |
484 | |||
485 | if (i > SSIZE_MAX) | ||
486 | i = SSIZE_MAX; | ||
475 | 487 | ||
476 | res = gnutls_record_send (connection->tls_session, | 488 | res = gnutls_record_send (connection->tls_session, |
477 | other, | 489 | other, |
478 | (i > SSIZE_MAX) ? SSIZE_MAX : i); | 490 | i); |
479 | if ( (GNUTLS_E_AGAIN == res) || | 491 | if ( (GNUTLS_E_AGAIN == res) || |
480 | (GNUTLS_E_INTERRUPTED == res) ) | 492 | (GNUTLS_E_INTERRUPTED == res) ) |
481 | { | 493 | { |
@@ -495,6 +507,11 @@ send_tls_adapter (struct MHD_Connection *connection, | |||
495 | MHD_socket_set_error_ (MHD_SCKT_ECONNRESET_); | 507 | MHD_socket_set_error_ (MHD_SCKT_ECONNRESET_); |
496 | return -1; | 508 | return -1; |
497 | } | 509 | } |
510 | #ifdef EPOLL_SUPPORT | ||
511 | /* If NOT all available data was sent - socket is not write ready anymore. */ | ||
512 | if (i > (size_t)res) | ||
513 | connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
514 | #endif /* EPOLL_SUPPORT */ | ||
498 | return res; | 515 | return res; |
499 | } | 516 | } |
500 | 517 | ||
@@ -1075,10 +1092,10 @@ process_urh (struct MHD_UpgradeResponseHandle *urh) | |||
1075 | else if (res > 0) | 1092 | else if (res > 0) |
1076 | { | 1093 | { |
1077 | urh->in_buffer_used += res; | 1094 | urh->in_buffer_used += res; |
1078 | if (0 < gnutls_record_check_pending (connection->tls_session)) | 1095 | if (buf_size > (size_t)res) |
1079 | { | 1096 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; |
1080 | connection->tls_read_ready = true; | 1097 | else if (0 < gnutls_record_check_pending (connection->tls_session)) |
1081 | } | 1098 | connection->tls_read_ready = true; |
1082 | } | 1099 | } |
1083 | else if ( (0 >= res ) && | 1100 | else if ( (0 >= res ) && |
1084 | (GNUTLS_E_INTERRUPTED != res) ) | 1101 | (GNUTLS_E_INTERRUPTED != res) ) |
@@ -1138,6 +1155,8 @@ process_urh (struct MHD_UpgradeResponseHandle *urh) | |||
1138 | &urh->in_buffer[res], | 1155 | &urh->in_buffer[res], |
1139 | urh->in_buffer_used - res); | 1156 | urh->in_buffer_used - res); |
1140 | urh->in_buffer_used -= res; | 1157 | urh->in_buffer_used -= res; |
1158 | if (data_size > (size_t)res) | ||
1159 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
1141 | } | 1160 | } |
1142 | else | 1161 | else |
1143 | { | 1162 | { |
@@ -1193,6 +1212,8 @@ process_urh (struct MHD_UpgradeResponseHandle *urh) | |||
1193 | else | 1212 | else |
1194 | { | 1213 | { |
1195 | urh->out_buffer_used += res; | 1214 | urh->out_buffer_used += res; |
1215 | if (buf_size > (size_t)res) | ||
1216 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
1196 | } | 1217 | } |
1197 | if (0 == res) | 1218 | if (0 == res) |
1198 | { | 1219 | { |
@@ -1228,6 +1249,8 @@ process_urh (struct MHD_UpgradeResponseHandle *urh) | |||
1228 | &urh->out_buffer[res], | 1249 | &urh->out_buffer[res], |
1229 | urh->out_buffer_used - res); | 1250 | urh->out_buffer_used - res); |
1230 | urh->out_buffer_used -= res; | 1251 | urh->out_buffer_used -= res; |
1252 | if (data_size > (size_t)res) | ||
1253 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
1231 | } | 1254 | } |
1232 | else | 1255 | else |
1233 | { | 1256 | { |
@@ -1860,12 +1883,14 @@ recv_param_adapter (struct MHD_Connection *connection, | |||
1860 | other, | 1883 | other, |
1861 | i); | 1884 | i); |
1862 | #ifdef EPOLL_SUPPORT | 1885 | #ifdef EPOLL_SUPPORT |
1863 | if ( (0 > ret) && | 1886 | if (0 > ret) |
1864 | (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ())) ) | ||
1865 | { | 1887 | { |
1866 | /* Got EAGAIN --- no longer read-ready */ | 1888 | /* Got EAGAIN --- no longer read-ready */ |
1867 | connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY; | 1889 | if (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ())) |
1890 | connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY; | ||
1868 | } | 1891 | } |
1892 | else if (i > ret) | ||
1893 | connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY; | ||
1869 | #endif | 1894 | #endif |
1870 | return ret; | 1895 | return ret; |
1871 | } | 1896 | } |
@@ -1918,24 +1943,34 @@ send_param_adapter (struct MHD_Connection *connection, | |||
1918 | offsetu64 = connection->response_write_position + connection->response->fd_off; | 1943 | offsetu64 = connection->response_write_position + connection->response->fd_off; |
1919 | left = connection->response->total_size - connection->response_write_position; | 1944 | left = connection->response->total_size - connection->response_write_position; |
1920 | ret = 0; | 1945 | ret = 0; |
1921 | MHD_socket_set_error_to_ENOMEM (); | ||
1922 | #ifndef HAVE_SENDFILE64 | 1946 | #ifndef HAVE_SENDFILE64 |
1923 | offset = (off_t) offsetu64; | 1947 | if ((uint64_t)OFF_T_MAX < offsetu64) |
1924 | if ( (offsetu64 <= (uint64_t) OFF_T_MAX) && | 1948 | MHD_socket_set_error_to_ENOMEM (); |
1925 | (0 < (ret = sendfile (connection->socket_fd, | 1949 | else |
1926 | file_fd, | 1950 | { |
1927 | &offset, | 1951 | offset = (off_t) offsetu64; |
1928 | left))) ) | 1952 | ret = sendfile (connection->socket_fd, |
1953 | file_fd, | ||
1954 | &offset, | ||
1955 | left); | ||
1956 | } | ||
1929 | #else /* HAVE_SENDFILE64 */ | 1957 | #else /* HAVE_SENDFILE64 */ |
1930 | offset = (off64_t) offsetu64; | 1958 | if ((uint64_t)OFF64_T_MAX < offsetu64) |
1931 | if ( (offsetu64 <= (uint64_t) OFF64_T_MAX) && | 1959 | MHD_socket_set_error_to_ENOMEM (); |
1932 | (0 < (ret = sendfile64 (connection->socket_fd, | 1960 | else |
1933 | file_fd, | 1961 | { |
1934 | &offset, | 1962 | offset = (off64_t) offsetu64; |
1935 | left))) ) | 1963 | ret = sendfile64 (connection->socket_fd, |
1964 | file_fd, | ||
1965 | &offset, | ||
1966 | left); | ||
1967 | } | ||
1936 | #endif /* HAVE_SENDFILE64 */ | 1968 | #endif /* HAVE_SENDFILE64 */ |
1969 | if (0 < ret) | ||
1937 | { | 1970 | { |
1938 | /* write successful */ | 1971 | /* write successful */ |
1972 | if (left > ret) | ||
1973 | connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
1939 | return ret; | 1974 | return ret; |
1940 | } | 1975 | } |
1941 | err = MHD_socket_get_error_(); | 1976 | err = MHD_socket_get_error_(); |
@@ -1965,12 +2000,14 @@ send_param_adapter (struct MHD_Connection *connection, | |||
1965 | i); | 2000 | i); |
1966 | err = MHD_socket_get_error_(); | 2001 | err = MHD_socket_get_error_(); |
1967 | #ifdef EPOLL_SUPPORT | 2002 | #ifdef EPOLL_SUPPORT |
1968 | if ( (0 > ret) && | 2003 | if (0 > ret) |
1969 | (MHD_SCKT_ERR_IS_EAGAIN_(err)) ) | ||
1970 | { | 2004 | { |
1971 | /* EAGAIN --- no longer write-ready */ | 2005 | /* EAGAIN --- no longer write-ready */ |
1972 | connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; | 2006 | if (MHD_SCKT_ERR_IS_EAGAIN_(err)) |
2007 | connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
1973 | } | 2008 | } |
2009 | else if (i > ret) | ||
2010 | connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
1974 | #endif | 2011 | #endif |
1975 | /* Handle broken kernel / libc, returning -1 but not setting errno; | 2012 | /* Handle broken kernel / libc, returning -1 but not setting errno; |
1976 | kill connection as that should be safe; reported on mailinglist here: | 2013 | kill connection as that should be safe; reported on mailinglist here: |