diff options
Diffstat (limited to 'src/microhttpd/connection.c')
-rw-r--r-- | src/microhttpd/connection.c | 81 |
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) | |||
1954 | static void | 1954 | static void |
1955 | process_request_body (struct MHD_Connection *connection) | 1955 | process_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) |