aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/daemon.c
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2016-10-17 23:36:06 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2016-10-27 22:44:58 +0300
commitafe4f08eda64657f268e0d83e204041b2c281194 (patch)
tree659dea02756687ead904f237b07e57168e3bbfb2 /src/microhttpd/daemon.c
parentaa4da2538f101e1070b35dae41323197166fb21c (diff)
downloadlibmicrohttpd-afe4f08eda64657f268e0d83e204041b2c281194.tar.gz
libmicrohttpd-afe4f08eda64657f268e0d83e204041b2c281194.zip
process_urh(): check returned errors and prevent further reading from socket when disconnect is detected.
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r--src/microhttpd/daemon.c58
1 files changed, 42 insertions, 16 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 03bc3a17..72cf476f 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -1028,11 +1028,13 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
1028 { 1028 {
1029 urh->in_buffer_off += res; 1029 urh->in_buffer_off += res;
1030 } 1030 }
1031 if (0 == res) 1031 else if (0 >= res)
1032 { 1032 {
1033 /* connection was shut down, signal by shrinking buffer, 1033 /* Connection was shut down or got unrecoverable error.
1034 which will eventually ensure this FD is no longer listed. */ 1034 * signal by shrinking buffer so no more attempts will be
1035 urh->in_buffer_size = urh->in_buffer_off; 1035 * performed to receive data. */
1036 urh->in_buffer_size = 0;
1037 urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1036 } 1038 }
1037 } 1039 }
1038 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) && 1040 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
@@ -1055,12 +1057,16 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
1055 if ( (MHD_SCKT_ERR_IS_EINTR_ (err)) || 1057 if ( (MHD_SCKT_ERR_IS_EINTR_ (err)) ||
1056 (MHD_SCKT_ERR_IS_EAGAIN_ (err)) ) 1058 (MHD_SCKT_ERR_IS_EAGAIN_ (err)) )
1057 urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; 1059 urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1058 else 1060 else if (! MHD_SCKT_ERR_IS_LOW_RESOURCES_(err))
1059 { 1061 {
1060 /* persistent / unrecoverable error, treat as 1062 /* persistent / unrecoverable error, treat as
1061 if connection was shut down */ 1063 if connection was shut down.
1064 Do not try to receive to 'in_buffer' and
1065 discard any unsent data. */
1062 urh->in_buffer_size = 0; 1066 urh->in_buffer_size = 0;
1063 urh->in_buffer_off = 0; 1067 urh->in_buffer_off = 0;
1068 urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1069 urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1064 } 1070 }
1065 } 1071 }
1066 else 1072 else
@@ -1095,8 +1101,18 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
1095 buf_size); 1101 buf_size);
1096 if (-1 == res) 1102 if (-1 == res)
1097 { 1103 {
1098 /* FIXME: differenciate by errno? */ 1104 int err = MHD_socket_get_error_ ();
1099 urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; 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 {
1111 /* persistent / unrecoverable error, treat as
1112 if connection was shut down */
1113 urh->out_buffer_size = 0;
1114 urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1115 }
1100 } 1116 }
1101 else 1117 else
1102 { 1118 {
@@ -1104,9 +1120,11 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
1104 } 1120 }
1105 if (0 == res) 1121 if (0 == res)
1106 { 1122 {
1107 /* connection was shut down, signal by shrinking buffer, 1123 /* Connection was shut down or got unrecoverable error.
1108 which will eventually ensure this FD is no longer listed. */ 1124 * signal by shrinking buffer so no more attempts will be
1109 urh->out_buffer_size = urh->out_buffer_off; 1125 * performed to receive data. */
1126 urh->out_buffer_size = 0;
1127 urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1110 } 1128 }
1111 fin_read = (0 == res); 1129 fin_read = (0 == res);
1112 } 1130 }
@@ -1147,9 +1165,13 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
1147 else 1165 else
1148 { 1166 {
1149 /* persistent / unrecoverable error, treat as 1167 /* persistent / unrecoverable error, treat as
1150 if connection was shut down */ 1168 if connection was shut down.
1169 Do not try to receive to 'out_buffer' and
1170 discard any unsent data. */
1151 urh->out_buffer_size = 0; 1171 urh->out_buffer_size = 0;
1152 urh->out_buffer_off = 0; 1172 urh->out_buffer_off = 0;
1173 urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1174 urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1153 } 1175 }
1154 } 1176 }
1155 /* cleanup connection if it was closed and all data was sent */ 1177 /* cleanup connection if it was closed and all data was sent */
@@ -1233,8 +1255,10 @@ thread_main_connection_upgrade (struct MHD_Connection *con)
1233 &rs, 1255 &rs,
1234 &ws); 1256 &ws);
1235 process_urh (urh); 1257 process_urh (urh);
1236 if ( (0 == urh->out_buffer_size) && 1258 if ( (0 == urh->in_buffer_size) &&
1237 (0 == urh->in_buffer_size) ) 1259 (0 == urh->out_buffer_size) &&
1260 (0 == urh->in_buffer_used) &&
1261 (0 == urh->out_buffer_used) )
1238 break; /* connections died, we have no more purpose here */ 1262 break; /* connections died, we have no more purpose here */
1239 } 1263 }
1240 } 1264 }
@@ -1287,8 +1311,10 @@ thread_main_connection_upgrade (struct MHD_Connection *con)
1287 if (0 != (p[1].revents & POLLOUT)) 1311 if (0 != (p[1].revents & POLLOUT))
1288 urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY; 1312 urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
1289 process_urh (urh); 1313 process_urh (urh);
1290 if ( (0 == urh->out_buffer_size) && 1314 if ( (0 == urh->in_buffer_size) &&
1291 (0 == urh->in_buffer_size) ) 1315 (0 == urh->out_buffer_size) &&
1316 (0 == urh->in_buffer_used) &&
1317 (0 == urh->out_buffer_used) )
1292 break; /* connections died, we have no more purpose here */ 1318 break; /* connections died, we have no more purpose here */
1293 } 1319 }
1294 } 1320 }