aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2023-11-26 18:00:31 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2023-12-02 20:14:31 +0300
commit38599d9fab185d2673674ac3b109f73d284e7127 (patch)
tree0ff9085b75a35912467f25479f4d1dbf5a055d17
parentf09bf9eafdcb4b2bad82a62500be79a0b9ce3b22 (diff)
downloadlibmicrohttpd-38599d9fab185d2673674ac3b109f73d284e7127.tar.gz
libmicrohttpd-38599d9fab185d2673674ac3b109f73d284e7127.zip
"Upgraded" TLS connections: fixed reading last chunks when closing
-rw-r--r--src/microhttpd/daemon.c63
1 files changed, 25 insertions, 38 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 688d829d..146559b4 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -1461,6 +1461,9 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
1461 mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \ 1461 mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \
1462 MHD_thread_handle_ID_is_current_thread_ (connection->tid) ); 1462 MHD_thread_handle_ID_is_current_thread_ (connection->tid) );
1463#endif /* MHD_USE_THREADS */ 1463#endif /* MHD_USE_THREADS */
1464
1465 mhd_assert (0 != (daemon->options & MHD_USE_TLS));
1466
1464 if (daemon->shutdown) 1467 if (daemon->shutdown)
1465 { 1468 {
1466 /* Daemon shutting down, application will not receive any more data. */ 1469 /* Daemon shutting down, application will not receive any more data. */
@@ -1485,18 +1488,11 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
1485 MHD_DLOG (daemon, 1488 MHD_DLOG (daemon,
1486 _ ("Failed to forward to application %" PRIu64 \ 1489 _ ("Failed to forward to application %" PRIu64 \
1487 " bytes of data received from remote side: " \ 1490 " bytes of data received from remote side: " \
1488 "application shut down socket.\n"), 1491 "application closed data forwarding.\n"),
1489 (uint64_t) urh->in_buffer_used); 1492 (uint64_t) urh->in_buffer_used);
1490#endif 1493#endif
1491 1494
1492 } 1495 }
1493 /* If application signaled MHD about socket closure then
1494 * check for any pending data even if socket is not marked
1495 * as 'ready' (signal may arrive after poll()/select()).
1496 * Socketpair for forwarding is always in non-blocking mode
1497 * so no risk that recv() will block the thread. */
1498 if (0 != urh->out_buffer_size)
1499 urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
1500 /* Discard any data received form remote. */ 1496 /* Discard any data received form remote. */
1501 urh->in_buffer_used = 0; 1497 urh->in_buffer_used = 0;
1502 /* Do not try to push data to application. */ 1498 /* Do not try to push data to application. */
@@ -1514,17 +1510,14 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
1514 * last part of incoming data may be lost. If disconnect or error was 1510 * last part of incoming data may be lost. If disconnect or error was
1515 * detected - try to read from socket to dry data possibly pending is system 1511 * detected - try to read from socket to dry data possibly pending is system
1516 * buffers. */ 1512 * buffers. */
1517 if (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi))
1518 urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
1519 if (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi))
1520 urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
1521 1513
1522 /* 1514 /*
1523 * handle reading from remote TLS client 1515 * handle reading from remote TLS client
1524 */ 1516 */
1525 if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) || 1517 if (((0 != ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY)
1526 (connection->tls_read_ready) ) && 1518 & urh->app.celi)) ||
1527 (urh->in_buffer_used < urh->in_buffer_size) ) 1519 (connection->tls_read_ready)) &&
1520 (urh->in_buffer_used < urh->in_buffer_size))
1528 { 1521 {
1529 ssize_t res; 1522 ssize_t res;
1530 size_t buf_size; 1523 size_t buf_size;
@@ -1539,13 +1532,16 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
1539 buf_size); 1532 buf_size);
1540 if (0 >= res) 1533 if (0 >= res)
1541 { 1534 {
1535 connection->tls_read_ready = false;
1542 if (GNUTLS_E_INTERRUPTED != res) 1536 if (GNUTLS_E_INTERRUPTED != res)
1543 { 1537 {
1544 urh->app.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY); 1538 urh->app.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY);
1545 if (GNUTLS_E_AGAIN != res) 1539 if ((GNUTLS_E_AGAIN != res) ||
1540 (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi)))
1546 { 1541 {
1547 /* Unrecoverable error on socket was detected or 1542 /* TLS unrecoverable error has been detected,
1548 * socket was disconnected/shut down. */ 1543 socket error was detected and all data has been read,
1544 or socket was disconnected/shut down. */
1549 /* Stop trying to read from this TLS socket. */ 1545 /* Stop trying to read from this TLS socket. */
1550 urh->in_buffer_size = 0; 1546 urh->in_buffer_size = 0;
1551 } 1547 }
@@ -1557,21 +1553,20 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
1557 connection->tls_read_ready = 1553 connection->tls_read_ready =
1558 (0 < gnutls_record_check_pending (connection->tls_session)); 1554 (0 < gnutls_record_check_pending (connection->tls_session));
1559 } 1555 }
1560 if (MHD_EPOLL_STATE_ERROR ==
1561 ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY) & urh->app.celi))
1562 {
1563 /* Unrecoverable error on socket was detected and all
1564 * pending data was read from system buffers. */
1565 /* Stop trying to read from this TLS socket. */
1566 urh->in_buffer_size = 0;
1567 }
1568 } 1556 }
1569 1557
1570 /* 1558 /*
1571 * handle reading from application 1559 * handle reading from application
1572 */ 1560 */
1573 if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) && 1561 /* If application signalled MHD about socket closure then
1574 (urh->out_buffer_used < urh->out_buffer_size) ) 1562 * check for any pending data even if socket is not marked
1563 * as 'ready' (signal may arrive after poll()/select()).
1564 * Socketpair for forwarding is always in non-blocking mode
1565 * so no risk that recv() will block the thread. */
1566 if (((0 != ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY)
1567 & urh->mhd.celi))
1568 || was_closed) /* Force last reading from app if app has closed the connection */
1569 && (urh->out_buffer_used < urh->out_buffer_size))
1575 { 1570 {
1576 ssize_t res; 1571 ssize_t res;
1577 size_t buf_size; 1572 size_t buf_size;
@@ -1597,7 +1592,8 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
1597 (! MHD_SCKT_ERR_IS_EAGAIN_ (err))) 1592 (! MHD_SCKT_ERR_IS_EAGAIN_ (err)))
1598 { 1593 {
1599 /* Socket disconnect/shutdown was detected; 1594 /* Socket disconnect/shutdown was detected;
1600 * Application signaled about closure of 'upgraded' socket; 1595 * Application signalled about closure of 'upgraded' socket and
1596 * all data has been read from application;
1601 * or persistent / unrecoverable error. */ 1597 * or persistent / unrecoverable error. */
1602 /* Do not try to pull more data from application. */ 1598 /* Do not try to pull more data from application. */
1603 urh->out_buffer_size = 0; 1599 urh->out_buffer_size = 0;
@@ -1610,15 +1606,6 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
1610 if (buf_size > (size_t) res) 1606 if (buf_size > (size_t) res)
1611 urh->mhd.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY); 1607 urh->mhd.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY);
1612 } 1608 }
1613 if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
1614 ( (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ||
1615 (was_closed) ) )
1616 {
1617 /* Unrecoverable error on socket was detected and all
1618 * pending data was read from system buffers. */
1619 /* Do not try to pull more data from application. */
1620 urh->out_buffer_size = 0;
1621 }
1622 } 1609 }
1623 1610
1624 /* 1611 /*