Partial revert of 1b610e5b13.

Implemented new functions for key and value with binary zero.
Significantly speedup search for key by using key size.
This commit is contained in:
Evgeny Grin (Karlson2k)
2019-05-01 22:12:24 +03:00
parent 08ea0cc894
commit 8aa7d23219
11 changed files with 185 additions and 88 deletions
+5 -12
View File
@@ -15,16 +15,11 @@
static int
print_out_key (void *cls,
enum MHD_ValueKind kind,
const char *key,
const char *value,
size_t value_size)
print_out_key (void *cls, enum MHD_ValueKind kind, const char *key,
const char *value)
{
(void) cls; /* Unused. Silent compiler warning. */
(void) kind; /* Unused. Silent compiler warning. */
(void) value_size;
(void)cls; /* Unused. Silent compiler warning. */
(void)kind; /* Unused. Silent compiler warning. */
printf ("%s: %s\n", key, value);
return MHD_YES;
}
@@ -43,9 +38,7 @@ answer_to_connection (void *cls, struct MHD_Connection *connection,
(void)con_cls; /* Unused. Silent compiler warning. */
printf ("New %s request for %s using version %s\n", method, url, version);
MHD_get_connection_values (connection,
MHD_HEADER_KIND,
&print_out_key,
MHD_get_connection_values (connection, MHD_HEADER_KIND, print_out_key,
NULL);
return MHD_NO;
+35 -9
View File
@@ -128,7 +128,7 @@ typedef intptr_t ssize_t;
* Current version of the library.
* 0x01093001 = 1.9.30-1.
*/
#define MHD_VERSION 0x00096302
#define MHD_VERSION 0x00096303
/**
* MHD-internal return code for "YES".
@@ -2041,8 +2041,6 @@ typedef void
* @param kind kind of the header we are looking at
* @param key key for the value, can be an empty string
* @param value corresponding value, can be NULL
* @param value_size number of bytes in @a value, NEW since #MHD_VERSION 0x00096301;
* for C-strings, the length excludes the 0-terminator
* @return #MHD_YES to continue iterating,
* #MHD_NO to abort the iteration
* @ingroup request
@@ -2051,8 +2049,34 @@ typedef int
(*MHD_KeyValueIterator) (void *cls,
enum MHD_ValueKind kind,
const char *key,
const char *value);
/**
* Iterator over key-value pairs with size parameters.
* This iterator can be used to iterate over all of
* the cookies, headers, or POST-data fields of a
* request, and also to iterate over the headers that
* have been added to a response.
* @note Available since #MHD_VERSION 0x00096303
*
* @param cls closure
* @param kind kind of the header we are looking at
* @param key key for the value, can be an empty string
* @param value corresponding value, can be NULL
* @param value_size number of bytes in @a value, NEW since #MHD_VERSION 0x00096301;
* for C-strings, the length excludes the 0-terminator
* @return #MHD_YES to continue iterating,
* #MHD_NO to abort the iteration
* @ingroup request
*/
typedef int
(*MHD_KeyValueIteratorN) (void *cls,
enum MHD_ValueKind kind,
const char *key,
size_t key_size,
const char *value,
size_t value_size);
size_t value_size);
/**
@@ -2531,6 +2555,7 @@ MHD_set_connection_value (struct MHD_Connection *connection,
* value should be set
* @param kind kind of the value
* @param key key for the value
* @param key_size number of bytes in @a key (excluding 0-terminator for C-strings)
* @param value the value itself
* @param value_size number of bytes in @a value (excluding 0-terminator for C-strings)
* @return #MHD_NO if the operation could not be
@@ -2539,11 +2564,12 @@ MHD_set_connection_value (struct MHD_Connection *connection,
* @ingroup request
*/
int
MHD_set_connection_value2 (struct MHD_Connection *connection,
enum MHD_ValueKind kind,
const char *key,
const char *value,
size_t value_size);
MHD_set_connection_value_n (struct MHD_Connection *connection,
enum MHD_ValueKind kind,
const char *key,
size_t key_size,
const char *value,
size_t value_size);
/**
+31 -20
View File
@@ -706,8 +706,7 @@ MHD_get_connection_values (struct MHD_Connection *connection,
(MHD_YES != iterator (iterator_cls,
pos->kind,
pos->header,
pos->value,
pos->value_size)) )
pos->value)) )
return ret;
}
return ret;
@@ -733,19 +732,21 @@ MHD_get_connection_values (struct MHD_Connection *connection,
* value should be set
* @param kind kind of the value
* @param key key for the value
* @param key_size number of bytes in @a key (excluding 0-terminator for C-strings)
* @param value the value itself
* @param value_size number of bytes in @a value
* @param value_size number of bytes in @a value (excluding 0-terminator for C-strings)
* @return #MHD_NO if the operation could not be
* performed due to insufficient memory;
* #MHD_YES on success
* @ingroup request
*/
int
MHD_set_connection_value2 (struct MHD_Connection *connection,
enum MHD_ValueKind kind,
const char *key,
const char *value,
size_t value_size)
MHD_set_connection_value_n (struct MHD_Connection *connection,
enum MHD_ValueKind kind,
const char *key,
size_t key_size,
const char *value,
size_t value_size)
{
struct MHD_HTTP_Header *pos;
@@ -755,6 +756,7 @@ MHD_set_connection_value2 (struct MHD_Connection *connection,
if (NULL == pos)
return MHD_NO;
pos->header = (char *) key;
pos->header_size = key_size;
pos->value = (char *) value;
pos->value_size = value_size;
pos->kind = kind;
@@ -805,13 +807,16 @@ MHD_set_connection_value (struct MHD_Connection *connection,
const char *key,
const char *value)
{
return MHD_set_connection_value2 (connection,
kind,
key,
value,
NULL != value
? strlen (value)
: 0);
return MHD_set_connection_value_n (connection,
kind,
key,
NULL != key
? strlen (key)
: 0,
value,
NULL != value
? strlen (value)
: 0);
}
@@ -2105,6 +2110,7 @@ get_next_header_line (struct MHD_Connection *connection,
* value should be set
* @param kind kind of the value
* @param key key for the value
* @param key_size number of bytes in @a key
* @param value the value itself
* @param value_size number of bytes in @a value
* @return #MHD_NO on failure (out of memory), #MHD_YES for success
@@ -2112,16 +2118,18 @@ get_next_header_line (struct MHD_Connection *connection,
static int
connection_add_header (struct MHD_Connection *connection,
const char *key,
size_t key_size,
const char *value,
size_t value_size,
enum MHD_ValueKind kind)
{
if (MHD_NO ==
MHD_set_connection_value2 (connection,
kind,
key,
value,
value_size))
MHD_set_connection_value_n (connection,
kind,
key,
key_size,
value,
value_size))
{
#ifdef HAVE_MESSAGES
MHD_DLOG (connection->daemon,
@@ -2203,6 +2211,7 @@ parse_cookie_header (struct MHD_Connection *connection)
if (MHD_NO ==
connection_add_header (connection,
pos,
ekill - pos + 1,
"",
0,
MHD_COOKIE_KIND))
@@ -2243,6 +2252,7 @@ parse_cookie_header (struct MHD_Connection *connection)
if (MHD_NO ==
connection_add_header (connection,
pos,
ekill - pos + 1,
equals,
end - equals,
MHD_COOKIE_KIND))
@@ -2774,6 +2784,7 @@ process_broken_line (struct MHD_Connection *connection,
if (MHD_NO ==
connection_add_header (connection,
last,
strlen (last),
connection->colon,
strlen (connection->colon),
kind))
+8 -3
View File
@@ -731,6 +731,7 @@ calculate_nonce (uint32_t nonce_time,
*
* @param connection the connection
* @param key the key
* @param key_size number of bytes in @a key
* @param value the value, can be NULL
* @param value_size number of bytes in @a value
* @param kind type of the header
@@ -740,6 +741,7 @@ calculate_nonce (uint32_t nonce_time,
static int
test_header (struct MHD_Connection *connection,
const char *key,
size_t key_size,
const char *value,
size_t value_size,
enum MHD_ValueKind kind)
@@ -750,10 +752,13 @@ test_header (struct MHD_Connection *connection,
{
if (kind != pos->kind)
continue;
if (value_size != pos->value_size)
if (key_size != pos->header_size)
continue;
if (0 != strcmp (key,
pos->header))
if (value_size != pos->value_size)
continue;
if (0 != memcmp (key,
pos->header,
key_size))
continue;
if ( (NULL == value) &&
(NULL == pos->value) )
+26 -21
View File
@@ -190,12 +190,13 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
struct MHD_Daemon *daemon = connection->daemon;
char *equals;
char *amper;
size_t len;
*num_headers = 0;
while ( (NULL != args) &&
('\0' != args[0]) )
{
size_t key_len;
size_t value_len;
equals = strchr (args, '=');
amper = strchr (args, '&');
if (NULL == amper)
@@ -205,11 +206,12 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
{
/* last argument, without '=' */
MHD_unescape_plus (args);
daemon->unescape_callback (daemon->unescape_callback_cls,
connection,
args);
key_len = daemon->unescape_callback (daemon->unescape_callback_cls,
connection,
args);
if (MHD_YES != cb (connection,
args,
key_len,
NULL,
0,
kind))
@@ -221,17 +223,18 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
equals[0] = '\0';
equals++;
MHD_unescape_plus (args);
daemon->unescape_callback (daemon->unescape_callback_cls,
connection,
args);
key_len = daemon->unescape_callback (daemon->unescape_callback_cls,
connection,
args);
MHD_unescape_plus (equals);
len = daemon->unescape_callback (daemon->unescape_callback_cls,
connection,
equals);
value_len = daemon->unescape_callback (daemon->unescape_callback_cls,
connection,
equals);
if (MHD_YES != cb (connection,
args,
key_len,
equals,
len,
value_len,
kind))
return MHD_NO;
(*num_headers)++;
@@ -245,11 +248,12 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
{
/* got 'foo&bar' or 'foo&bar=val', add key 'foo' with NULL for value */
MHD_unescape_plus (args);
daemon->unescape_callback (daemon->unescape_callback_cls,
connection,
args);
key_len = daemon->unescape_callback (daemon->unescape_callback_cls,
connection,
args);
if (MHD_YES != cb (connection,
args,
key_len,
NULL,
0,
kind))
@@ -264,17 +268,18 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
equals[0] = '\0';
equals++;
MHD_unescape_plus (args);
daemon->unescape_callback (daemon->unescape_callback_cls,
connection,
args);
key_len = daemon->unescape_callback (daemon->unescape_callback_cls,
connection,
args);
MHD_unescape_plus (equals);
len = daemon->unescape_callback (daemon->unescape_callback_cls,
connection,
equals);
value_len = daemon->unescape_callback (daemon->unescape_callback_cls,
connection,
equals);
if (MHD_YES != cb (connection,
args,
key_len,
equals,
len,
value_len,
kind))
return MHD_NO;
(*num_headers)++;
+15 -3
View File
@@ -270,6 +270,11 @@ struct MHD_HTTP_Header
*/
char *header;
/**
* Number of bytes in @a header.
*/
size_t header_size;
/**
* The value of the header.
*/
@@ -1886,6 +1891,7 @@ MHD_unescape_plus (char *arg);
*
* @param connection context of the iteration
* @param key 0-terminated key string, never NULL
* @param key_size number of bytes in key
* @param value 0-terminated binary data, may include binary zeros, may be NULL
* @param value_size number of bytes in value
* @param kind origin of the key-value pair
@@ -1895,6 +1901,7 @@ MHD_unescape_plus (char *arg);
typedef int
(*MHD_ArgumentIterator_)(struct MHD_Connection *connection,
const char *key,
size_t key_size,
const char *value,
size_t value_size,
enum MHD_ValueKind kind);
@@ -1923,14 +1930,17 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
/**
* Check whether response header contains particular @a token.
* Check whether response header contains particular token.
*
* Token could be surrounded by spaces and tabs and delimited by comma.
* Case-insensitive match used for header names and tokens.
*
* @param response the response to query
* @param key header name
* @param key_len the length of @a key, not including optional
* terminating null-character.
* @param token the token to find
* @param token_len the length of token, not including optional
* @param token_len the length of @a token, not including optional
* terminating null-character.
* @return true if token is found in specified header,
* false otherwise
@@ -1938,6 +1948,7 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
bool
MHD_check_response_header_token_ci (const struct MHD_Response *response,
const char *key,
size_t key_len,
const char *token,
size_t token_len);
@@ -1953,7 +1964,8 @@ MHD_check_response_header_token_ci (const struct MHD_Response *response,
* false otherwise
*/
#define MHD_check_response_header_s_token_ci(r,k,tkn) \
MHD_check_response_header_token_ci((r),(k),(tkn),MHD_STATICSTR_LEN_(tkn))
MHD_check_response_header_token_ci((r),(k),MHD_STATICSTR_LEN_(k),\
(tkn),MHD_STATICSTR_LEN_(tkn))
/**
+29
View File
@@ -376,6 +376,35 @@ MHD_str_equal_caseless_n_ (const char * const str1,
}
/**
* Check two string for equality, ignoring case of US-ASCII letters and
* checking exactly @a len characters.
* Compares exactly @a len characters, including binary zero characters.
* @param str1 first string to compare
* @param str2 second string to compare
* @param len number of characters to compare
* @return non-zero if two strings are equal, zero otherwise.
*/
bool
MHD_str_equal_caseless_bin_n_ (const char * const str1,
const char * const str2,
size_t len)
{
size_t i;
for (i = 0; i < len; ++i)
{
const char c1 = str1[i];
const char c2 = str2[i];
if ( (c1 != c2) &&
(toasciilower (c1) != toasciilower (c2)) )
return 0;
}
return !0;
}
/**
* Check whether @a str has case-insensitive @a token.
* Token could be surrounded by spaces and tabs and delimited by comma.
+15
View File
@@ -82,6 +82,21 @@ MHD_str_equal_caseless_n_ (const char * const str1,
size_t maxlen);
/**
* Check two string for equality, ignoring case of US-ASCII letters and
* checking exactly @a len characters.
* Compares exactly @a len characters, including binary zero characters.
* @param str1 first string to compare
* @param str2 second string to compare
* @param len number of characters to compare
* @return non-zero if two strings are equal, zero otherwise.
*/
bool
MHD_str_equal_caseless_bin_n_ (const char * const str1,
const char * const str2,
size_t len);
/**
* Check whether @a str has case-insensitive @a token.
* Token could be surrounded by spaces and tabs and delimited by comma.
+18 -6
View File
@@ -105,6 +105,7 @@ add_response_entry (struct MHD_Response *response,
free (hdr);
return MHD_NO;
}
hdr->header_size = strlen (header);
if (NULL == (hdr->value = strdup (content)))
{
free (hdr->header);
@@ -254,8 +255,7 @@ MHD_get_response_headers (struct MHD_Response *response,
(MHD_YES != iterator (iterator_cls,
pos->kind,
pos->header,
pos->value,
pos->value_size)))
pos->value)))
break;
}
return numHeaders;
@@ -275,14 +275,18 @@ MHD_get_response_header (struct MHD_Response *response,
const char *key)
{
struct MHD_HTTP_Header *pos;
size_t key_size;
if (NULL == key)
return NULL;
key_size = strlen (key);
for (pos = response->first_header;
NULL != pos;
pos = pos->next)
{
if (MHD_str_equal_caseless_ (pos->header, key))
if ((pos->header_size == key_size) &&
(MHD_str_equal_caseless_bin_n_ (pos->header, key, pos->header_size)))
return pos->value;
}
return NULL;
@@ -297,8 +301,10 @@ MHD_get_response_header (struct MHD_Response *response,
*
* @param response the response to query
* @param key header name
* @param key_len the length of @a key, not including optional
* terminating null-character.
* @param token the token to find
* @param token_len the length of token, not including optional
* @param token_len the length of @a token, not including optional
* terminating null-character.
* @return true if token is found in specified header,
* false otherwise
@@ -306,6 +312,7 @@ MHD_get_response_header (struct MHD_Response *response,
bool
MHD_check_response_header_token_ci (const struct MHD_Response *response,
const char *key,
size_t key_len,
const char *token,
size_t token_len)
{
@@ -317,13 +324,18 @@ MHD_check_response_header_token_ci (const struct MHD_Response *response,
('\0' == token[0]) )
return false;
/* Token must not contain binary zero! */
mhd_assert(strlen(token) == token_len);
for (pos = response->first_header;
NULL != pos;
pos = pos->next)
{
if ( (pos->kind == MHD_HEADER_KIND) &&
MHD_str_equal_caseless_ (pos->header,
key) &&
(key_len == pos->header_size) &&
MHD_str_equal_caseless_bin_n_ (pos->header,
key,
key_len) &&
MHD_str_has_token_caseless_ (pos->value,
token,
token_len) )
+1 -7
View File
@@ -65,13 +65,8 @@ copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
return size * nmemb;
}
static int
kv_cb (void *cls,
enum MHD_ValueKind kind,
const char *key,
const char *value,
size_t value_size)
kv_cb (void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
{
if ((0 == strcmp (key, MHD_HTTP_HEADER_HOST)) &&
(0 == strncmp (value, "127.0.0.1", strlen("127.0.0.1"))) && (kind == MHD_HEADER_KIND))
@@ -82,7 +77,6 @@ kv_cb (void *cls,
return MHD_YES;
}
static int
ahc_echo (void *cls,
struct MHD_Connection *connection,
+2 -7
View File
@@ -67,18 +67,13 @@ copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
return size * nmemb;
}
static int
test_values (void *cls,
enum MHD_ValueKind kind,
const char *key,
const char *value,
size_t value_size)
const char *value)
{
(void) cls;
(void) kind;
(void) value_size;
(void)cls;(void)kind; /* Unused. Silent compiler warning. */
if ( (0 == strcmp (key, "a")) &&
(0 == strcmp (value, "b")) )
matches += 1;