diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2023-11-26 18:00:31 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2023-12-02 20:14:31 +0300 |
commit | 38599d9fab185d2673674ac3b109f73d284e7127 (patch) | |
tree | 0ff9085b75a35912467f25479f4d1dbf5a055d17 | |
parent | f09bf9eafdcb4b2bad82a62500be79a0b9ce3b22 (diff) | |
download | libmicrohttpd-38599d9fab185d2673674ac3b109f73d284e7127.tar.gz libmicrohttpd-38599d9fab185d2673674ac3b109f73d284e7127.zip |
"Upgraded" TLS connections: fixed reading last chunks when closing
-rw-r--r-- | src/microhttpd/daemon.c | 63 |
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 | /* |