1
0
mirror of https://gitlab.xiph.org/xiph/icecast-common.git synced 2024-06-16 06:15:24 +00:00

Update: Replaced next member with an array of values

This commit is contained in:
Philipp Schafft 2018-07-26 12:55:10 +00:00
parent 0117b90aa6
commit 53c13dd00e
2 changed files with 78 additions and 32 deletions

View File

@ -55,8 +55,9 @@ static int _free_vars(void *key);
/* For avl tree manipulation */ /* For avl tree manipulation */
static void parse_query(avl_tree *tree, const char *query, size_t len); static void parse_query(avl_tree *tree, const char *query, size_t len);
static const char *_httpp_get_param(avl_tree *tree, const char *name); static const char *_httpp_get_param(avl_tree *tree, const char *name);
static void _httpp_set_param_nocopy(avl_tree *tree, char *name, char *value); static void _httpp_set_param_nocopy(avl_tree *tree, char *name, char *value, int replace);
static void _httpp_set_param(avl_tree *tree, const char *name, const char *value); static void _httpp_set_param(avl_tree *tree, const char *name, const char *value);
static http_var_t *_httpp_get_param_var(avl_tree *tree, const char *name);
http_parser_t *httpp_create_parser(void) http_parser_t *httpp_create_parser(void)
{ {
@ -76,7 +77,12 @@ void httpp_initialize(http_parser_t *parser, http_varlist_t *defaults)
/* now insert the default variables */ /* now insert the default variables */
list = defaults; list = defaults;
while (list != NULL) { while (list != NULL) {
httpp_setvar(parser, list->var.name, list->var.value); size_t i;
for (i = 0; i < list->var.values; i++) {
httpp_setvar(parser, list->var.name, list->var.value[i]);
}
list = list->next; list = list->next;
} }
} }
@ -310,7 +316,7 @@ static void parse_query_element(avl_tree *tree, const char *start, const char *m
value = url_unescape(mid + 1, valuelen); value = url_unescape(mid + 1, valuelen);
_httpp_set_param_nocopy(tree, key, value); _httpp_set_param_nocopy(tree, key, value, 0);
} }
static void parse_query(avl_tree *tree, const char *query, size_t len) static void parse_query(avl_tree *tree, const char *query, size_t len)
@ -508,8 +514,15 @@ void httpp_setvar(http_parser_t *parser, const char *name, const char *value)
var = (http_var_t *)calloc(1, sizeof(http_var_t)); var = (http_var_t *)calloc(1, sizeof(http_var_t));
if (var == NULL) return; if (var == NULL) return;
var->value = calloc(1, sizeof(*var->value));
if (!var->value) {
free(var);
return;
}
var->name = strdup(name); var->name = strdup(name);
var->value = strdup(value); var->values = 1;
var->value[0] = strdup(value);
if (httpp_getvar(parser, name) == NULL) { if (httpp_getvar(parser, name) == NULL) {
avl_insert(parser->vars, (void *)var); avl_insert(parser->vars, (void *)var);
@ -532,29 +545,54 @@ const char *httpp_getvar(http_parser_t *parser, const char *name)
memset(&var, 0, sizeof(var)); memset(&var, 0, sizeof(var));
var.name = (char*)name; var.name = (char*)name;
if (avl_get_by_key(parser->vars, &var, fp) == 0) if (avl_get_by_key(parser->vars, &var, fp) == 0) {
return found->value; if (!found->values)
else return NULL;
return found->value[0];
} else {
return NULL; return NULL;
}
} }
static void _httpp_set_param_nocopy(avl_tree *tree, char *name, char *value) static void _httpp_set_param_nocopy(avl_tree *tree, char *name, char *value, int replace)
{ {
http_var_t *var; http_var_t *var, *found;
char **n;
if (name == NULL || value == NULL) if (name == NULL || value == NULL)
return; return;
var = (http_var_t *)calloc(1, sizeof(http_var_t)); found = _httpp_get_param_var(tree, name);
if (var == NULL) return;
var->name = name; if (replace || !found) {
var->value = value; var = (http_var_t *)calloc(1, sizeof(http_var_t));
if (var == NULL) {
free(name);
free(value);
return;
}
if (_httpp_get_param(tree, name) == NULL) { var->name = name;
avl_insert(tree, (void *)var);
} else { } else {
avl_delete(tree, (void *)var, _free_vars); free(name);
var = found;
}
n = realloc(var->value, sizeof(*n)*(var->values + 1));
if (!n) {
if (replace || !found) {
free(name);
free(var);
}
free(value);
return;
}
var->value = n;
var->value[var->values++] = value;
if (replace && found) {
avl_delete(tree, (void *)found, _free_vars);
avl_insert(tree, (void *)var); avl_insert(tree, (void *)var);
} }
} }
@ -564,10 +602,10 @@ static void _httpp_set_param(avl_tree *tree, const char *name, const char *value
if (name == NULL || value == NULL) if (name == NULL || value == NULL)
return; return;
_httpp_set_param_nocopy(tree, strdup(name), url_unescape(value, strlen(value))); _httpp_set_param_nocopy(tree, strdup(name), url_unescape(value, strlen(value)), 1);
} }
static const char *_httpp_get_param(avl_tree *tree, const char *name) static http_var_t *_httpp_get_param_var(avl_tree *tree, const char *name)
{ {
http_var_t var; http_var_t var;
http_var_t *found; http_var_t *found;
@ -578,10 +616,22 @@ static const char *_httpp_get_param(avl_tree *tree, const char *name)
var.name = (char *)name; var.name = (char *)name;
if (avl_get_by_key(tree, (void *)&var, fp) == 0) if (avl_get_by_key(tree, (void *)&var, fp) == 0)
return found->value; return found;
else else
return NULL; return NULL;
} }
static const char *_httpp_get_param(avl_tree *tree, const char *name)
{
http_var_t *res = _httpp_get_param_var(tree, name);
if (!res)
return NULL;
if (!res->values)
return NULL;
return res->value[0];
}
void httpp_set_query_param(http_parser_t *parser, const char *name, const char *value) void httpp_set_query_param(http_parser_t *parser, const char *name, const char *value)
{ {
@ -652,20 +702,16 @@ static int _compare_vars(void *compare_arg, void *a, void *b)
static int _free_vars(void *key) static int _free_vars(void *key)
{ {
http_var_t *var, *next; http_var_t *var = (http_var_t *)key;
size_t i;
next = (http_var_t *)key; free(var->name);
while (next) { for (i = 0; i < var->values; i++) {
var = next; free(var->value[i]);
next = var->next;
if (var->name)
free(var->name);
if (var->value)
free(var->value);
free(var);
} }
free(var->value);
free(var);
return 1; return 1;
} }

View File

@ -64,8 +64,8 @@ typedef enum httpp_request_type_tag {
typedef struct http_var_tag http_var_t; typedef struct http_var_tag http_var_t;
struct http_var_tag { struct http_var_tag {
char *name; char *name;
char *value; size_t values;
http_var_t *next; char **value;
}; };
typedef struct http_varlist_tag { typedef struct http_varlist_tag {