libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit 5847d13f470d525502b991f94bd5e0f77c302368
parent f5170975b4fad18e6156884aef533b137843cff3
Author: Christian Grothoff <christian@grothoff.org>
Date:   Fri, 19 Jul 2019 19:19:39 +0200

inline TLS logic

Diffstat:
Msrc/microhttpd/mhd_send.c | 76+++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
1 file changed, 49 insertions(+), 27 deletions(-)

diff --git a/src/microhttpd/mhd_send.c b/src/microhttpd/mhd_send.c @@ -85,7 +85,7 @@ MHD_send_on_connection_ (struct MHD_Connection *connection, /* The socket. */ MHD_socket s = connection->socket_fd; int eno; - int ret; + ssize_t ret; int optval; const MHD_SCKT_OPT_BOOL_ off_val = 0; const MHD_SCKT_OPT_BOOL_ on_val = 1; @@ -205,11 +205,36 @@ MHD_send_on_connection_ (struct MHD_Connection *connection, #ifdef HTTPS_SUPPORT if (using_tls) { - send_tls_adapter(connection, buffer, buffer_size); + if (i > SSIZE_MAX) + i = SSIZE_MAX; + ret = gnutls_record_send (connection->tls_session, + buffer, + buffer_size); + if ( (GNUTLS_E_AGAIN == ret) || + (GNUTLS_E_INTERRUPTED == ret) ) + { +#ifdef EPOLL_SUPPORT + if (GNUTLS_E_AGAIN == ret) + connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; +#endif + return MHD_ERR_AGAIN_; + } + if (ret < 0) + { + /* Likely 'GNUTLS_E_INVALID_SESSION' (client communication + disrupted); interpret as a hard error */ + return MHD_ERR_NOTCONN_; + } +#ifdef EPOLL_SUPPORT + /* Unlike non-TLS connections, do not reset "write-ready" if + * sent amount smaller than provided amount, as TLS + * connections may break data into smaller parts for sending. */ +#endif /* EPOLL_SUPPORT */ } else #endif { + /* plaintext transmission */ #if MSG_MORE ret = send (connection->socket_fd, buffer, @@ -218,6 +243,28 @@ MHD_send_on_connection_ (struct MHD_Connection *connection, #else ret = send (connection->socket_fd, buffer, buffer_size, 0); #endif + + if (0 > ret) + { + if (MHD_SCKT_ERR_IS_EAGAIN_ (err)) + { +#if EPOLL_SUPPORT + /* EAGAIN, no longer write-ready */ + connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; +#endif /* EPOLL_SUPPORT */ + return MHD_ERR_AGAIN_; + } + if (MHD_SCKT_ERR_IS_EINTR_ (err)) + return MHD_ERR_AGAIN_; + if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ECONNRESET_)) + return MHD_ERR_CONNRESET_; + /* Treat any other error as hard error. */ + return MHD_ERR_NOTCONN_; + } +#if EPOLL_SUPPORT + else if (buffer_size > (size_t) ret) + connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; +#endif /* EPOLL_SUPPORT */ } #if TCP_CORK if (use_corknopush) @@ -273,31 +320,6 @@ MHD_send_on_connection_ (struct MHD_Connection *connection, gnutls_record_uncork(connection->tls_session); */ - // shouldn't we return 0 or -1? Why re-use the _ERR_ functions? - // error handling from send_param_adapter(): - if (0 > ret) - { - if (MHD_SCKT_ERR_IS_EAGAIN_ (err)) - { -#if EPOLL_SUPPORT - /* EAGAIN, no longer write-ready */ - connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; -#endif /* EPOLL_SUPPORT */ - return MHD_ERR_AGAIN_; - } - if (MHD_SCKT_ERR_IS_EINTR_ (err)) - return MHD_ERR_AGAIN_; - if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ECONNRESET_)) - return MHD_ERR_CONNRESET_; - /* Treat any other error as hard error. */ - return MHD_ERR_NOTCONN_; - } -#if EPOLL_SUPPORT - else if (buffer_size > (size_t) ret) - connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; -#endif /* EPOLL_SUPPORT */ - // return ret; // should be return at the end of the function? - // previous error save: errno = eno; return ret; }