Commit 8527ed7b authored by Michael Smith's avatar Michael Smith

Implementation of aliases contributed by Paul Donohue <icecast@TopQuark.net>

svn path=/trunk/icecast/; revision=4629
parent 776f7597
2003-04-23
Support aliases
2003-03-09
Support listening on multiple sockets.
......
......@@ -83,6 +83,14 @@
be relative to the new root, not the original root -->
<logdir>/usr/local/icecast/logs</logdir>
<webroot>/usr/local/icecast/web</webroot>
<!-- Aliases: treat requests for 'source' path as being for 'dest' path
May be made specific to a port or bound address using the "port"
and "bind-address" attributes.
-->
<!--
<alias source="/foo" dest="/bar"/>
-->
</paths>
<logging>
......
......@@ -98,6 +98,7 @@ void config_clear(ice_config_t *c)
ice_config_dir_t *dirnode, *nextdirnode;
relay_server *relay, *nextrelay;
mount_proxy *mount, *nextmount;
aliases *alias, *nextalias;
int i;
if (c->config_filename)
......@@ -160,6 +161,16 @@ void config_clear(ice_config_t *c)
}
thread_mutex_unlock(&(_locks.mounts_lock));
alias = c->aliases;
while(alias) {
nextalias = alias->next;
xmlFree(alias->source);
xmlFree(alias->destination);
xmlFree(alias->bind_address);
free(alias);
alias = nextalias;
}
dirnode = c->dir_list;
while(dirnode) {
nextdirnode = dirnode->next;
......@@ -423,6 +434,7 @@ static void _parse_mount(xmlDocPtr doc, xmlNodePtr node,
configuration->mounts = mount;
mount->max_listeners = -1;
mount->next = NULL;
do {
if (node == NULL) break;
......@@ -474,6 +486,8 @@ static void _parse_relay(xmlDocPtr doc, xmlNodePtr node,
else
configuration->relay = relay;
relay->next = NULL;
do {
if (node == NULL) break;
if (xmlIsBlankNode(node)) continue;
......@@ -606,6 +620,9 @@ static void _parse_directory(xmlDocPtr doc, xmlNodePtr node,
static void _parse_paths(xmlDocPtr doc, xmlNodePtr node,
ice_config_t *configuration)
{
char *temp;
aliases *alias, *current, *last;
do {
if (node == NULL) break;
if (xmlIsBlankNode(node)) continue;
......@@ -621,7 +638,39 @@ static void _parse_paths(xmlDocPtr doc, xmlNodePtr node,
configuration->webroot_dir = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
if(configuration->webroot_dir[strlen(configuration->webroot_dir)-1] == '/')
configuration->webroot_dir[strlen(configuration->webroot_dir)-1] = 0;
} else if (strcmp(node->name, "alias") == 0) {
alias = malloc(sizeof(aliases));
alias->next = NULL;
alias->source = xmlGetProp(node, "source");
if(alias->source == NULL) {
free(alias);
continue;
}
alias->destination = xmlGetProp(node, "dest");
if(alias->destination == NULL) {
xmlFree(alias->source);
free(alias);
continue;
}
temp = NULL;
temp = xmlGetProp(node, "port");
if(temp != NULL) {
alias->port = atoi(temp);
xmlFree(temp);
}
else
alias->port = -1;
alias->bind_address = xmlGetProp(node, "bind-address");
current = configuration->aliases;
last = NULL;
while(current) {
last = current;
current = current->next;
}
if(last)
last->next = alias;
else
configuration->aliases = alias;
}
} while ((node = node->next));
}
......
......@@ -43,6 +43,14 @@ typedef struct _mount_proxy {
struct _mount_proxy *next;
} mount_proxy;
typedef struct _aliases {
char *source;
char *destination;
int port;
char *bind_address;
struct _aliases *next;
}aliases;
typedef struct {
int port;
char *bind_address;
......@@ -89,6 +97,7 @@ typedef struct ice_config_tag
char *base_dir;
char *log_dir;
char *webroot_dir;
aliases *aliases;
char *access_log;
char *error_log;
......
......@@ -109,11 +109,12 @@ static unsigned long _next_connection_id(void)
return id;
}
connection_t *create_connection(sock_t sock, char *ip) {
connection_t *create_connection(sock_t sock, sock_t serversock, char *ip) {
connection_t *con;
con = (connection_t *)malloc(sizeof(connection_t));
memset(con, 0, sizeof(connection_t));
con->sock = sock;
con->serversock = serversock;
con->con_time = time(NULL);
con->id = _next_connection_id();
con->ip = ip;
......@@ -203,7 +204,7 @@ static connection_t *_accept_connection(void)
sock = sock_accept(serversock, ip, MAX_ADDR_LEN);
if (sock >= 0) {
con = create_connection(sock, ip);
con = create_connection(sock, serversock, ip);
return con;
}
......@@ -648,6 +649,10 @@ static void _handle_get_request(connection_t *con,
int fileserve;
char *host;
int port;
int i;
char *serverhost;
int serverport;
aliases *alias;
ice_config_t *config;
int client_limit;
......@@ -655,6 +660,14 @@ static void _handle_get_request(connection_t *con,
fileserve = config->fileserve;
host = config->hostname;
port = config->port;
for(i = 0; i < MAX_LISTEN_SOCKETS; i++) {
if(global.serversock[i] == con->serversock) {
serverhost = config->listeners[i].bind_address;
serverport = config->listeners[i].port;
break;
}
}
alias = config->aliases;
client_limit = config->client_limit;
config_release_config();
......@@ -668,13 +681,22 @@ static void _handle_get_request(connection_t *con,
/* there are several types of HTTP GET clients
** media clients, which are looking for a source (eg, URI = /stream.ogg)
** stats clients, which are looking for /admin/stats.xml
** and director server authorizers, which are looking for /GUID-xxxxxxxx
** and directory server authorizers, which are looking for /GUID-xxxxxxxx
** (where xxxxxx is the GUID in question) - this isn't implemented yet.
** we need to handle the latter two before the former, as the latter two
** aren't subject to the limits.
*/
/* TODO: add GUID-xxxxxx */
/* Handle aliases */
while(alias) {
if(strcmp(uri, alias->source) == 0 && (alias->port == -1 || alias->port == serverport) && (alias->bind_address == NULL || (serverhost != NULL && strcmp(alias->bind_address, serverhost) == 0))) {
uri = alias->destination;
break;
}
alias = alias->next;
}
/* Dispatch all admin requests */
if (strncmp(uri, "/admin/", 7) == 0) {
admin_handle_request(client, uri);
......
......@@ -17,6 +17,7 @@ typedef struct connection_tag
uint64_t sent_bytes;
int sock;
int serversock;
int error;
char *ip;
......@@ -31,7 +32,7 @@ void connection_initialize(void);
void connection_shutdown(void);
void connection_accept_loop(void);
void connection_close(connection_t *con);
connection_t *create_connection(sock_t sock, char *ip);
connection_t *create_connection(sock_t sock, sock_t serversock, char *ip);
int connection_create_source(struct _client_tag *client, connection_t *con,
http_parser_t *parser, char *mount);
......
......@@ -91,7 +91,7 @@ static void create_relay_stream(char *server, int port,
WARN2("Failed to relay stream from master server, couldn't connect to http://%s:%d", server, port);
return;
}
con = create_connection(streamsock, NULL);
con = create_connection(streamsock, -1, NULL);
if(mp3) {
/* Some mp3 servers are bitchy, send a user-agent string to make them
* send the right response.
......
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