Commit df9d738b authored by Philipp Schafft's avatar Philipp Schafft 🦁

initial patch to allow adding user defined headers, closes #1885

svn path=/icecast/trunk/icecast/; revision=19267
parent 97454060
...@@ -87,6 +87,7 @@ static void _parse_logging(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c); ...@@ -87,6 +87,7 @@ static void _parse_logging(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
static void _parse_security(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c); static void _parse_security(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node, static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node,
ice_config_t *c); ice_config_t *c);
static void _parse_http_headers(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
static void _parse_relay(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c); static void _parse_relay(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
static void _parse_mount(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c); static void _parse_mount(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
static void _parse_listen_socket(xmlDocPtr doc, xmlNodePtr node, static void _parse_listen_socket(xmlDocPtr doc, xmlNodePtr node,
...@@ -123,6 +124,18 @@ void config_init_configuration(ice_config_t *configuration) ...@@ -123,6 +124,18 @@ void config_init_configuration(ice_config_t *configuration)
_set_defaults(configuration); _set_defaults(configuration);
} }
static void config_clear_http_header(ice_config_http_header_t *header) {
ice_config_http_header_t *old;
while (header) {
xmlFree(header->name);
xmlFree(header->value);
old = header;
header = header->next;
free(old);
}
}
static void config_clear_mount (mount_proxy *mount) static void config_clear_mount (mount_proxy *mount)
{ {
config_options_t *option; config_options_t *option;
...@@ -263,6 +276,8 @@ void config_clear(ice_config_t *c) ...@@ -263,6 +276,8 @@ void config_clear(ice_config_t *c)
} }
#endif #endif
config_clear_http_header(c->http_headers);
memset(c, 0, sizeof(ice_config_t)); memset(c, 0, sizeof(ice_config_t));
} }
...@@ -471,6 +486,8 @@ static void _parse_root(xmlDocPtr doc, xmlNodePtr node, ...@@ -471,6 +486,8 @@ static void _parse_root(xmlDocPtr doc, xmlNodePtr node,
configuration->shoutcast_mount = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); configuration->shoutcast_mount = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("limits")) == 0) { } else if (xmlStrcmp (node->name, XMLSTR("limits")) == 0) {
_parse_limits(doc, node->xmlChildrenNode, configuration); _parse_limits(doc, node->xmlChildrenNode, configuration);
} else if (xmlStrcmp (node->name, XMLSTR("http-headers")) == 0) {
_parse_http_headers(doc, node->xmlChildrenNode, configuration);
} else if (xmlStrcmp (node->name, XMLSTR("relay")) == 0) { } else if (xmlStrcmp (node->name, XMLSTR("relay")) == 0) {
_parse_relay(doc, node->xmlChildrenNode, configuration); _parse_relay(doc, node->xmlChildrenNode, configuration);
} else if (xmlStrcmp (node->name, XMLSTR("mount")) == 0) { } else if (xmlStrcmp (node->name, XMLSTR("mount")) == 0) {
...@@ -741,6 +758,41 @@ static void _parse_mount(xmlDocPtr doc, xmlNodePtr node, ...@@ -741,6 +758,41 @@ static void _parse_mount(xmlDocPtr doc, xmlNodePtr node,
configuration->mounts = mount; configuration->mounts = mount;
} }
static void _parse_http_headers(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c) {
ice_config_http_header_t *header;
ice_config_http_header_t *next;
char *name = NULL;
char *value = NULL;
do {
if (node == NULL) break;
if (xmlIsBlankNode(node)) continue;
if (xmlStrcmp (node->name, XMLSTR("header")) != 0) break;
if (!(name = (char *)xmlGetProp(node, XMLSTR("name")))) break;
if (!(value = (char *)xmlGetProp(node, XMLSTR("value")))) break;
header = calloc(1, sizeof(ice_config_http_header_t));
if (!header) break;
header->type = HTTP_HEADER_TYPE_STATIC;
header->name = name;
header->value = value;
name = NULL;
value = NULL;
if (!c->http_headers) {
c->http_headers = header;
continue;
}
next = c->http_headers;
while (next->next) next = next->next;
next->next = header;
} while ((node = node->next));
/* in case we used break we may need to clean those up */
if (name)
xmlFree(name);
if (value)
xmlFree(value);
}
static void _parse_relay(xmlDocPtr doc, xmlNodePtr node, static void _parse_relay(xmlDocPtr doc, xmlNodePtr node,
ice_config_t *configuration) ice_config_t *configuration)
......
...@@ -31,6 +31,17 @@ struct _mount_proxy; ...@@ -31,6 +31,17 @@ struct _mount_proxy;
#define XMLSTR(str) ((xmlChar *)(str)) #define XMLSTR(str) ((xmlChar *)(str))
typedef enum _http_header_type {
HTTP_HEADER_TYPE_STATIC
} http_header_type;
typedef struct ice_config_http_header_tag {
http_header_type type;
char *name;
char *value;
struct ice_config_http_header_tag *next;
} ice_config_http_header_t;
typedef struct ice_config_dir_tag { typedef struct ice_config_dir_tag {
char *host; char *host;
int touch_interval; int touch_interval;
...@@ -156,6 +167,8 @@ typedef struct ice_config_tag { ...@@ -156,6 +167,8 @@ typedef struct ice_config_tag {
char *master_username; char *master_username;
char *master_password; char *master_password;
ice_config_http_header_t *http_headers;
relay_server *relay; relay_server *relay;
mount_proxy *mounts; mount_proxy *mounts;
......
...@@ -486,6 +486,40 @@ char *util_base64_decode(const char *data) ...@@ -486,6 +486,40 @@ char *util_base64_decode(const char *data)
return result; return result;
} }
/* TODO, FIXME: handle memory allocation errors better. */
static inline char * _build_headers(ice_config_t *config) {
char *ret = NULL;
size_t len = 1;
size_t headerlen;
const char *name;
const char *value;
ice_config_http_header_t *header = config->http_headers;
if (!header) {
return strdup("");
}
ret = calloc(1, 1);
*ret = 0;
while (header) {
name = header->name;
switch (header->type) {
case HTTP_HEADER_TYPE_STATIC:
value = header->value;
break;
}
headerlen = strlen(name) + strlen(value) + 4;
len += headerlen;
ret = realloc(ret, len);
strcat(ret, name);
strcat(ret, ": ");
strcat(ret, value);
strcat(ret, "\r\n");
header = header->next;
}
return ret;
}
ssize_t util_http_build_header(char * out, size_t len, ssize_t offset, ssize_t util_http_build_header(char * out, size_t len, ssize_t offset,
int cache, int cache,
int status, const char * statusmsg, int status, const char * statusmsg,
...@@ -500,6 +534,7 @@ ssize_t util_http_build_header(char * out, size_t len, ssize_t offset, ...@@ -500,6 +534,7 @@ ssize_t util_http_build_header(char * out, size_t len, ssize_t offset,
char status_buffer[80]; char status_buffer[80];
char contenttype_buffer[80]; char contenttype_buffer[80];
ssize_t ret; ssize_t ret;
char * extra_headers;
if (!out) if (!out)
return -1; return -1;
...@@ -563,7 +598,8 @@ ssize_t util_http_build_header(char * out, size_t len, ssize_t offset, ...@@ -563,7 +598,8 @@ ssize_t util_http_build_header(char * out, size_t len, ssize_t offset,
currenttime_buffer[0] = '\0'; currenttime_buffer[0] = '\0';
config = config_get_config(); config = config_get_config();
ret = snprintf (out, len, "%sServer: %s\r\n%s%s%s%s%s%s", extra_headers = _build_headers(config);
ret = snprintf (out, len, "%sServer: %s\r\n%s%s%s%s%s%s%s",
status_buffer, status_buffer,
config->server_id, config->server_id,
currenttime_buffer, currenttime_buffer,
...@@ -572,8 +608,10 @@ ssize_t util_http_build_header(char * out, size_t len, ssize_t offset, ...@@ -572,8 +608,10 @@ ssize_t util_http_build_header(char * out, size_t len, ssize_t offset,
(cache ? "" : "Cache-Control: no-cache\r\n" (cache ? "" : "Cache-Control: no-cache\r\n"
"Expires: Mon, 26 Jul 1997 05:00:00 GMT\r\n" "Expires: Mon, 26 Jul 1997 05:00:00 GMT\r\n"
"Pragma: no-cache\r\n"), "Pragma: no-cache\r\n"),
extra_headers,
(datablock ? "\r\n" : ""), (datablock ? "\r\n" : ""),
(datablock ? datablock : "")); (datablock ? datablock : ""));
free(extra_headers);
config_release_config(); config_release_config();
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment