aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2021-08-21 16:39:35 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2021-08-21 18:35:20 +0300
commit4fb57ae153ddd856c80885425eb2321cd95a2cf0 (patch)
tree794757846326cd4f8ea182f20539ff5f31b7e5e8
parent55785fe949779a18c461000ce0b4356f790fb8c5 (diff)
downloadlibmicrohttpd-4fb57ae153ddd856c80885425eb2321cd95a2cf0.tar.gz
libmicrohttpd-4fb57ae153ddd856c80885425eb2321cd95a2cf0.zip
Added new connection flag "stop_with_error".
Stopped usage of "read_close" flag when read hasn't been closed.
-rw-r--r--src/microhttpd/connection.c59
-rw-r--r--src/microhttpd/internal.h12
2 files changed, 43 insertions, 28 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index a01ca32e..7b61916f 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -829,6 +829,7 @@ connection_close_error (struct MHD_Connection *connection,
829 const char *emsg) 829 const char *emsg)
830{ 830{
831#ifdef HAVE_MESSAGES 831#ifdef HAVE_MESSAGES
832 connection->stop_with_error = true;
832 if (NULL != emsg) 833 if (NULL != emsg)
833 MHD_DLOG (connection->daemon, 834 MHD_DLOG (connection->daemon,
834 "%s\n", 835 "%s\n",
@@ -865,7 +866,8 @@ connection_close_error_check (struct MHD_Connection *connection,
865{ 866{
866 if ( (NULL != connection->response) && 867 if ( (NULL != connection->response) &&
867 (400 <= connection->responseCode) && 868 (400 <= connection->responseCode) &&
868 (connection->read_closed) && 869 (NULL == connection->response->crc) && /* Static response only! */
870 (connection->stop_with_error) &&
869 (MHD_CONNECTION_HEADERS_SENDING == connection->state) ) 871 (MHD_CONNECTION_HEADERS_SENDING == connection->state) )
870 return; /* An error response was already queued */ 872 return; /* An error response was already queued */
871 873
@@ -1188,9 +1190,7 @@ keepalive_possible (struct MHD_Connection *connection)
1188 } 1190 }
1189#endif /* UPGRADE_SUPPORT */ 1191#endif /* UPGRADE_SUPPORT */
1190 1192
1191 /* TODO: use additional flags, like "error_closure" or 1193 if ((c->read_closed) || (c->stop_with_error))
1192 * "! read_completed" */
1193 if (c->read_closed)
1194 return MHD_CONN_MUST_CLOSE; 1194 return MHD_CONN_MUST_CLOSE;
1195 1195
1196 if (0 != (r->flags & MHD_RF_HTTP_1_0_COMPATIBLE_STRICT)) 1196 if (0 != (r->flags & MHD_RF_HTTP_1_0_COMPATIBLE_STRICT))
@@ -2126,7 +2126,7 @@ transmit_error_response_len (struct MHD_Connection *connection,
2126 enum MHD_Result iret; 2126 enum MHD_Result iret;
2127 2127
2128 connection->state = MHD_CONNECTION_FOOTERS_RECEIVED; 2128 connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
2129 connection->read_closed = true; 2129 connection->stop_with_error = true;
2130 if (0 != connection->read_buffer_size) 2130 if (0 != connection->read_buffer_size)
2131 { 2131 {
2132 /* Read buffer is not needed anymore, discard it 2132 /* Read buffer is not needed anymore, discard it
@@ -2254,7 +2254,7 @@ MHD_connection_update_event_loop_info (struct MHD_Connection *connection)
2254 REQUEST_TOO_BIG); 2254 REQUEST_TOO_BIG);
2255 continue; 2255 continue;
2256 } 2256 }
2257 if (! connection->read_closed) 2257 if (! connection->stop_with_error)
2258 connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ; 2258 connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
2259 else 2259 else
2260 connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK; 2260 connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
@@ -2294,7 +2294,7 @@ MHD_connection_update_event_loop_info (struct MHD_Connection *connection)
2294 } 2294 }
2295 } 2295 }
2296 if ( (connection->read_buffer_offset < connection->read_buffer_size) && 2296 if ( (connection->read_buffer_offset < connection->read_buffer_size) &&
2297 (! connection->read_closed) ) 2297 (! connection->stop_with_error) )
2298 connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ; 2298 connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
2299 else 2299 else
2300 connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK; 2300 connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
@@ -2303,7 +2303,7 @@ MHD_connection_update_event_loop_info (struct MHD_Connection *connection)
2303 case MHD_CONNECTION_FOOTER_PART_RECEIVED: 2303 case MHD_CONNECTION_FOOTER_PART_RECEIVED:
2304 /* while reading footers, we always grow the 2304 /* while reading footers, we always grow the
2305 read buffer if needed, no size-check required */ 2305 read buffer if needed, no size-check required */
2306 if (connection->read_closed) 2306 if (connection->stop_with_error)
2307 { 2307 {
2308 CONNECTION_CLOSE_ERROR (connection, 2308 CONNECTION_CLOSE_ERROR (connection,
2309 NULL); 2309 NULL);
@@ -2930,8 +2930,9 @@ process_request_body (struct MHD_Connection *connection)
2930 { 2930 {
2931 /* malformed encoding */ 2931 /* malformed encoding */
2932 CONNECTION_CLOSE_ERROR (connection, 2932 CONNECTION_CLOSE_ERROR (connection,
2933 _ ( 2933 _ ("Received malformed HTTP request " \
2934 "Received malformed HTTP request (bad chunked encoding). Closing connection.")); 2934 "(bad chunked encoding). " \
2935 "Closing connection."));
2935 return; 2936 return;
2936 } 2937 }
2937 available -= i; 2938 available -= i;
@@ -3009,8 +3010,9 @@ process_request_body (struct MHD_Connection *connection)
3009 { 3010 {
3010 /* malformed encoding */ 3011 /* malformed encoding */
3011 CONNECTION_CLOSE_ERROR (connection, 3012 CONNECTION_CLOSE_ERROR (connection,
3012 _ ( 3013 _ ("Received malformed HTTP request " \
3013 "Received malformed HTTP request (bad chunked encoding). Closing connection.")); 3014 "(bad chunked encoding). " \
3015 "Closing connection."));
3014 return; 3016 return;
3015 } 3017 }
3016 /* skip 2nd part of line feed */ 3018 /* skip 2nd part of line feed */
@@ -3065,8 +3067,8 @@ process_request_body (struct MHD_Connection *connection)
3065 { 3067 {
3066 /* serious internal error, close connection */ 3068 /* serious internal error, close connection */
3067 CONNECTION_CLOSE_ERROR (connection, 3069 CONNECTION_CLOSE_ERROR (connection,
3068 _ ( 3070 _ ("Application reported internal error, " \
3069 "Application reported internal error, closing connection.")); 3071 "closing connection."));
3070 return; 3072 return;
3071 } 3073 }
3072 if (left_unprocessed > to_be_processed) 3074 if (left_unprocessed > to_be_processed)
@@ -3089,8 +3091,8 @@ process_request_body (struct MHD_Connection *connection)
3089 if ( (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) && 3091 if ( (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) &&
3090 (! connection->suspended) ) 3092 (! connection->suspended) )
3091 MHD_DLOG (daemon, 3093 MHD_DLOG (daemon,
3092 _ ( 3094 _ ("WARNING: incomplete upload processing and connection " \
3093 "WARNING: incomplete upload processing and connection not suspended may result in hung connection.\n")); 3095 "not suspended may result in hung connection.\n"));
3094#endif 3096#endif
3095 } 3097 }
3096 processed_size = to_be_processed - left_unprocessed; 3098 processed_size = to_be_processed - left_unprocessed;
@@ -3326,7 +3328,7 @@ parse_connection_headers (struct MHD_Connection *connection)
3326 3328
3327 /* die, http 1.1 request without host and we are pedantic */ 3329 /* die, http 1.1 request without host and we are pedantic */
3328 connection->state = MHD_CONNECTION_FOOTERS_RECEIVED; 3330 connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
3329 connection->read_closed = true; 3331 connection->stop_with_error = true;
3330#ifdef HAVE_MESSAGES 3332#ifdef HAVE_MESSAGES
3331 MHD_DLOG (connection->daemon, 3333 MHD_DLOG (connection->daemon,
3332 _ ("Received HTTP 1.1 request without `Host' header.\n")); 3334 _ ("Received HTTP 1.1 request without `Host' header.\n"));
@@ -3535,7 +3537,7 @@ MHD_connection_handle_read (struct MHD_Connection *connection)
3535 case MHD_CONNECTION_BODY_RECEIVED: 3537 case MHD_CONNECTION_BODY_RECEIVED:
3536 case MHD_CONNECTION_FOOTER_PART_RECEIVED: 3538 case MHD_CONNECTION_FOOTER_PART_RECEIVED:
3537 /* nothing to do but default action */ 3539 /* nothing to do but default action */
3538 if (connection->read_closed) 3540 if ((connection->read_closed) || (connection->stop_with_error))
3539 { 3541 {
3540 MHD_connection_close_ (connection, 3542 MHD_connection_close_ (connection,
3541 MHD_REQUEST_TERMINATED_READ_ERROR); 3543 MHD_REQUEST_TERMINATED_READ_ERROR);
@@ -4111,7 +4113,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
4111 { 4113 {
4112 if (MHD_CONNECTION_INIT != connection->state) 4114 if (MHD_CONNECTION_INIT != connection->state)
4113 continue; 4115 continue;
4114 if (connection->read_closed) 4116 if (connection->stop_with_error)
4115 { 4117 {
4116 CONNECTION_CLOSE_ERROR (connection, 4118 CONNECTION_CLOSE_ERROR (connection,
4117 NULL); 4119 NULL);
@@ -4137,7 +4139,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
4137 { 4139 {
4138 if (MHD_CONNECTION_URL_RECEIVED != connection->state) 4140 if (MHD_CONNECTION_URL_RECEIVED != connection->state)
4139 continue; 4141 continue;
4140 if (connection->read_closed) 4142 if (connection->stop_with_error)
4141 { 4143 {
4142 CONNECTION_CLOSE_ERROR (connection, 4144 CONNECTION_CLOSE_ERROR (connection,
4143 NULL); 4145 NULL);
@@ -4169,7 +4171,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
4169 { 4171 {
4170 if (connection->state != MHD_CONNECTION_HEADER_PART_RECEIVED) 4172 if (connection->state != MHD_CONNECTION_HEADER_PART_RECEIVED)
4171 continue; 4173 continue;
4172 if (connection->read_closed) 4174 if (connection->stop_with_error)
4173 { 4175 {
4174 CONNECTION_CLOSE_ERROR (connection, 4176 CONNECTION_CLOSE_ERROR (connection,
4175 NULL); 4177 NULL);
@@ -4216,7 +4218,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
4216 /* we refused (no upload allowed!) */ 4218 /* we refused (no upload allowed!) */
4217 connection->remaining_upload_size = 0; 4219 connection->remaining_upload_size = 0;
4218 /* force close, in case client still tries to upload... */ 4220 /* force close, in case client still tries to upload... */
4219 connection->read_closed = true; 4221 connection->stop_with_error = true;
4220 } 4222 }
4221 connection->state = (0 == connection->remaining_upload_size) 4223 connection->state = (0 == connection->remaining_upload_size)
4222 ? MHD_CONNECTION_FOOTERS_RECEIVED 4224 ? MHD_CONNECTION_FOOTERS_RECEIVED
@@ -4242,10 +4244,10 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
4242 if ( (0 == connection->remaining_upload_size) || 4244 if ( (0 == connection->remaining_upload_size) ||
4243 ( (MHD_SIZE_UNKNOWN == connection->remaining_upload_size) && 4245 ( (MHD_SIZE_UNKNOWN == connection->remaining_upload_size) &&
4244 (0 == connection->read_buffer_offset) && 4246 (0 == connection->read_buffer_offset) &&
4245 (connection->read_closed) ) ) 4247 (connection->stop_with_error) ) )
4246 { 4248 {
4247 if ( (connection->have_chunked_upload) && 4249 if ( (connection->have_chunked_upload) &&
4248 (! connection->read_closed) ) 4250 (! connection->stop_with_error) )
4249 connection->state = MHD_CONNECTION_BODY_RECEIVED; 4251 connection->state = MHD_CONNECTION_BODY_RECEIVED;
4250 else 4252 else
4251 connection->state = MHD_CONNECTION_FOOTERS_RECEIVED; 4253 connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
@@ -4261,7 +4263,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
4261 { 4263 {
4262 if (connection->state != MHD_CONNECTION_BODY_RECEIVED) 4264 if (connection->state != MHD_CONNECTION_BODY_RECEIVED)
4263 continue; 4265 continue;
4264 if (connection->read_closed) 4266 if (connection->stop_with_error)
4265 { 4267 {
4266 CONNECTION_CLOSE_ERROR (connection, 4268 CONNECTION_CLOSE_ERROR (connection,
4267 NULL); 4269 NULL);
@@ -4293,7 +4295,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
4293 { 4295 {
4294 if (connection->state != MHD_CONNECTION_FOOTER_PART_RECEIVED) 4296 if (connection->state != MHD_CONNECTION_FOOTER_PART_RECEIVED)
4295 continue; 4297 continue;
4296 if (connection->read_closed) 4298 if (connection->stop_with_error)
4297 { 4299 {
4298 CONNECTION_CLOSE_ERROR (connection, 4300 CONNECTION_CLOSE_ERROR (connection,
4299 NULL); 4301 NULL);
@@ -4471,7 +4473,8 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
4471 /* Reset connection after complete reply */ 4473 /* Reset connection after complete reply */
4472 connection_reset (connection, 4474 connection_reset (connection,
4473 MHD_CONN_USE_KEEPALIVE == connection->keepalive && 4475 MHD_CONN_USE_KEEPALIVE == connection->keepalive &&
4474 ! connection->read_closed); 4476 ! connection->read_closed &&
4477 ! connection->stop_with_error);
4475 continue; 4478 continue;
4476 case MHD_CONNECTION_CLOSED: 4479 case MHD_CONNECTION_CLOSED:
4477 cleanup_connection (connection); 4480 cleanup_connection (connection);
@@ -4881,7 +4884,7 @@ MHD_queue_response (struct MHD_Connection *connection,
4881 { 4884 {
4882 /* response was queued "early", refuse to read body / footers or 4885 /* response was queued "early", refuse to read body / footers or
4883 further requests! */ 4886 further requests! */
4884 connection->read_closed = true; 4887 connection->stop_with_error = true;
4885 connection->state = MHD_CONNECTION_FOOTERS_RECEIVED; 4888 connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
4886 connection->remaining_upload_size = 0; 4889 connection->remaining_upload_size = 0;
4887 } 4890 }
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index 60d1862d..a2a454f1 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -1186,6 +1186,18 @@ struct MHD_Connection
1186 */ 1186 */
1187 bool read_closed; 1187 bool read_closed;
1188 1188
1189 /**
1190 * Some error happens during processing the connection therefore this
1191 * connection must be closed.
1192 * The error may come from the client side (like wrong request format),
1193 * from the application side (like data callback returned error), or from
1194 * the OS side (like out-of-memory).
1195 * The connection cannot be reused for additional requests as the current
1196 * request may be incompletely read and it is unclear where is the initial
1197 * byte of the next request.
1198 */
1199 bool stop_with_error;
1200
1189#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 1201#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1190 /** 1202 /**
1191 * Set to `true` if the thread has been joined. 1203 * Set to `true` if the thread has been joined.