mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2025-02-02 15:07:36 -05:00
Implementation of aliases contributed by Paul Donohue <icecast@TopQuark.net>
svn path=/trunk/icecast/; revision=4629
This commit is contained in:
parent
776f759736
commit
8527ed7b43
3
News
3
News
@ -1,3 +1,6 @@
|
||||
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>
|
||||
|
51
src/config.c
51
src/config.c
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user