commit 5847d13f470d525502b991f94bd5e0f77c302368
parent f5170975b4fad18e6156884aef533b137843cff3
Author: Christian Grothoff <christian@grothoff.org>
Date: Fri, 19 Jul 2019 19:19:39 +0200
inline TLS logic
Diffstat:
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;
}