aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r--src/microhttpd/daemon.c53
1 files changed, 37 insertions, 16 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 72cf476f..b61b3b99 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -1003,7 +1003,16 @@ MHD_cleanup_upgraded_connection_ (struct MHD_Connection *connection)
1003static void 1003static void
1004process_urh (struct MHD_UpgradeResponseHandle *urh) 1004process_urh (struct MHD_UpgradeResponseHandle *urh)
1005{ 1005{
1006 int fin_read; 1006 if (MHD_NO != urh->was_closed)
1007 {
1008 /* Application was closed connections: no more data
1009 * can be forwarded to application socket. */
1010 urh->in_buffer_size = 0;
1011 urh->in_buffer_off = 0;
1012 urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1013 /* Reading from remote client is not required anymore. */
1014 urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1015 }
1007 1016
1008 /* handle reading from TLS client and writing to application */ 1017 /* handle reading from TLS client and writing to application */
1009 if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) && 1018 if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) &&
@@ -1086,9 +1095,15 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
1086 } 1095 }
1087 1096
1088 /* handle reading from application and writing to HTTPS client */ 1097 /* handle reading from application and writing to HTTPS client */
1089 if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) && 1098 if ( ((0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) ||
1099 (MHD_NO != urh->was_closed)) &&
1090 (urh->out_buffer_off < urh->out_buffer_size) ) 1100 (urh->out_buffer_off < urh->out_buffer_size) )
1091 { 1101 {
1102 /* If application signaled MHD about socket closure then
1103 * check for any pending data even if socket is not marked
1104 * as 'ready' (signal may arrive after poll()/select()).
1105 * Socketpair for forwarding is always in non-blocking mode
1106 * so no risk that recv() will block the thread. */
1092 ssize_t res; 1107 ssize_t res;
1093 size_t buf_size; 1108 size_t buf_size;
1094 1109
@@ -1101,18 +1116,27 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
1101 buf_size); 1116 buf_size);
1102 if (-1 == res) 1117 if (-1 == res)
1103 { 1118 {
1104 int err = MHD_socket_get_error_ (); 1119 if (MHD_NO != urh->was_closed)
1105
1106 if ( (MHD_SCKT_ERR_IS_EINTR_ (err)) ||
1107 (MHD_SCKT_ERR_IS_EAGAIN_ (err)) )
1108 urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1109 else if (! MHD_SCKT_ERR_IS_LOW_RESOURCES_(err))
1110 { 1120 {
1111 /* persistent / unrecoverable error, treat as 1121 /* Connection was shuted down or all data received and
1112 if connection was shut down */ 1122 * application will not forward any more data. */
1113 urh->out_buffer_size = 0; 1123 urh->out_buffer_size = 0;
1114 urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; 1124 urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1115 } 1125 }
1126 else
1127 {
1128 const int err = MHD_socket_get_error_ ();
1129 if ( (MHD_SCKT_ERR_IS_EINTR_ (err)) ||
1130 (MHD_SCKT_ERR_IS_EAGAIN_ (err)) )
1131 urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1132 else if (! MHD_SCKT_ERR_IS_LOW_RESOURCES_(err))
1133 {
1134 /* persistent / unrecoverable error, treat as
1135 if connection was shut down */
1136 urh->out_buffer_size = 0;
1137 urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1138 }
1139 }
1116 } 1140 }
1117 else 1141 else
1118 { 1142 {
@@ -1126,10 +1150,7 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
1126 urh->out_buffer_size = 0; 1150 urh->out_buffer_size = 0;
1127 urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; 1151 urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1128 } 1152 }
1129 fin_read = (0 == res);
1130 } 1153 }
1131 else
1132 fin_read = 0;
1133 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) && 1154 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
1134 (urh->out_buffer_off > 0) ) 1155 (urh->out_buffer_off > 0) )
1135 { 1156 {
@@ -1175,9 +1196,9 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
1175 } 1196 }
1176 } 1197 }
1177 /* cleanup connection if it was closed and all data was sent */ 1198 /* cleanup connection if it was closed and all data was sent */
1178 if ( (MHD_YES == urh->was_closed) && 1199 if ( (MHD_NO != urh->was_closed) &&
1179 (0 == urh->out_buffer_off) && 1200 (0 == urh->out_buffer_size) &&
1180 (MHD_YES == fin_read) ) 1201 (0 == urh->out_buffer_off) )
1181 { 1202 {
1182 MHD_cleanup_upgraded_connection_ (urh->connection); 1203 MHD_cleanup_upgraded_connection_ (urh->connection);
1183 } 1204 }