aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/connection.c')
-rw-r--r--src/microhttpd/connection.c81
1 files changed, 41 insertions, 40 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index a5aba1b2..cee82945 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -1954,13 +1954,8 @@ call_connection_handler (struct MHD_Connection *connection)
1954static void 1954static void
1955process_request_body (struct MHD_Connection *connection) 1955process_request_body (struct MHD_Connection *connection)
1956{ 1956{
1957 uint64_t processed;
1958 size_t available; 1957 size_t available;
1959 size_t used;
1960 size_t i;
1961 size_t end_size;
1962 int instant_retry; 1958 int instant_retry;
1963 int malformed;
1964 char *buffer_head; 1959 char *buffer_head;
1965 1960
1966 if (NULL != connection->response) 1961 if (NULL != connection->response)
@@ -1970,6 +1965,10 @@ process_request_body (struct MHD_Connection *connection)
1970 available = connection->read_buffer_offset; 1965 available = connection->read_buffer_offset;
1971 do 1966 do
1972 { 1967 {
1968 size_t to_be_processed;
1969 size_t left_unprocessed;
1970 size_t processed_size;
1971
1973 instant_retry = MHD_NO; 1972 instant_retry = MHD_NO;
1974 if ( (connection->have_chunked_upload) && 1973 if ( (connection->have_chunked_upload) &&
1975 (MHD_SIZE_UNKNOWN == connection->remaining_upload_size) ) 1974 (MHD_SIZE_UNKNOWN == connection->remaining_upload_size) )
@@ -1978,6 +1977,7 @@ process_request_body (struct MHD_Connection *connection)
1978 (0LLU != connection->current_chunk_offset) && 1977 (0LLU != connection->current_chunk_offset) &&
1979 (available >= 2) ) 1978 (available >= 2) )
1980 { 1979 {
1980 size_t i;
1981 /* skip new line at the *end* of a chunk */ 1981 /* skip new line at the *end* of a chunk */
1982 i = 0; 1982 i = 0;
1983 if ( ('\r' == buffer_head[i]) || 1983 if ( ('\r' == buffer_head[i]) ||
@@ -2001,18 +2001,27 @@ process_request_body (struct MHD_Connection *connection)
2001 if (connection->current_chunk_offset < 2001 if (connection->current_chunk_offset <
2002 connection->current_chunk_size) 2002 connection->current_chunk_size)
2003 { 2003 {
2004 uint64_t cur_chunk_left;
2004 /* we are in the middle of a chunk, give 2005 /* we are in the middle of a chunk, give
2005 as much as possible to the client (without 2006 as much as possible to the client (without
2006 crossing chunk boundaries) */ 2007 crossing chunk boundaries) */
2007 processed 2008 cur_chunk_left
2008 = connection->current_chunk_size - connection->current_chunk_offset; 2009 = connection->current_chunk_size - connection->current_chunk_offset;
2009 if (processed > available) 2010 if (cur_chunk_left > available)
2010 processed = available; 2011 to_be_processed = available;
2011 if (available > processed) 2012 else
2012 instant_retry = MHD_YES; 2013 { /* cur_chunk_left <= (size_t)available */
2014 to_be_processed = (size_t)cur_chunk_left;
2015 if (available > to_be_processed)
2016 instant_retry = MHD_YES;
2017 }
2013 } 2018 }
2014 else 2019 else
2015 { 2020 {
2021 size_t i;
2022 size_t end_size;
2023 bool malformed;
2024
2016 /* we need to read chunk boundaries */ 2025 /* we need to read chunk boundaries */
2017 i = 0; 2026 i = 0;
2018 while (i < available) 2027 while (i < available)
@@ -2088,7 +2097,7 @@ process_request_body (struct MHD_Connection *connection)
2088 (MHD_SIZE_UNKNOWN != connection->remaining_upload_size) && 2097 (MHD_SIZE_UNKNOWN != connection->remaining_upload_size) &&
2089 (connection->remaining_upload_size < available) ) 2098 (connection->remaining_upload_size < available) )
2090 { 2099 {
2091 processed = (size_t)connection->remaining_upload_size; 2100 to_be_processed = (size_t)connection->remaining_upload_size;
2092 } 2101 }
2093 else 2102 else
2094 { 2103 {
@@ -2096,35 +2105,27 @@ process_request_body (struct MHD_Connection *connection)
2096 * 1. no chunked encoding, give all to the client 2105 * 1. no chunked encoding, give all to the client
2097 * 2. client may send large chunked data, but only a smaller part is available at one time. 2106 * 2. client may send large chunked data, but only a smaller part is available at one time.
2098 */ 2107 */
2099 processed = available; 2108 to_be_processed = available;
2100 } 2109 }
2101 } 2110 }
2102 used = processed; 2111 left_unprocessed = to_be_processed;
2103 connection->client_aware = true; 2112 connection->client_aware = true;
2104 { 2113 if (MHD_NO ==
2105 size_t processed_st; 2114 connection->daemon->default_handler (connection->daemon->default_handler_cls,
2106 if (processed > SIZE_MAX) 2115 connection,
2107 processed_st = SIZE_MAX; 2116 connection->url,
2108 else 2117 connection->method,
2109 processed_st = (size_t) processed; 2118 connection->version,
2110 if (MHD_NO == 2119 buffer_head,
2111 connection->daemon->default_handler (connection->daemon->default_handler_cls, 2120 &left_unprocessed,
2112 connection, 2121 &connection->client_context))
2113 connection->url,
2114 connection->method,
2115 connection->version,
2116 buffer_head,
2117 &processed_st,
2118 &connection->client_context))
2119 { 2122 {
2120 /* serious internal error, close connection */ 2123 /* serious internal error, close connection */
2121 CONNECTION_CLOSE_ERROR (connection, 2124 CONNECTION_CLOSE_ERROR (connection,
2122 _("Application reported internal error, closing connection.\n")); 2125 _("Application reported internal error, closing connection.\n"));
2123 return; 2126 return;
2124 } 2127 }
2125 processed = (uint64_t) processed_st; 2128 if (left_unprocessed > to_be_processed)
2126 }
2127 if (processed > (uint64_t)used)
2128 mhd_panic (mhd_panic_cls, 2129 mhd_panic (mhd_panic_cls,
2129 __FILE__, 2130 __FILE__,
2130 __LINE__ 2131 __LINE__
@@ -2134,27 +2135,27 @@ process_request_body (struct MHD_Connection *connection)
2134 , NULL 2135 , NULL
2135#endif 2136#endif
2136 ); 2137 );
2137 if (0 != processed) 2138 if (0 != left_unprocessed)
2138 { 2139 {
2139 instant_retry = MHD_NO; /* client did not process everything */ 2140 instant_retry = MHD_NO; /* client did not process everything */
2140#ifdef HAVE_MESSAGES 2141#ifdef HAVE_MESSAGES
2141 /* client did not process all POST data, complain if 2142 /* client did not process all upload data, complain if
2142 the setup was incorrect, which may prevent us from 2143 the setup was incorrect, which may prevent us from
2143 handling the rest of the request */ 2144 handling the rest of the request */
2144 if ( (0 != (connection->daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) && 2145 if ( (0 != (connection->daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) &&
2145 (! connection->suspended) ) 2146 (! connection->suspended) )
2146 MHD_DLOG (connection->daemon, 2147 MHD_DLOG (connection->daemon,
2147 _("WARNING: incomplete POST processing and connection not suspended will result in hung connection.\n")); 2148 _("WARNING: incomplete upload processing and connection not suspended may result in hung connection.\n"));
2148#endif 2149#endif
2149 } 2150 }
2150 used -= (size_t)processed; /* 'processed' is less than SIZE_MAX */ 2151 processed_size = to_be_processed - left_unprocessed;
2151 if (connection->have_chunked_upload) 2152 if (connection->have_chunked_upload)
2152 connection->current_chunk_offset += used; 2153 connection->current_chunk_offset += processed_size;
2153 /* dh left "processed" bytes in buffer for next time... */ 2154 /* dh left "processed" bytes in buffer for next time... */
2154 buffer_head += used; 2155 buffer_head += processed_size;
2155 available -= used; 2156 available -= processed_size;
2156 if (MHD_SIZE_UNKNOWN != connection->remaining_upload_size) 2157 if (MHD_SIZE_UNKNOWN != connection->remaining_upload_size)
2157 connection->remaining_upload_size -= used; 2158 connection->remaining_upload_size -= processed_size;
2158 } 2159 }
2159 while (MHD_YES == instant_retry); 2160 while (MHD_YES == instant_retry);
2160 if (available > 0) 2161 if (available > 0)