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