diff --git a/Makefile b/Makefile index 007d2552..021d0e4f 100644 --- a/Makefile +++ b/Makefile @@ -107,6 +107,7 @@ LIB_SOURCES = src/libhttp.c \ src/httplib_handle_request.c \ src/httplib_handle_static_file_request.c \ src/httplib_handle_websocket_request.c \ + src/httplib_header_has_option.c \ src/httplib_inet_pton.c \ src/httplib_initialize_ssl.c \ src/httplib_interpret_uri.c \ @@ -130,6 +131,7 @@ LIB_SOURCES = src/libhttp.c \ src/httplib_mkdir.c \ src/httplib_modify_passwords_file.c \ src/httplib_must_hide_file.c \ + src/httplib_next_option.c \ src/httplib_open_auth_file.c \ src/httplib_opendir.c \ src/httplib_parse_auth_header.c \ diff --git a/src/httplib_header_has_option.c b/src/httplib_header_has_option.c new file mode 100644 index 00000000..2b4c8fae --- /dev/null +++ b/src/httplib_header_has_option.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2016 Lammert Bies + * Copyright (c) 2013-2016 the Civetweb developers + * Copyright (c) 2004-2013 Sergey Lyubka + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + + +#include "libhttp-private.h" + + + +/* A helper function for checking if a comma separated list of values contains + * the given option (case insensitvely). + * 'header' can be NULL, in which case false is returned. */ +int XX_httplib_header_has_option( const char *header, const char *option ) { + + struct vec opt_vec; + struct vec eq_vec; + + assert(option != NULL); + assert(option[0] != '\0'); + + while ((header = XX_httplib_next_option(header, &opt_vec, &eq_vec)) != NULL) { + if (mg_strncasecmp(option, opt_vec.ptr, opt_vec.len) == 0) return 1; + } + + return 0; + +} /* XX_httplib_header_has_option */ diff --git a/src/httplib_next_option.c b/src/httplib_next_option.c new file mode 100644 index 00000000..5376caf2 --- /dev/null +++ b/src/httplib_next_option.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2016 Lammert Bies + * Copyright (c) 2013-2016 the Civetweb developers + * Copyright (c) 2004-2013 Sergey Lyubka + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + + +#include "libhttp-private.h" + + + +/* A helper function for traversing a comma separated list of values. + * It returns a list pointer shifted to the next value, or NULL if the end + * of the list found. + * Value is stored in val vector. If value has form "x=y", then eq_val + * vector is initialized to point to the "y" part, and val vector length + * is adjusted to point only to "x". */ +const char *XX_httplib_next_option( const char *list, struct vec *val, struct vec *eq_val ) { + + int end; + +reparse: + if (val == NULL || list == NULL || *list == '\0') { + /* End of the list */ + list = NULL; + } else { + /* Skip over leading LWS */ + while (*list == ' ' || *list == '\t') list++; + + val->ptr = list; + if ((list = strchr(val->ptr, ',')) != NULL) { + /* Comma found. Store length and shift the list ptr */ + val->len = ((size_t)(list - val->ptr)); + list++; + } else { + /* This value is the last one */ + list = val->ptr + strlen(val->ptr); + val->len = ((size_t)(list - val->ptr)); + } + + /* Adjust length for trailing LWS */ + end = (int)val->len - 1; + while (end >= 0 && (val->ptr[end] == ' ' || val->ptr[end] == '\t')) + end--; + val->len = (size_t)(end + 1); + + if (val->len == 0) { + /* Ignore any empty entries. */ + goto reparse; + } + + if (eq_val != NULL) { + /* Value has form "x=y", adjust pointers and lengths + * so that val points to "x", and eq_val points to "y". */ + eq_val->len = 0; + eq_val->ptr = (const char *)memchr(val->ptr, '=', val->len); + if (eq_val->ptr != NULL) { + eq_val->ptr++; /* Skip over '=' character */ + eq_val->len = ((size_t)(val->ptr - eq_val->ptr)) + val->len; + val->len = ((size_t)(eq_val->ptr - val->ptr)) - 1; + } + } + } + + return list; + +} /* XX_httplib_next_option */ diff --git a/src/libhttp.c b/src/libhttp.c index 7c80afdb..ba622d88 100644 --- a/src/libhttp.c +++ b/src/libhttp.c @@ -828,85 +828,6 @@ void XX_httplib_set_thread_name(const char *threadName) { -/* A helper function for traversing a comma separated list of values. - * It returns a list pointer shifted to the next value, or NULL if the end - * of the list found. - * Value is stored in val vector. If value has form "x=y", then eq_val - * vector is initialized to point to the "y" part, and val vector length - * is adjusted to point only to "x". */ -const char *XX_httplib_next_option( const char *list, struct vec *val, struct vec *eq_val ) { - - int end; - -reparse: - if (val == NULL || list == NULL || *list == '\0') { - /* End of the list */ - list = NULL; - } else { - /* Skip over leading LWS */ - while (*list == ' ' || *list == '\t') list++; - - val->ptr = list; - if ((list = strchr(val->ptr, ',')) != NULL) { - /* Comma found. Store length and shift the list ptr */ - val->len = ((size_t)(list - val->ptr)); - list++; - } else { - /* This value is the last one */ - list = val->ptr + strlen(val->ptr); - val->len = ((size_t)(list - val->ptr)); - } - - /* Adjust length for trailing LWS */ - end = (int)val->len - 1; - while (end >= 0 && (val->ptr[end] == ' ' || val->ptr[end] == '\t')) - end--; - val->len = (size_t)(end + 1); - - if (val->len == 0) { - /* Ignore any empty entries. */ - goto reparse; - } - - if (eq_val != NULL) { - /* Value has form "x=y", adjust pointers and lengths - * so that val points to "x", and eq_val points to "y". */ - eq_val->len = 0; - eq_val->ptr = (const char *)memchr(val->ptr, '=', val->len); - if (eq_val->ptr != NULL) { - eq_val->ptr++; /* Skip over '=' character */ - eq_val->len = ((size_t)(val->ptr - eq_val->ptr)) + val->len; - val->len = ((size_t)(eq_val->ptr - val->ptr)) - 1; - } - } - } - - return list; - -} /* XX_httplib_next_option */ - - - -/* A helper function for checking if a comma separated list of values contains - * the given option (case insensitvely). - * 'header' can be NULL, in which case false is returned. */ -int XX_httplib_header_has_option( const char *header, const char *option ) { - - struct vec opt_vec; - struct vec eq_vec; - - assert(option != NULL); - assert(option[0] != '\0'); - - while ((header = XX_httplib_next_option(header, &opt_vec, &eq_vec)) != NULL) { - if (mg_strncasecmp(option, opt_vec.ptr, opt_vec.len) == 0) return 1; - } - - return 0; - -} /* XX_httplib_header_has_option */ - - /* Perform case-insensitive match of string against pattern */ int XX_httplib_match_prefix(const char *pattern, size_t pattern_len, const char *str) {