From 1d567696487c5896b37b19e8851d8a3d6c473cae Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Fri, 7 Nov 2014 10:12:24 +0000 Subject: [PATCH] added support for type="" and status="" in
(subelement of ). svn path=/icecast/trunk/icecast/; revision=19270 --- src/cfgfile.c | 33 ++++++++++++++++++++++++++++----- src/cfgfile.h | 9 +++++++++ src/util.c | 22 ++++++++++++++++------ 3 files changed, 53 insertions(+), 11 deletions(-) diff --git a/src/cfgfile.c b/src/cfgfile.c index c9be993f..6643505b 100644 --- a/src/cfgfile.c +++ b/src/cfgfile.c @@ -137,7 +137,7 @@ static void config_clear_http_header(ice_config_http_header_t *header) { } } -static ice_config_http_header_t * config_copy_http_header(ice_config_http_header_t *header) { +static inline ice_config_http_header_t * config_copy_http_header(ice_config_http_header_t *header) { ice_config_http_header_t *ret = NULL; ice_config_http_header_t *cur = NULL; ice_config_http_header_t *old = NULL; @@ -154,9 +154,10 @@ static ice_config_http_header_t * config_copy_http_header(ice_config_http_header if (!cur) return ret; /* TODO: do better error handling */ - cur->type = header->type; - cur->name = (char *)xmlCharStrdup(header->name); - cur->value = (char *)xmlCharStrdup(header->value); + cur->type = header->type; + cur->name = (char *)xmlCharStrdup(header->name); + cur->value = (char *)xmlCharStrdup(header->value); + cur->status = header->status; if (!cur->name || !cur->value) { if (cur->name) xmlFree(cur->name); @@ -810,6 +811,9 @@ static void _parse_http_headers(xmlDocPtr doc, xmlNodePtr node, ice_config_http_ ice_config_http_header_t *next; char *name = NULL; char *value = NULL; + char *tmp; + int status; + http_header_type type; do { if (node == NULL) break; @@ -818,11 +822,30 @@ static void _parse_http_headers(xmlDocPtr doc, xmlNodePtr node, ice_config_http_ if (!(name = (char *)xmlGetProp(node, XMLSTR("name")))) break; if (!(value = (char *)xmlGetProp(node, XMLSTR("value")))) break; + type = HTTP_HEADER_TYPE_STATIC; /* default */ + if ((tmp = (char *)xmlGetProp(node, XMLSTR("type")))) { + if (strcmp(tmp, "static") == 0) { + type = HTTP_HEADER_TYPE_STATIC; + } else { + ICECAST_LOG_WARN("Unknown type %s for HTTP Header %s", tmp, name); + xmlFree(tmp); + break; + } + xmlFree(tmp); + } + + status = 0; /* default: any */ + if ((tmp = (char *)xmlGetProp(node, XMLSTR("status")))) { + status = atoi(tmp); + xmlFree(tmp); + } + header = calloc(1, sizeof(ice_config_http_header_t)); if (!header) break; - header->type = HTTP_HEADER_TYPE_STATIC; + header->type = type; header->name = name; header->value = value; + header->status = status; name = NULL; value = NULL; diff --git a/src/cfgfile.h b/src/cfgfile.h index 54458fc4..68d7a370 100644 --- a/src/cfgfile.h +++ b/src/cfgfile.h @@ -32,13 +32,22 @@ struct _mount_proxy; #define XMLSTR(str) ((xmlChar *)(str)) typedef enum _http_header_type { + /* static: headers are passed as is to the client. */ HTTP_HEADER_TYPE_STATIC } http_header_type; typedef struct ice_config_http_header_tag { + /* type of this header. See http_header_type */ http_header_type type; + + /* name and value of the header */ char *name; char *value; + + /* filters */ + int status; + + /* link to the next list element */ struct ice_config_http_header_tag *next; } ice_config_http_header_t; diff --git a/src/util.c b/src/util.c index 99ca078c..4926529c 100644 --- a/src/util.c +++ b/src/util.c @@ -488,19 +488,30 @@ char *util_base64_decode(const char *data) } /* TODO, FIXME: handle memory allocation errors better. */ -static inline void _build_headers_loop(char **ret, size_t *len, ice_config_http_header_t *header) { +static inline void _build_headers_loop(char **ret, size_t *len, ice_config_http_header_t *header, int status) { size_t headerlen; const char *name; const char *value; char * r = *ret; - while (header) { + if (!header) + return; + + do { + /* filter out header's we don't use. */ + if (header->status != 0 && header->status != status) continue; + + /* get the name of the header */ name = header->name; + + /* handle type of the header */ switch (header->type) { case HTTP_HEADER_TYPE_STATIC: value = header->value; break; } + + /* append the header to the buffer */ headerlen = strlen(name) + strlen(value) + 4; *len += headerlen; r = realloc(r, *len); @@ -508,8 +519,7 @@ static inline void _build_headers_loop(char **ret, size_t *len, ice_config_htt strcat(r, ": "); strcat(r, value); strcat(r, "\r\n"); - header = header->next; - } + } while ((header = header->next)); *ret = r; } static inline char * _build_headers(int status, ice_config_t *config, source_t *source) { @@ -523,9 +533,9 @@ static inline char * _build_headers(int status, ice_config_t *config, source_t * ret = calloc(1, 1); *ret = 0; - _build_headers_loop(&ret, &len, config->http_headers); + _build_headers_loop(&ret, &len, config->http_headers, status); if (mountproxy && mountproxy->http_headers) - _build_headers_loop(&ret, &len, mountproxy->http_headers); + _build_headers_loop(&ret, &len, mountproxy->http_headers, status); return ret; }