1
0
mirror of https://gitlab.xiph.org/xiph/icecast-common.git synced 2024-12-04 14:46:31 -05:00

Feature: Allow enumeration of parser content

This commit is contained in:
Philipp Schafft 2018-08-09 11:17:38 +00:00
parent c1d41f38b0
commit 6492a456a1
2 changed files with 124 additions and 0 deletions

View File

@ -725,6 +725,120 @@ const http_var_t *httpp_get_param_var(http_parser_t *parser, const char *name)
return _httpp_get_param_var(parser->queryvars, name);
}
const http_var_t *httpp_get_any_var(http_parser_t *parser, httpp_ns_t ns, const char *name)
{
avl_tree *tree = NULL;
if (!parser || !name)
return NULL;
switch (ns) {
case HTTPP_NS_VAR:
if (name[0] != '_' || name[1] != '_')
return NULL;
tree = parser->vars;
break;
case HTTPP_NS_HEADER:
if (name[0] == '_' && name[1] == '_')
return NULL;
tree = parser->vars;
break;
case HTTPP_NS_QUERY_STRING:
tree = parser->queryvars;
break;
case HTTPP_NS_POST_BODY:
tree = parser->postvars;
break;
}
if (!tree)
return NULL;
return _httpp_get_param_var(tree, name);
}
char ** httpp_get_any_key(http_parser_t *parser, httpp_ns_t ns)
{
avl_tree *tree = NULL;
avl_node *avlnode;
char **ret;
size_t len;
size_t pos = 0;
if (!parser)
return NULL;
switch (ns) {
case HTTPP_NS_VAR:
case HTTPP_NS_HEADER:
tree = parser->vars;
break;
case HTTPP_NS_QUERY_STRING:
tree = parser->queryvars;
break;
case HTTPP_NS_POST_BODY:
tree = parser->postvars;
break;
}
if (!tree)
return NULL;
ret = calloc(8, sizeof(*ret));
if (!ret)
return NULL;
len = 8;
for (avlnode = avl_get_first(tree); avlnode; avlnode = avl_get_next(avlnode)) {
http_var_t *var = avlnode->key;
if (ns == HTTPP_NS_VAR) {
if (var->name[0] != '_' || var->name[1] != '_') {
continue;
}
} else if (ns == HTTPP_NS_HEADER) {
if (var->name[0] == '_' && var->name[1] == '_') {
continue;
}
}
if (pos == (len-1)) {
char **n = realloc(ret, sizeof(*ret)*(len + 8));
if (!n) {
httpp_free_any_key(ret);
return NULL;
}
memset(n + len, 0, sizeof(*n)*8);
ret = n;
len += 8;
}
ret[pos] = strdup(var->name);
if (!ret[pos]) {
httpp_free_any_key(ret);
return NULL;
}
pos++;
}
return ret;
}
void httpp_free_any_key(char **keys)
{
char **p;
if (!keys)
return;
for (p = keys; *p; p++) {
free(*p);
}
free(keys);
}
const char *httpp_get_param(http_parser_t *parser, const char *name)
{
const char *ret = _httpp_get_param(parser->postvars, name);

View File

@ -39,6 +39,13 @@
#define HTTPP_VAR_ERROR_CODE "__errorcode"
#define HTTPP_VAR_ICYPASSWORD "__icy_password"
typedef enum {
HTTPP_NS_VAR,
HTTPP_NS_HEADER,
HTTPP_NS_QUERY_STRING,
HTTPP_NS_POST_BODY
} httpp_ns_t;
typedef enum httpp_request_type_tag {
/* Initial and internally used state of the engine */
httpp_req_none = 0,
@ -126,6 +133,9 @@ void httpp_set_post_param(http_parser_t *parser, const char *name, const char *v
const char *httpp_get_post_param(http_parser_t *parser, const char *name);
const char *httpp_get_param(http_parser_t *parser, const char *name);
const http_var_t *httpp_get_param_var(http_parser_t *parser, const char *name);
const http_var_t *httpp_get_any_var(http_parser_t *parser, httpp_ns_t ns, const char *name);
char ** httpp_get_any_key(http_parser_t *parser, httpp_ns_t ns);
void httpp_free_any_key(char **keys);
int httpp_addref(http_parser_t *parser);
int httpp_release(http_parser_t *parser);
#define httpp_destroy(x) httpp_release((x))