commit f1c69db3000e65a992e33190f3d272a5b9ca7462
parent bf9e99729c52c2462390ce1d29eeda7f0f337b26
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date: Thu, 20 Oct 2022 19:22:14 +0300
Reworked partial processing of the upload
Now if some data has been processed by Access Handler Callback, zero
timeout is used for the next turn and at the same time more data is
read (if available) from the network.
If Access Handler Callback has not processed any data, MHD will wait
for additional data to come.
Diffstat:
2 files changed, 33 insertions(+), 9 deletions(-)
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
@@ -2592,6 +2592,8 @@ MHD_connection_update_event_loop_info (struct MHD_Connection *connection)
if ( (connection->read_buffer_offset < connection->read_buffer_size) &&
(! connection->discard_request) )
connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
+ else if (connection->rq.some_payload_processed)
+ connection->event_loop_info = MHD_EVENT_LOOP_INFO_PROCESS_READ;
else
connection->event_loop_info = MHD_EVENT_LOOP_INFO_PROCESS;
break;
@@ -3448,6 +3450,8 @@ process_request_body (struct MHD_Connection *connection)
bool instant_retry;
char *buffer_head;
+ connection->rq.some_payload_processed = false;
+
if (NULL != connection->rp.response)
{
/* TODO: discard all read buffer as early response
@@ -3673,19 +3677,27 @@ process_request_body (struct MHD_Connection *connection)
}
if (left_unprocessed > to_be_processed)
MHD_PANIC (_ ("libmicrohttpd API violation.\n"));
+
+ if (left_unprocessed != to_be_processed)
+ /* Something was processed by the application. */
+ connection->rq.some_payload_processed = true;
if (0 != left_unprocessed)
{
instant_retry = false; /* client did not process everything */
#ifdef HAVE_MESSAGES
- /* client did not process all upload data, complain if
- the setup was incorrect, which may prevent us from
- handling the rest of the request */
- if ( (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) &&
- (! connection->suspended) )
- MHD_DLOG (daemon,
- _ ("WARNING: incomplete upload processing and connection " \
- "not suspended may result in hung connection.\n"));
-#endif
+ if ((left_unprocessed == to_be_processed) &&
+ (! connection->suspended))
+ {
+ /* client did not process any upload data, complain if
+ the setup was incorrect, which may prevent us from
+ handling the rest of the request */
+ if (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
+ MHD_DLOG (daemon,
+ _ ("WARNING: Access Handler Callback has not processed " \
+ "any upload data and connection is not suspended. " \
+ "This may result in hung connection.\n"));
+ }
+#endif /* HAVE_MESSAGES */
}
processed_size = to_be_processed - left_unprocessed;
if (connection->rq.have_chunked_upload)
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
@@ -1022,6 +1022,18 @@ struct MHD_Request
uint64_t current_chunk_offset;
/**
+ * Indicate that some of the upload payload data have been processed
+ * by the last call of the connection handler.
+ * If any data have been processed, but some data left in the buffer
+ * for further processing, then MHD will use zero timeout before the
+ * next data processing round.
+ * If no data have been processed, than MHD will wait for more data
+ * to come (as it makes no sense to call the connection handler with
+ * the same conditions).
+ */
+ bool some_payload_processed;
+
+ /**
* We allow the main application to associate some pointer with the
* HTTP request, which is passed to each #MHD_AccessHandlerCallback
* and some other API calls. Here is where we store it. (MHD does