aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd')
-rw-r--r--src/microhttpd/connection.c108
-rw-r--r--src/microhttpd/digestauth.c23
-rw-r--r--src/microhttpd/internal.c19
-rw-r--r--src/microhttpd/internal.h9
-rw-r--r--src/microhttpd/response.c3
5 files changed, 121 insertions, 41 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index e06ae993..4fe66805 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of libmicrohttpd 2 This file is part of libmicrohttpd
3 Copyright (C) 2007-2017 Daniel Pittman and Christian Grothoff 3 Copyright (C) 2007-2019 Daniel Pittman and Christian Grothoff
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public 6 modify it under the terms of the GNU Lesser General Public
@@ -706,7 +706,8 @@ MHD_get_connection_values (struct MHD_Connection *connection,
706 (MHD_YES != iterator (iterator_cls, 706 (MHD_YES != iterator (iterator_cls,
707 pos->kind, 707 pos->kind,
708 pos->header, 708 pos->header,
709 pos->value)) ) 709 pos->value,
710 pos->value_size)) )
710 return ret; 711 return ret;
711 } 712 }
712 return ret; 713 return ret;
@@ -733,16 +734,18 @@ MHD_get_connection_values (struct MHD_Connection *connection,
733 * @param kind kind of the value 734 * @param kind kind of the value
734 * @param key key for the value 735 * @param key key for the value
735 * @param value the value itself 736 * @param value the value itself
737 * @param value_size number of bytes in @a value
736 * @return #MHD_NO if the operation could not be 738 * @return #MHD_NO if the operation could not be
737 * performed due to insufficient memory; 739 * performed due to insufficient memory;
738 * #MHD_YES on success 740 * #MHD_YES on success
739 * @ingroup request 741 * @ingroup request
740 */ 742 */
741int 743int
742MHD_set_connection_value (struct MHD_Connection *connection, 744MHD_set_connection_value2 (struct MHD_Connection *connection,
743 enum MHD_ValueKind kind, 745 enum MHD_ValueKind kind,
744 const char *key, 746 const char *key,
745 const char *value) 747 const char *value,
748 size_t value_size)
746{ 749{
747 struct MHD_HTTP_Header *pos; 750 struct MHD_HTTP_Header *pos;
748 751
@@ -753,6 +756,7 @@ MHD_set_connection_value (struct MHD_Connection *connection,
753 return MHD_NO; 756 return MHD_NO;
754 pos->header = (char *) key; 757 pos->header = (char *) key;
755 pos->value = (char *) value; 758 pos->value = (char *) value;
759 pos->value_size = value_size;
756 pos->kind = kind; 760 pos->kind = kind;
757 pos->next = NULL; 761 pos->next = NULL;
758 /* append 'pos' to the linked list of headers */ 762 /* append 'pos' to the linked list of headers */
@@ -771,6 +775,47 @@ MHD_set_connection_value (struct MHD_Connection *connection,
771 775
772 776
773/** 777/**
778 * This function can be used to add an entry to the HTTP headers of a
779 * connection (so that the #MHD_get_connection_values function will
780 * return them -- and the `struct MHD_PostProcessor` will also see
781 * them). This maybe required in certain situations (see Mantis
782 * #1399) where (broken) HTTP implementations fail to supply values
783 * needed by the post processor (or other parts of the application).
784 *
785 * This function MUST only be called from within the
786 * #MHD_AccessHandlerCallback (otherwise, access maybe improperly
787 * synchronized). Furthermore, the client must guarantee that the key
788 * and value arguments are 0-terminated strings that are NOT freed
789 * until the connection is closed. (The easiest way to do this is by
790 * passing only arguments to permanently allocated strings.).
791 *
792 * @param connection the connection for which a
793 * value should be set
794 * @param kind kind of the value
795 * @param key key for the value
796 * @param value the value itself
797 * @return #MHD_NO if the operation could not be
798 * performed due to insufficient memory;
799 * #MHD_YES on success
800 * @ingroup request
801 */
802int
803MHD_set_connection_value (struct MHD_Connection *connection,
804 enum MHD_ValueKind kind,
805 const char *key,
806 const char *value)
807{
808 return MHD_set_connection_value2 (connection,
809 kind,
810 key,
811 value,
812 NULL != value
813 ? strlen (value)
814 : 0);
815}
816
817
818/**
774 * Get a particular header value. If multiple 819 * Get a particular header value. If multiple
775 * values match the kind, return any one of them. 820 * values match the kind, return any one of them.
776 * 821 *
@@ -2061,19 +2106,22 @@ get_next_header_line (struct MHD_Connection *connection,
2061 * @param kind kind of the value 2106 * @param kind kind of the value
2062 * @param key key for the value 2107 * @param key key for the value
2063 * @param value the value itself 2108 * @param value the value itself
2109 * @param value_size number of bytes in @a value
2064 * @return #MHD_NO on failure (out of memory), #MHD_YES for success 2110 * @return #MHD_NO on failure (out of memory), #MHD_YES for success
2065 */ 2111 */
2066static int 2112static int
2067connection_add_header (struct MHD_Connection *connection, 2113connection_add_header (struct MHD_Connection *connection,
2068 const char *key, 2114 const char *key,
2069 const char *value, 2115 const char *value,
2116 size_t value_size,
2070 enum MHD_ValueKind kind) 2117 enum MHD_ValueKind kind)
2071{ 2118{
2072 if (MHD_NO == 2119 if (MHD_NO ==
2073 MHD_set_connection_value (connection, 2120 MHD_set_connection_value2 (connection,
2074 kind, 2121 kind,
2075 key, 2122 key,
2076 value)) 2123 value,
2124 value_size))
2077 { 2125 {
2078#ifdef HAVE_MESSAGES 2126#ifdef HAVE_MESSAGES
2079 MHD_DLOG (connection->daemon, 2127 MHD_DLOG (connection->daemon,
@@ -2104,6 +2152,7 @@ parse_cookie_header (struct MHD_Connection *connection)
2104 char *semicolon; 2152 char *semicolon;
2105 char *equals; 2153 char *equals;
2106 char *ekill; 2154 char *ekill;
2155 char *end;
2107 char old; 2156 char old;
2108 int quotes; 2157 int quotes;
2109 2158
@@ -2155,6 +2204,7 @@ parse_cookie_header (struct MHD_Connection *connection)
2155 connection_add_header (connection, 2204 connection_add_header (connection,
2156 pos, 2205 pos,
2157 "", 2206 "",
2207 0,
2158 MHD_COOKIE_KIND)) 2208 MHD_COOKIE_KIND))
2159 return MHD_NO; 2209 return MHD_NO;
2160 if (old == '\0') 2210 if (old == '\0')
@@ -2174,6 +2224,7 @@ parse_cookie_header (struct MHD_Connection *connection)
2174 quotes = (quotes + 1) & 1; 2224 quotes = (quotes + 1) & 1;
2175 semicolon++; 2225 semicolon++;
2176 } 2226 }
2227 end = semicolon;
2177 if ('\0' == semicolon[0]) 2228 if ('\0' == semicolon[0])
2178 semicolon = NULL; 2229 semicolon = NULL;
2179 if (NULL != semicolon) 2230 if (NULL != semicolon)
@@ -2183,15 +2234,17 @@ parse_cookie_header (struct MHD_Connection *connection)
2183 } 2234 }
2184 /* remove quotes */ 2235 /* remove quotes */
2185 if ( ('"' == equals[0]) && 2236 if ( ('"' == equals[0]) &&
2186 ('"' == equals[strlen (equals) - 1]) ) 2237 ('"' == end[-1]) )
2187 { 2238 {
2188 equals[strlen (equals) - 1] = '\0';
2189 equals++; 2239 equals++;
2240 end--;
2241 *end = '\0';
2190 } 2242 }
2191 if (MHD_NO == 2243 if (MHD_NO ==
2192 connection_add_header (connection, 2244 connection_add_header (connection,
2193 pos, 2245 pos,
2194 equals, 2246 equals,
2247 end - equals,
2195 MHD_COOKIE_KIND)) 2248 MHD_COOKIE_KIND))
2196 return MHD_NO; 2249 return MHD_NO;
2197 pos = semicolon; 2250 pos = semicolon;
@@ -2257,7 +2310,7 @@ parse_initial_message_line (struct MHD_Connection *connection,
2257 http_version--; 2310 http_version--;
2258 if (http_version > uri) 2311 if (http_version > uri)
2259 { 2312 {
2260 /* http_version points to string before HTTP version string */ 2313 /* http_version points to character before HTTP version string */
2261 http_version[0] = '\0'; 2314 http_version[0] = '\0';
2262 connection->version = http_version + 1; 2315 connection->version = http_version + 1;
2263 uri_len = http_version - uri; 2316 uri_len = http_version - uri;
@@ -2277,24 +2330,21 @@ parse_initial_message_line (struct MHD_Connection *connection,
2277 return MHD_NO; 2330 return MHD_NO;
2278 } 2331 }
2279 2332
2280 /* unescape URI before searching for arguments */
2281 daemon->unescape_callback (daemon->unescape_callback_cls,
2282 connection,
2283 uri);
2284 uri_len = strlen (uri); /* recalculate: may have changed! */
2285 args = memchr (uri, 2333 args = memchr (uri,
2286 '?', 2334 '?',
2287 uri_len); 2335 uri_len);
2288 } 2336 }
2289 2337
2338 /* log callback before we modify URI *or* args */
2290 if (NULL != daemon->uri_log_callback) 2339 if (NULL != daemon->uri_log_callback)
2291 { 2340 {
2292 connection->client_aware = true; 2341 connection->client_aware = true;
2293 connection->client_context 2342 connection->client_context
2294 = daemon->uri_log_callback (daemon->uri_log_callback_cls, 2343 = daemon->uri_log_callback (daemon->uri_log_callback_cls,
2295 curi, 2344 uri,
2296 connection); 2345 connection);
2297 } 2346 }
2347
2298 if (NULL != args) 2348 if (NULL != args)
2299 { 2349 {
2300 args[0] = '\0'; 2350 args[0] = '\0';
@@ -2306,6 +2356,12 @@ parse_initial_message_line (struct MHD_Connection *connection,
2306 &connection_add_header, 2356 &connection_add_header,
2307 &unused_num_headers); 2357 &unused_num_headers);
2308 } 2358 }
2359
2360 /* unescape URI *after* searching for arguments and log callback */
2361 if (NULL != uri)
2362 daemon->unescape_callback (daemon->unescape_callback_cls,
2363 connection,
2364 uri);
2309 connection->url = curi; 2365 connection->url = curi;
2310 return MHD_YES; 2366 return MHD_YES;
2311} 2367}
@@ -2708,16 +2764,20 @@ process_broken_line (struct MHD_Connection *connection,
2708 REQUEST_TOO_BIG); 2764 REQUEST_TOO_BIG);
2709 return MHD_NO; 2765 return MHD_NO;
2710 } 2766 }
2711 memcpy (&last[last_len], tmp, tmp_len + 1); 2767 memcpy (&last[last_len],
2768 tmp,
2769 tmp_len + 1);
2712 connection->last = last; 2770 connection->last = last;
2713 return MHD_YES; /* possibly more than 2 lines... */ 2771 return MHD_YES; /* possibly more than 2 lines... */
2714 } 2772 }
2715 mhd_assert ( (NULL != last) && 2773 mhd_assert ( (NULL != last) &&
2716 (NULL != connection->colon) ); 2774 (NULL != connection->colon) );
2717 if ((MHD_NO == connection_add_header (connection, 2775 if (MHD_NO ==
2718 last, 2776 connection_add_header (connection,
2719 connection->colon, 2777 last,
2720 kind))) 2778 connection->colon,
2779 strlen (connection->colon),
2780 kind))
2721 { 2781 {
2722 transmit_error_response (connection, 2782 transmit_error_response (connection,
2723 MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE, 2783 MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE,
diff --git a/src/microhttpd/digestauth.c b/src/microhttpd/digestauth.c
index d4e23fef..8f04bf38 100644
--- a/src/microhttpd/digestauth.c
+++ b/src/microhttpd/digestauth.c
@@ -732,6 +732,7 @@ calculate_nonce (uint32_t nonce_time,
732 * @param connection the connection 732 * @param connection the connection
733 * @param key the key 733 * @param key the key
734 * @param value the value, can be NULL 734 * @param value the value, can be NULL
735 * @param value_size number of bytes in @a value
735 * @param kind type of the header 736 * @param kind type of the header
736 * @return #MHD_YES if the key-value pair is in the headers, 737 * @return #MHD_YES if the key-value pair is in the headers,
737 * #MHD_NO if not 738 * #MHD_NO if not
@@ -740,6 +741,7 @@ static int
740test_header (struct MHD_Connection *connection, 741test_header (struct MHD_Connection *connection,
741 const char *key, 742 const char *key,
742 const char *value, 743 const char *value,
744 size_t value_size,
743 enum MHD_ValueKind kind) 745 enum MHD_ValueKind kind)
744{ 746{
745 struct MHD_HTTP_Header *pos; 747 struct MHD_HTTP_Header *pos;
@@ -748,6 +750,8 @@ test_header (struct MHD_Connection *connection,
748 { 750 {
749 if (kind != pos->kind) 751 if (kind != pos->kind)
750 continue; 752 continue;
753 if (value_size != pos->value_size)
754 continue;
751 if (0 != strcmp (key, 755 if (0 != strcmp (key,
752 pos->header)) 756 pos->header))
753 continue; 757 continue;
@@ -756,8 +760,9 @@ test_header (struct MHD_Connection *connection,
756 return MHD_YES; 760 return MHD_YES;
757 if ( (NULL == value) || 761 if ( (NULL == value) ||
758 (NULL == pos->value) || 762 (NULL == pos->value) ||
759 (0 != strcmp (value, 763 (0 != memcmp (value,
760 pos->value)) ) 764 pos->value,
765 value_size)) )
761 continue; 766 continue;
762 return MHD_YES; 767 return MHD_YES;
763 } 768 }
@@ -862,6 +867,7 @@ digest_auth_check_all (struct MHD_Connection *connection,
862 uint32_t t; 867 uint32_t t;
863 size_t left; /* number of characters left in 'header' for 'uri' */ 868 size_t left; /* number of characters left in 'header' for 'uri' */
864 uint64_t nci; 869 uint64_t nci;
870 char *qmark;
865 871
866 VLA_CHECK_LEN_DIGEST(da->digest_size); 872 VLA_CHECK_LEN_DIGEST(da->digest_size);
867 header = MHD_lookup_connection_value (connection, 873 header = MHD_lookup_connection_value (connection,
@@ -1072,15 +1078,17 @@ digest_auth_check_all (struct MHD_Connection *connection,
1072 uri, 1078 uri,
1073 hentity, 1079 hentity,
1074 da); 1080 da);
1075 1081 qmark = strchr (uri,
1082 '?');
1083 if (NULL != qmark)
1084 *qmark = '\0';
1076 1085
1077 /* Need to unescape URI before comparing with connection->url */ 1086 /* Need to unescape URI before comparing with connection->url */
1078 daemon->unescape_callback (daemon->unescape_callback_cls, 1087 daemon->unescape_callback (daemon->unescape_callback_cls,
1079 connection, 1088 connection,
1080 uri); 1089 uri);
1081 if (0 != strncmp (uri, 1090 if (0 != strcmp (uri,
1082 connection->url, 1091 connection->url))
1083 strlen (connection->url)))
1084 { 1092 {
1085#ifdef HAVE_MESSAGES 1093#ifdef HAVE_MESSAGES
1086 MHD_DLOG (daemon, 1094 MHD_DLOG (daemon,
@@ -1091,8 +1099,7 @@ digest_auth_check_all (struct MHD_Connection *connection,
1091 } 1099 }
1092 1100
1093 { 1101 {
1094 const char *args = strchr (uri, 1102 const char *args = qmark;
1095 '?');
1096 1103
1097 if (NULL == args) 1104 if (NULL == args)
1098 args = ""; 1105 args = "";
diff --git a/src/microhttpd/internal.c b/src/microhttpd/internal.c
index d2532c54..8e9e0aac 100644
--- a/src/microhttpd/internal.c
+++ b/src/microhttpd/internal.c
@@ -162,7 +162,7 @@ MHD_http_unescape (char *val)
162 } 162 }
163 } 163 }
164 *wpos = '\0'; /* add 0-terminator */ 164 *wpos = '\0'; /* add 0-terminator */
165 return wpos - val; /* = strlen(val) */ 165 return wpos - val;
166} 166}
167 167
168 168
@@ -190,6 +190,7 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
190 struct MHD_Daemon *daemon = connection->daemon; 190 struct MHD_Daemon *daemon = connection->daemon;
191 char *equals; 191 char *equals;
192 char *amper; 192 char *amper;
193 size_t len;
193 194
194 *num_headers = 0; 195 *num_headers = 0;
195 while ( (NULL != args) && 196 while ( (NULL != args) &&
@@ -210,6 +211,7 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
210 if (MHD_YES != cb (connection, 211 if (MHD_YES != cb (connection,
211 args, 212 args,
212 NULL, 213 NULL,
214 0,
213 kind)) 215 kind))
214 return MHD_NO; 216 return MHD_NO;
215 (*num_headers)++; 217 (*num_headers)++;
@@ -223,12 +225,13 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
223 connection, 225 connection,
224 args); 226 args);
225 MHD_unescape_plus (equals); 227 MHD_unescape_plus (equals);
226 daemon->unescape_callback (daemon->unescape_callback_cls, 228 len = daemon->unescape_callback (daemon->unescape_callback_cls,
227 connection, 229 connection,
228 equals); 230 equals);
229 if (MHD_YES != cb (connection, 231 if (MHD_YES != cb (connection,
230 args, 232 args,
231 equals, 233 equals,
234 len,
232 kind)) 235 kind))
233 return MHD_NO; 236 return MHD_NO;
234 (*num_headers)++; 237 (*num_headers)++;
@@ -248,6 +251,7 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
248 if (MHD_YES != cb (connection, 251 if (MHD_YES != cb (connection,
249 args, 252 args,
250 NULL, 253 NULL,
254 0,
251 kind)) 255 kind))
252 return MHD_NO; 256 return MHD_NO;
253 /* continue with 'bar' */ 257 /* continue with 'bar' */
@@ -264,12 +268,13 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
264 connection, 268 connection,
265 args); 269 args);
266 MHD_unescape_plus (equals); 270 MHD_unescape_plus (equals);
267 daemon->unescape_callback (daemon->unescape_callback_cls, 271 len = daemon->unescape_callback (daemon->unescape_callback_cls,
268 connection, 272 connection,
269 equals); 273 equals);
270 if (MHD_YES != cb (connection, 274 if (MHD_YES != cb (connection,
271 args, 275 args,
272 equals, 276 equals,
277 len,
273 kind)) 278 kind))
274 return MHD_NO; 279 return MHD_NO;
275 (*num_headers)++; 280 (*num_headers)++;
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index d09de610..f77ebd10 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -276,6 +276,11 @@ struct MHD_HTTP_Header
276 char *value; 276 char *value;
277 277
278 /** 278 /**
279 * Number of bytes in @a value.
280 */
281 size_t value_size;
282
283 /**
279 * Type of the header (where in the HTTP protocol is this header 284 * Type of the header (where in the HTTP protocol is this header
280 * from). 285 * from).
281 */ 286 */
@@ -1881,7 +1886,8 @@ MHD_unescape_plus (char *arg);
1881 * 1886 *
1882 * @param connection context of the iteration 1887 * @param connection context of the iteration
1883 * @param key 0-terminated key string, never NULL 1888 * @param key 0-terminated key string, never NULL
1884 * @param value 0-terminated value string, may be NULL 1889 * @param value 0-terminated binary data, may include binary zeros, may be NULL
1890 * @param value_size number of bytes in value
1885 * @param kind origin of the key-value pair 1891 * @param kind origin of the key-value pair
1886 * @return #MHD_YES on success (continue to iterate) 1892 * @return #MHD_YES on success (continue to iterate)
1887 * #MHD_NO to signal failure (and abort iteration) 1893 * #MHD_NO to signal failure (and abort iteration)
@@ -1890,6 +1896,7 @@ typedef int
1890(*MHD_ArgumentIterator_)(struct MHD_Connection *connection, 1896(*MHD_ArgumentIterator_)(struct MHD_Connection *connection,
1891 const char *key, 1897 const char *key,
1892 const char *value, 1898 const char *value,
1899 size_t value_size,
1893 enum MHD_ValueKind kind); 1900 enum MHD_ValueKind kind);
1894 1901
1895 1902
diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c
index 263f8303..9f328eef 100644
--- a/src/microhttpd/response.c
+++ b/src/microhttpd/response.c
@@ -240,7 +240,8 @@ MHD_get_response_headers (struct MHD_Response *response,
240 (MHD_YES != iterator (iterator_cls, 240 (MHD_YES != iterator (iterator_cls,
241 pos->kind, 241 pos->kind,
242 pos->header, 242 pos->header,
243 pos->value))) 243 pos->value,
244 pos->value_size)))
244 break; 245 break;
245 } 246 }
246 return numHeaders; 247 return numHeaders;