mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05:00
initial patch to allow adding user defined headers, closes #1885
svn path=/icecast/trunk/icecast/; revision=19267
This commit is contained in:
parent
97454060eb
commit
df9d738b6e
@ -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_authentication(xmlDocPtr doc, xmlNodePtr node,
|
||||
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_mount(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
|
||||
static void _parse_listen_socket(xmlDocPtr doc, xmlNodePtr node,
|
||||
@ -123,6 +124,18 @@ void config_init_configuration(ice_config_t *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)
|
||||
{
|
||||
config_options_t *option;
|
||||
@ -263,6 +276,8 @@ void config_clear(ice_config_t *c)
|
||||
}
|
||||
#endif
|
||||
|
||||
config_clear_http_header(c->http_headers);
|
||||
|
||||
memset(c, 0, sizeof(ice_config_t));
|
||||
}
|
||||
|
||||
@ -471,6 +486,8 @@ static void _parse_root(xmlDocPtr doc, xmlNodePtr node,
|
||||
configuration->shoutcast_mount = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
|
||||
} else if (xmlStrcmp (node->name, XMLSTR("limits")) == 0) {
|
||||
_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) {
|
||||
_parse_relay(doc, node->xmlChildrenNode, configuration);
|
||||
} else if (xmlStrcmp (node->name, XMLSTR("mount")) == 0) {
|
||||
@ -741,6 +758,41 @@ static void _parse_mount(xmlDocPtr doc, xmlNodePtr node,
|
||||
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,
|
||||
ice_config_t *configuration)
|
||||
|
@ -31,6 +31,17 @@ struct _mount_proxy;
|
||||
|
||||
#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 {
|
||||
char *host;
|
||||
int touch_interval;
|
||||
@ -156,6 +167,8 @@ typedef struct ice_config_tag {
|
||||
char *master_username;
|
||||
char *master_password;
|
||||
|
||||
ice_config_http_header_t *http_headers;
|
||||
|
||||
relay_server *relay;
|
||||
|
||||
mount_proxy *mounts;
|
||||
|
40
src/util.c
40
src/util.c
@ -486,6 +486,40 @@ char *util_base64_decode(const char *data)
|
||||
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,
|
||||
int cache,
|
||||
int status, const char * statusmsg,
|
||||
@ -500,6 +534,7 @@ ssize_t util_http_build_header(char * out, size_t len, ssize_t offset,
|
||||
char status_buffer[80];
|
||||
char contenttype_buffer[80];
|
||||
ssize_t ret;
|
||||
char * extra_headers;
|
||||
|
||||
if (!out)
|
||||
return -1;
|
||||
@ -563,7 +598,8 @@ ssize_t util_http_build_header(char * out, size_t len, ssize_t offset,
|
||||
currenttime_buffer[0] = '\0';
|
||||
|
||||
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,
|
||||
config->server_id,
|
||||
currenttime_buffer,
|
||||
@ -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"
|
||||
"Expires: Mon, 26 Jul 1997 05:00:00 GMT\r\n"
|
||||
"Pragma: no-cache\r\n"),
|
||||
extra_headers,
|
||||
(datablock ? "\r\n" : ""),
|
||||
(datablock ? datablock : ""));
|
||||
free(extra_headers);
|
||||
config_release_config();
|
||||
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user