diff --git a/src/admin.c b/src/admin.c index e2bbea4f..eca2837c 100644 --- a/src/admin.c +++ b/src/admin.c @@ -747,7 +747,6 @@ static void command_buildm3u(client_t *client, source_t *source, admin_format_t const char *mount = source->mount; const char *username = NULL; const char *password = NULL; - ice_config_t *config; ssize_t ret; COMMAND_REQUIRE(client, "username", username); @@ -766,17 +765,7 @@ static void command_buildm3u(client_t *client, source_t *source, admin_format_t } - config = config_get_config(); - snprintf(client->refbuf->data + ret, PER_CLIENT_REFBUF_SIZE - ret, - "Content-Disposition: attachment; filename=listen.m3u\r\n\r\n" - "http://%s:%s@%s:%d%s\r\n", - username, - password, - config->hostname, - config->port, - mount - ); - config_release_config(); + client_get_baseurl(client, NULL, client->refbuf->data + ret, PER_CLIENT_REFBUF_SIZE - ret, username, password, "Content-Disposition: attachment; filename=listen.m3u\r\n\r\n", mount, "\r\n"); client->respcode = 200; client->refbuf->len = strlen (client->refbuf->data); @@ -1131,7 +1120,7 @@ static void command_stats(client_t *client, source_t *source, admin_format_t res ICECAST_LOG_DEBUG("Stats request, sending xml stats"); - doc = stats_get_xml(1, mount, client->mode); + doc = stats_get_xml(1, mount, client); admin_send_response(doc, client, response, STATS_HTML_REQUEST); xmlFreeDoc(doc); return; diff --git a/src/client.c b/src/client.c index b4373042..bfcf4844 100644 --- a/src/client.c +++ b/src/client.c @@ -48,6 +48,7 @@ #include "util.h" #include "acl.h" +#include "listensocket.h" /* for ADMIN_COMMAND_ERROR */ #include "admin.h" @@ -766,3 +767,91 @@ client_slurp_result_t client_body_skip(client_t *client) break; } } + +ssize_t client_get_baseurl(client_t *client, listensocket_t *listensocket, char *buf, size_t len, const char *user, const char *pw, const char *prefix, const char *suffix0, const char *suffix1) +{ + const listener_t *listener = NULL; + const ice_config_t *config = NULL; + const char *host = NULL; + const char *proto = "http"; + int port = 0; + ssize_t ret; + tlsmode_t tlsmode = ICECAST_TLSMODE_AUTO; + protocol_t protocol = ICECAST_PROTOCOL_HTTP; + + if (!buf || !len) + return -1; + + if (!prefix) + prefix = ""; + + if (!suffix0) + suffix0 = ""; + + if (!suffix1) + suffix1 = ""; + + if (client) { + host = httpp_getvar(client->parser, "host"); + + /* at least a couple of players (fb2k/winamp) are reported to send a + * host header but without the port number. So if we are missing the + * port then lets treat it as if no host line was sent */ + if (host && strchr(host, ':') == NULL) + host = NULL; + + listensocket = client->con->listensocket_effective; + tlsmode = client->con->tlsmode; + protocol = client->protocol; + } + + if (!host && listensocket) { + listener = listensocket_get_listener(listensocket); + if (listener) { + host = listener->bind_address; + port = listener->port; + if (!client) + tlsmode = listener->tls; + } + } + + if (!host) { + config = config_get_config(); + host = config->hostname; + if (!port) + port = config->port; + } + + switch (tlsmode) { + case ICECAST_TLSMODE_DISABLED: + case ICECAST_TLSMODE_AUTO: + switch (protocol) { + case ICECAST_PROTOCOL_HTTP: proto = "http"; break; + case ICECAST_PROTOCOL_SHOUTCAST: proto = "icy"; break; + } + break; + case ICECAST_TLSMODE_AUTO_NO_PLAIN: + case ICECAST_TLSMODE_RFC2817: + case ICECAST_TLSMODE_RFC2818: + switch (protocol) { + case ICECAST_PROTOCOL_HTTP: proto = "https"; break; + case ICECAST_PROTOCOL_SHOUTCAST: proto = "icys"; break; + } + break; + } + + if (host && port) { + ret = snprintf(buf, len, "%s%s://%s%s%s%s%s:%i%s%s", prefix, proto, user ? user : "", pw ? ":" : "", pw ? pw : "", (user || pw) ? "@" : "", host, port, suffix0, suffix1); + } else if (host) { + ret = snprintf(buf, len, "%s%s://%s%s%s%s%s%s%s", prefix, proto, user ? user : "", pw ? ":" : "", pw ? pw : "", (user || pw) ? "@" : "", host, suffix0, suffix1); + } else { + ret = -1; + } + + if (config) + config_release_config(); + if (listener) + listensocket_release_listener(listensocket); + + return ret; +} diff --git a/src/client.h b/src/client.h index 9d426c44..e3c0bb58 100644 --- a/src/client.h +++ b/src/client.h @@ -151,5 +151,6 @@ ssize_t client_body_read(client_t *client, void *buf, size_t len); int client_body_eof(client_t *client); client_slurp_result_t client_body_slurp(client_t *client, void *buf, size_t *len); client_slurp_result_t client_body_skip(client_t *client); +ssize_t client_get_baseurl(client_t *client, listensocket_t *listensocket, char *buf, size_t len, const char *user, const char *pw, const char *prefix, const char *suffix0, const char *suffix1); #endif /* __CLIENT_H__ */ diff --git a/src/fserve.c b/src/fserve.c index e7158449..f526c0db 100644 --- a/src/fserve.c +++ b/src/fserve.c @@ -452,16 +452,9 @@ int fserve_client_create (client_t *httpclient, const char *path) if (m3u_requested && m3u_file_available == 0) { - const char *host = httpp_getvar (httpclient->parser, "host"); char *sourceuri = strdup (path); char *dot = strrchr(sourceuri, '.'); - /* at least a couple of players (fb2k/winamp) are reported to send a - * host header but without the port number. So if we are missing the - * port then lets treat it as if no host line was sent */ - if (host && strchr (host, ':') == NULL) - host = NULL; - *dot = 0; httpclient->respcode = 200; ret = util_http_build_header (httpclient->refbuf->data, BUFSIZE, 0, @@ -473,24 +466,7 @@ int fserve_client_create (client_t *httpclient, const char *path) free(sourceuri); return -1; } - if (host == NULL) - { - config = config_get_config(); - snprintf (httpclient->refbuf->data + ret, BUFSIZE - ret, - "http://%s:%d%s\r\n", - config->hostname, config->port, - sourceuri - ); - config_release_config(); - } - else - { - snprintf (httpclient->refbuf->data + ret, BUFSIZE - ret, - "http://%s%s\r\n", - host, - sourceuri - ); - } + client_get_baseurl(httpclient, NULL, httpclient->refbuf->data + ret, BUFSIZE - ret, NULL, NULL, NULL, sourceuri, "\r\n"); httpclient->refbuf->len = strlen (httpclient->refbuf->data); fserve_add_client (httpclient, NULL); free (sourceuri); @@ -504,7 +480,7 @@ int fserve_client_create (client_t *httpclient, const char *path) char *eol = strrchr (reference, '.'); if (eol) *eol = '\0'; - doc = stats_get_xml (0, reference, httpclient->mode); + doc = stats_get_xml (0, reference, httpclient); free (reference); admin_send_response (doc, httpclient, ADMIN_FORMAT_HTML, xslt_playlist_requested); xmlFreeDoc(doc); diff --git a/src/source.c b/src/source.c index 7a7e0a65..2887322c 100644 --- a/src/source.c +++ b/src/source.c @@ -616,19 +616,8 @@ static FILE * source_open_dumpfile(const char * filename) { */ static void source_init (source_t *source) { - ice_config_t *config = config_get_config(); - char *listenurl; + char listenurl[512]; const char *str; - int listen_url_size; - - /* 6 for max size of port */ - listen_url_size = strlen("http://") + strlen(config->hostname) + - strlen(":") + 6 + strlen(source->mount) + 1; - - listenurl = malloc (listen_url_size); - snprintf (listenurl, listen_url_size, "http://%s:%d%s", - config->hostname, config->port, source->mount); - config_release_config(); str = httpp_getvar(source->parser, "ice-audio-info"); source->audio_info = util_dict_new(); @@ -638,10 +627,9 @@ static void source_init (source_t *source) stats_event (source->mount, "audio_info", str); } + client_get_baseurl(NULL, NULL, listenurl, sizeof(listenurl), NULL, NULL, NULL, NULL, NULL); stats_event (source->mount, "listenurl", listenurl); - free(listenurl); - if (source->dumpfilename != NULL) { source->dumpfile = source_open_dumpfile (source->dumpfilename); diff --git a/src/stats.c b/src/stats.c index 07cf534c..0f9d9ce9 100644 --- a/src/stats.c +++ b/src/stats.c @@ -829,7 +829,7 @@ static inline void __add_authstack (auth_stack_t *stack, xmlNodePtr parent) { auth_stack_next(&stack); } } -static xmlNodePtr _dump_stats_to_doc (xmlNodePtr root, const char *show_mount, int hidden) { +static xmlNodePtr _dump_stats_to_doc (xmlNodePtr root, const char *show_mount, int hidden, client_t *client) { avl_node *avlnode; xmlNodePtr ret = NULL; ice_config_t *config; @@ -870,7 +870,13 @@ static xmlNodePtr _dump_stats_to_doc (xmlNodePtr root, const char *show_mount, i while (avlnode2) { stats_node_t *stat = avlnode2->key; - xmlNewTextChild (xmlnode, NULL, XMLSTR(stat->name), XMLSTR(stat->value)); + if (client && strcmp(stat->name, "listenurl") == 0) { + char buf[512]; + client_get_baseurl(client, NULL, buf, sizeof(buf), NULL, NULL, NULL, source->source, NULL); + xmlNewTextChild (xmlnode, NULL, XMLSTR(stat->name), XMLSTR(buf)); + } else { + xmlNewTextChild (xmlnode, NULL, XMLSTR(stat->name), XMLSTR(stat->value)); + } avlnode2 = avl_get_next (avlnode2); } @@ -1022,7 +1028,7 @@ void stats_transform_xslt(client_t *client, const char *uri) char *xslpath = util_get_path_from_normalised_uri(uri); const char *mount = httpp_get_param(client->parser, "mount"); - doc = stats_get_xml(0, mount, client->mode); + doc = stats_get_xml(0, mount, client); xslt_transform(doc, xslpath, client, 200); @@ -1053,7 +1059,7 @@ static void __add_metadata(xmlNodePtr node, const char *tag) { free(name); } -xmlDocPtr stats_get_xml(int show_hidden, const char *show_mount, operation_mode mode) +xmlDocPtr stats_get_xml(int show_hidden, const char *show_mount, client_t *client) { xmlDocPtr doc; xmlNodePtr node; @@ -1063,12 +1069,12 @@ xmlDocPtr stats_get_xml(int show_hidden, const char *show_mount, operation_mode node = xmlNewDocNode (doc, NULL, XMLSTR("icestats"), NULL); xmlDocSetRootElement(doc, node); - node = _dump_stats_to_doc (node, show_mount, show_hidden); + node = _dump_stats_to_doc(node, show_mount, show_hidden, client); if (show_mount && node) { avl_tree_rlock(global.source_tree); source = source_find_mount_raw(show_mount); - admin_add_listeners_to_mount(source, node, mode); + admin_add_listeners_to_mount(source, node, client->mode); avl_tree_unlock(global.source_tree); } diff --git a/src/stats.h b/src/stats.h index 3ec72214..d004782f 100644 --- a/src/stats.h +++ b/src/stats.h @@ -18,7 +18,6 @@ #include #include "icecasttypes.h" -#include "cfgfile.h" #include "refbuf.h" typedef struct _stats_node_tag @@ -95,7 +94,7 @@ void stats_callback (client_t *client, void *notused); void stats_transform_xslt(client_t *client, const char *uri); void stats_sendxml(client_t *client); -xmlDocPtr stats_get_xml(int show_hidden, const char *show_mount, operation_mode mode); +xmlDocPtr stats_get_xml(int show_hidden, const char *show_mount, client_t *client); char *stats_get_value(const char *source, const char *name); #endif /* __STATS_H__ */ diff --git a/src/xslt.c b/src/xslt.c index 366ed4c2..821660ef 100644 --- a/src/xslt.c +++ b/src/xslt.c @@ -53,6 +53,7 @@ #include "stats.h" #include "fserve.h" #include "util.h" +#include "cfgfile.h" #define CATMODULE "xslt"