[Icecast] Add-on patch to support .pls .asx .ram .qtl listing formats

Guy Baconnière baco at infomaniak.ch
Sun Sep 24 01:51:01 PDT 2006


Hi,

If you have multiple players installed on your PC/Mac .m3u will always
open the last media player who are the default in charge of the extension
and mime m3u.

On your web site you want maybe to force a link to open real media player
or quicktime/itune. You need to create a .pls to force winamp loading the 
streaming because windows media player won't open .pls etc.

If you add a .pls file or other listing formats to icecast root you
will receive incorrect mime type so maybe a futur "todo" can be customized 
mime-types for each extension.

So I have included in attachement a patch to implement all listings formats
available in order to generate a listing with a link to the streaming.
Based on http://www.streamalot.com/playlists/playlist-formats.htm

I hope you can include this patch in your next release and make once again
icecast the best audio streaming server available on the market !
-- thanks for your great product !

Best Regards,
Guy Baconniere

--

Infomaniak Network SA
Guy Baconniere <baco at infomaniak.ch>
Unix System Administrator
Certified Linux Engineer (RHCE, LPIC-2)
Avenue de la Praille 26
1227 Carouge (Geneva)
Switzerland (CH)
Phone +41 (0)22 820 3541
Fax +41 (0)22 820 3546
AS29222 / BACO-RIPE



-------------- next part --------------
--- ChangeLog	2005-11-30 19:17:41.000000000 +0100
+++ ChangeLog	2006-09-22 15:52:11.191506000 +0200
@@ -1,3 +1,15 @@
+2006-09-22 16:38  baco
+
+	* trunk/icecast/src/admin.c, trunk/icecast/src/fserve.c,
+	  trunk/icecast/web/status.xsl, trunk/icecast/web/auth.xsl,
+	  trunk/icecast/admin/listmounts.xsl, trunk/icecast/admin/stats.xsl,
+	  trunk/icecast/admin/listclients.xsl, 
+	  trunk/icecast/doc/icecast2_basicsetup.html,
+	  trunk/icecast/doc/icecast2_listenerauth.html:
+	  add pls,asx,ram,qtl support when user want to launch a specific player
+	  Now support winamp, windows media player, real media player, quicktime player
+	  listing format.
+
 2005-11-29 03:06  karl
 
 	* trunk/icecast/src/auth_url.c: update for authentication header
--- admin/listclients.xsl	2005-09-27 22:22:18.000000000 +0200
+++ admin/listclients.xsl	2006-09-22 15:07:08.531673000 +0200
@@ -46,7 +46,15 @@
 <a href="/auth.xsl"><img border="0" src="/key.png"/></a>
 </xsl:when>
 <xsl:otherwise>
-<a href="{@mount}.m3u"><img border="0" src="/tunein.png"/></a>
+<a href="{@mount}.m3u"><img border="0" src="/tunein.png" alt="M3U"/></a>
+<xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;
+<a href="{@mount}.pls"><img border="0" src="/tunein.png" alt="PLS"/></a>
+<xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;
+<a href="{@mount}.asx"><img border="0" src="/tunein.png" alt="ASX"/></a>
+<xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;
+<a href="{@mount}.ram"><img border="0" src="/tunein.png" alt="RAM"/></a>
+<xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;
+<a href="{@mount}.qtl"><img border="0" src="/tunein.png" alt="QTL"/></a>
 </xsl:otherwise>
 </xsl:choose>
 <xsl:if test="server_name"><xsl:value-of select="server_name" /> </xsl:if>
--- admin/listmounts.xsl	2005-09-27 22:21:28.000000000 +0200
+++ admin/listmounts.xsl	2006-09-22 15:10:51.112936000 +0200
@@ -44,7 +44,15 @@
 <a href="/auth.xsl"><img border="0" src="/key.png"/></a>
 </xsl:when>
 <xsl:otherwise>
-<a href="{@mount}.m3u"><img border="0" src="/tunein.png"/></a>
+<a href="{@mount}.m3u"><img border="0" src="/tunein.png" alt="M3U"/></a>
+<xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;
+<a href="{@mount}.pls"><img border="0" src="/tunein.png" alt="PLS"/></a>
+<xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;
+<a href="{@mount}.asx"><img border="0" src="/tunein.png" alt="ASX"/></a>
+<xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;
+<a href="{@mount}.ram"><img border="0" src="/tunein.png" alt="RAM"/></a>
+<xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;
+<a href="{@mount}.qtl"><img border="0" src="/tunein.png" alt="QTL"/></a>
 </xsl:otherwise>
 </xsl:choose>
 <xsl:if test="server_name"><xsl:value-of select="server_name" /> </xsl:if>
--- admin/stats.xsl	2005-09-27 22:21:55.000000000 +0200
+++ admin/stats.xsl	2006-09-22 15:08:31.827158000 +0200
@@ -73,7 +73,15 @@
 <a href="/auth.xsl"><img border="0" src="/key.png"/></a>
 </xsl:when>
 <xsl:otherwise>
-<a href="{@mount}.m3u"><img border="0" src="/tunein.png"/></a>
+<a href="{@mount}.m3u"><img border="0" src="/tunein.png" alt="M3U"/></a>
+<xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;
+<a href="{@mount}.pls"><img border="0" src="/tunein.png" alt="PLS"/></a>
+<xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;
+<a href="{@mount}.asx"><img border="0" src="/tunein.png" alt="ASX"/></a>
+<xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;
+<a href="{@mount}.ram"><img border="0" src="/tunein.png" alt="RAM"/></a>
+<xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;
+<a href="{@mount}.qtl"><img border="0" src="/tunein.png" alt="QTL"/></a>
 </xsl:otherwise>
 </xsl:choose>
 Mount Point : (<xsl:value-of select="@mount" />)
--- doc/icecast2_basicsetup.html	2005-09-30 01:46:33.000000000 +0200
+++ doc/icecast2_basicsetup.html	2006-09-22 15:04:55.943809000 +0200
@@ -66,7 +66,7 @@
 </p>
 <p>Additionally, you will need to choose a mountpoint and specify this in the source client.  Icecast does not need to know about each mount point (although you can configure settings for specific mountpoint - this is covered under Advanced configuration) there are, however, some points to mention regarding mountpoints.  All Ogg Vorbis streams should have mountpoints that end in .ogg (i,e. /mystream.ogg).  This is due to the lazy way most media players infer the type of stream.  MP3 streams usually do not contain an extension (/mystream).  Mount points also should not contain any spaces or odd characters (again due to the lazy way many of the media players are coded).</p>
 <p>Once you have configured your source client, you should be able to connect it to the icecast server.  Verify that it is connected by hitting the stats.xml URL that was mentioned above.</p>
-<p>Now that you have the source connnected, listening to the stream involves simply opening the appropriate following URL in a browser: http://yourip:port/mounpointyouspecified.m3u.  So, for instance, if you attached your source client to an icecast server located at 192.168.1.10:8000 with a mountpoint of /mystream.ogg, then you would open : http://192.168.1.10:8000/mystream.ogg.m3u.  Note that the .m3u extention will serve up a link that opens most media players.  Also it is important to note that m3u need not contain only MP3 stream, it can contain streams of arbitrary content-type and is used by icecast to serve a playlist that represents your broadcast to listening clients.  Alternatively you can open up the stream URL directly within your media player (http://192.168.1.10:8000/mystream.ogg in this case)</p>
+<p>Now that you have the source connnected, listening to the stream involves simply opening the appropriate following URL in a browser: http://yourip:port/mounpointyouspecified.m3u or others listing formats .pls .asx .ram .qtl.  So, for instance, if you attached your source client to an icecast server located at 192.168.1.10:8000 with a mountpoint of /mystream.ogg, then you would open : http://192.168.1.10:8000/mystream.ogg.m3u or any other format like .ogg.pls .ogg.asx .ogg.ram .ogg.qtl.  Note that all extentions will serve up a link that opens media players.  Also it is important to note that all listing formats not contain only MP3 stream, it can contain streams of arbitrary content-type and is used by icecast to serve a playlist that represents your broadcast to listening clients.  Alternatively you can open up the stream URL directly within your media player (http://192.168.1.10:8000/mystream.ogg in this case)</p>
 <p>
 <br />
 <br />
--- doc/icecast2_listenerauth.html	2005-08-20 01:20:56.000000000 +0200
+++ doc/icecast2_listenerauth.html	2006-09-22 14:58:26.488075000 +0200
@@ -61,7 +61,7 @@
 <h3>Finishing it all off</h3>
 <p>Ok, so you've created your users, and you have everything setup properly, how do your users login ?  Well, we've provided a simple login form that you can use for this purpose.  This page (http://server:port/auth.xsl) will bring up a form that users can use to enter their username and password.</p>
 <img src="listener_auth3.jpg" alt="Screenshot of http://server:port/auth.xsl" />
-<p>This page will serve a m3u with the username and password and in most cases should open the correct media player and begin playing your stream</p>
+<p>This page will serve a m3u, pls, asx, ram, qtl with the username and password and in most cases should open the correct media player and begin playing your stream</p>
 <br />
 <br />
 <h2>URL</h2>
--- src/admin.c	2005-09-13 00:50:48.000000000 +0200
+++ src/admin.c	2006-09-22 17:05:53.541833000 +0200
@@ -79,6 +79,10 @@
 
 /* Admin commands requiring no auth */
 #define COMMAND_BUILDM3U                    501
+#define COMMAND_BUILDPLS                    502
+#define COMMAND_BUILDASX                    503
+#define COMMAND_BUILDRAM                    504
+#define COMMAND_BUILDQTL                    505
 
 #define FALLBACK_RAW_REQUEST "fallbacks"
 #define FALLBACK_TRANSFORMED_REQUEST "fallbacks.xsl"
@@ -108,6 +112,10 @@
 #define DEFAULT_RAW_REQUEST ""
 #define DEFAULT_TRANSFORMED_REQUEST ""
 #define BUILDM3U_RAW_REQUEST "buildm3u"
+#define BUILDPLS_RAW_REQUEST "buildpls"
+#define BUILDASX_RAW_REQUEST "buildasx"
+#define BUILDRAM_RAW_REQUEST "buildram"
+#define BUILDQTL_RAW_REQUEST "buildqtl"
 
 #define RAW         1
 #define TRANSFORMED 2
@@ -165,6 +173,14 @@
         return COMMAND_TRANSFORMED_UPDATEMETADATA;
     else if(!strcmp(command, BUILDM3U_RAW_REQUEST))
         return COMMAND_BUILDM3U;
+    else if(!strcmp(command, BUILDPLS_RAW_REQUEST))
+        return COMMAND_BUILDPLS;
+    else if(!strcmp(command, BUILDASX_RAW_REQUEST))
+        return COMMAND_BUILDASX;
+    else if(!strcmp(command, BUILDRAM_RAW_REQUEST))
+        return COMMAND_BUILDRAM;
+    else if(!strcmp(command, BUILDQTL_RAW_REQUEST))
+        return COMMAND_BUILDQTL;
     else if(!strcmp(command, DEFAULT_TRANSFORMED_REQUEST))
         return COMMAND_TRANSFORMED_STATS;
     else if(!strcmp(command, DEFAULT_RAW_REQUEST))
@@ -188,6 +204,14 @@
         int response);
 static void command_buildm3u(client_t *client, source_t *source,
         int response);
+static void command_buildpls(client_t *client, source_t *source,
+        int response);
+static void command_buildasx(client_t *client, source_t *source,
+        int response);
+static void command_buildram(client_t *client, source_t *source,
+        int response);
+static void command_buildqtl(client_t *client, source_t *source,
+        int response);
 static void command_kill_source(client_t *client, source_t *source,
         int response);
 static void command_updatemetadata(client_t *client, source_t *source,
@@ -360,7 +384,9 @@
     if(mount != NULL) {
         source_t *source;
 
-        if (command == COMMAND_BUILDM3U) {
+        if ( (command == COMMAND_BUILDM3U) || (command == COMMAND_BUILDPLS)
+          || (command == COMMAND_BUILDASX) || (command == COMMAND_BUILDRAM)
+          || (command == COMMAND_BUILDQTL) ) {
             noauth = 1;
         }
         /* This is a mount request, handle it as such */
@@ -528,6 +554,18 @@
         case COMMAND_BUILDM3U:
             command_buildm3u(client, source, RAW);
             break;
+        case COMMAND_BUILDPLS:
+            command_buildpls(client, source, RAW);
+            break;
+        case COMMAND_BUILDASX:
+            command_buildasx(client, source, RAW);
+            break;
+        case COMMAND_BUILDRAM:
+            command_buildram(client, source, RAW);
+            break;
+        case COMMAND_BUILDQTL:
+            command_buildqtl(client, source, RAW);
+            break;
         default:
             WARN0("Mount request not recognised");
             client_send_400(client, "Mount request unknown");
@@ -703,6 +741,138 @@
 }
 
 
+static void command_buildpls(client_t *client, source_t *source,
+    int response)
+{
+    char *username = NULL;
+    char *password = NULL;
+    ice_config_t *config;
+
+    COMMAND_REQUIRE(client, "username", username);
+    COMMAND_REQUIRE(client, "password", password);
+
+    client->respcode = 200;
+    config = config_get_config();
+    snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
+        "HTTP/1.0 200 OK\r\n"
+        "Content-Type: audio/x-scpls\r\n"
+        "Content-Disposition = attachment; filename=listen.pls\r\n\r\n" 
+        "[playlist]\r\n"
+        "File1=http://%s:%s@%s:%d%s\r\n"
+        "Title1=\r\n"
+        "Length1=-1\r\n"
+        "NumberOfEntries=1\r\n"
+        "Version=2\r\n",
+        username,
+        password,
+        config->hostname,
+        config->port,
+        source->mount
+    );
+    config_release_config();
+
+    client->refbuf->len = strlen (client->refbuf->data);
+    fserve_add_client (client, NULL);
+}
+
+
+static void command_buildasx(client_t *client, source_t *source,
+    int response)
+{
+    char *username = NULL;
+    char *password = NULL;
+    ice_config_t *config;
+
+    COMMAND_REQUIRE(client, "username", username);
+    COMMAND_REQUIRE(client, "password", password);
+
+    client->respcode = 200;
+    config = config_get_config();
+    snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
+        "HTTP/1.0 200 OK\r\n"
+        "Content-Type: video/x-ms-asf\r\n"
+        "Content-Disposition = attachment; filename=listen.asx\r\n\r\n" 
+        "<ASX version=\"3.0\">\r\n"
+        "<TITLE></TITLE>\r\n"
+        "<ENTRY>\r\n"
+        "<TITLE></TITLE>\r\n"
+        "<REF HREF=\"http://%s:%s@%s:%d%s\" />\r\n"
+        "</ENTRY>\r\n"
+        "</ASX>\r\n",
+        username,
+        password,
+        config->hostname,
+        config->port,
+        source->mount
+    );
+    config_release_config();
+
+    client->refbuf->len = strlen (client->refbuf->data);
+    fserve_add_client (client, NULL);
+}
+
+
+static void command_buildram(client_t *client, source_t *source,
+    int response)
+{
+    char *username = NULL;
+    char *password = NULL;
+    ice_config_t *config;
+
+    COMMAND_REQUIRE(client, "username", username);
+    COMMAND_REQUIRE(client, "password", password);
+
+    client->respcode = 200;
+    config = config_get_config();
+    snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
+        "HTTP/1.0 200 OK\r\n"
+        "Content-Type: audio/x-pn-realaudio\r\n"
+        "Content-Disposition = attachment; filename=listen.ram\r\n\r\n" 
+        "http://%s:%s@%s:%d%s\r\n",
+        username,
+        password,
+        config->hostname,
+        config->port,
+        source->mount
+    );
+    config_release_config();
+
+    client->refbuf->len = strlen (client->refbuf->data);
+    fserve_add_client (client, NULL);
+}
+
+
+static void command_buildqtl(client_t *client, source_t *source,
+    int response)
+{
+    char *username = NULL;
+    char *password = NULL;
+    ice_config_t *config;
+
+    COMMAND_REQUIRE(client, "username", username);
+    COMMAND_REQUIRE(client, "password", password);
+
+    client->respcode = 200;
+    config = config_get_config();
+    snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
+        "HTTP/1.0 200 OK\r\n"
+        "Content-Type: application/x-quicktimeplayer\r\n"
+        "Content-Disposition = attachment; filename=listen.qtl\r\n\r\n" 
+        "<?quicktime type=\"application/x-quicktime-media-link\"?>\r\n"
+        "<embed autoplay=\"true\" moviename=\"\" src=\"http://%s:%s@%s:%d%s.pls\" />\r\n",
+        username,
+        password,
+        config->hostname,
+        config->port,
+        source->mount
+    );
+    config_release_config();
+
+    client->refbuf->len = strlen (client->refbuf->data);
+    fserve_add_client (client, NULL);
+}
+
+
 static void command_manageauth(client_t *client, source_t *source,
     int response)
 {
--- src/fserve.c	2005-09-08 16:03:51.000000000 +0200
+++ src/fserve.c	2006-09-22 15:51:25.426800000 +0200
@@ -340,6 +340,14 @@
             return "image/png";
         else if(!strcmp(ext, "m3u"))
             return "audio/x-mpegurl";
+        else if(!strcmp(ext, "pls"))
+            return "audio/x-scpls";
+        else if(!strcmp(ext, "asx"))
+            return "video/x-ms-asf";
+        else if(!strcmp(ext, "ram"))
+            return "audio/x-pn-realaudio";
+        else if(!strcmp(ext, "qtl"))
+            return "application/x-quicktimeplayer";
         else
             return "application/octet-stream";
     }
@@ -376,6 +384,10 @@
     int ret = 0;
     char *fullpath;
     int m3u_requested = 0, m3u_file_available = 1;
+    int pls_requested = 0, pls_file_available = 1;
+    int asx_requested = 0, asx_file_available = 1;
+    int ram_requested = 0, ram_file_available = 1;
+    int qtl_requested = 0, qtl_file_available = 1;
     ice_config_t *config;
     FILE *file;
 
@@ -384,12 +396,20 @@
 
     if (strcmp (util_get_extension (fullpath), "m3u") == 0)
         m3u_requested = 1;
+    if (strcmp (util_get_extension (fullpath), "pls") == 0)
+        pls_requested = 1;
+    if (strcmp (util_get_extension (fullpath), "asx") == 0)
+        asx_requested = 1;
+    if (strcmp (util_get_extension (fullpath), "ram") == 0)
+        ram_requested = 1;
+    if (strcmp (util_get_extension (fullpath), "qtl") == 0)
+        qtl_requested = 1;
 
     /* check for the actual file */
     if (stat (fullpath, &file_buf) != 0)
     {
-        /* the m3u can be generated, but send an m3u file if available */
-        if (m3u_requested == 0)
+        /* an listing can be generated, but send an listing file if available */
+        if ( (m3u_requested == 0) && (pls_requested == 0) && (asx_requested == 0) && (ram_requested == 0) && (qtl_requested == 0) )
         {
             WARN2 ("req for file \"%s\" %s", fullpath, strerror (errno));
             client_send_404 (httpclient, "The file you requested could not be found");
@@ -397,6 +417,10 @@
             return -1;
         }
         m3u_file_available = 0;
+        pls_file_available = 0;
+        asx_file_available = 0;
+        ram_file_available = 0;
+        qtl_file_available = 0;
     }
 
     httpclient->refbuf->len = PER_CLIENT_REFBUF_SIZE;
@@ -443,6 +467,200 @@
         free (fullpath);
         return 0;
     }
+	if (pls_requested && pls_file_available == 0)
+    {
+        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;
+        if (host == NULL)
+        {
+            config = config_get_config();
+            snprintf (httpclient->refbuf->data, BUFSIZE,
+                    "HTTP/1.0 200 OK\r\n"
+                    "Content-Type: audio/x-scpls\r\n\r\n"
+                    "[playlist]\r\n"
+                    "File1=http://%s:%d%s\r\n"
+                    "Title1=\r\n"
+                    "Length1=-1\r\n"
+                    "NumberOfEntries=1\r\n"
+                    "Version=2\r\n",
+                    config->hostname, config->port,
+                    sourceuri
+                    );
+            config_release_config();
+        }
+        else
+        {
+            snprintf (httpclient->refbuf->data, BUFSIZE,
+                    "HTTP/1.0 200 OK\r\n"
+                    "Content-Type: audio/x-scpls\r\n\r\n"
+                    "[playlist]\r\n"
+                    "File1=http://%s%s\r\n"
+                    "Title1=\r\n"
+                    "Length1=-1\r\n"
+                    "NumberOfEntries=1\r\n"
+                    "Version=2\r\n",
+                    host, 
+                    sourceuri
+                    );
+        }
+        httpclient->refbuf->len = strlen (httpclient->refbuf->data);
+        fserve_add_client (httpclient, NULL);
+        free (sourceuri);
+        free (fullpath);
+        return 0;
+    }
+	if (asx_requested && asx_file_available == 0)
+    {
+        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;
+        if (host == NULL)
+        {
+            config = config_get_config();
+            snprintf (httpclient->refbuf->data, BUFSIZE,
+                    "HTTP/1.0 200 OK\r\n"
+                    "Content-Type: video/x-ms-asf\r\n\r\n"
+                    "<ASX version=\"3.0\">\r\n"
+                    "<TITLE></TITLE>\r\n"
+                    "<ENTRY>\r\n"
+                    "<TITLE></TITLE>\r\n"
+                    "<REF HREF=\"http://%s:%d%s\" />\r\n"
+                    "</ENTRY>\r\n"
+                    "</ASX>\r\n",
+                    config->hostname, config->port,
+                    sourceuri
+                    );
+            config_release_config();
+        }
+        else
+        {
+            snprintf (httpclient->refbuf->data, BUFSIZE,
+                    "HTTP/1.0 200 OK\r\n"
+                    "Content-Type: video/x-ms-asf\r\n\r\n"
+                    "<ASX version=\"3.0\">\r\n"
+                    "<TITLE></TITLE>\r\n"
+                    "<ENTRY>\r\n"
+                    "<TITLE></TITLE>\r\n"
+                    "<REF HREF=\"http://%s%s\" />\r\n"
+                    "</ENTRY>\r\n"
+                    "</ASX>\r\n",
+                    host, 
+                    sourceuri
+                    );
+        }
+        httpclient->refbuf->len = strlen (httpclient->refbuf->data);
+        fserve_add_client (httpclient, NULL);
+        free (sourceuri);
+        free (fullpath);
+        return 0;
+    }
+    if (ram_requested && ram_file_available == 0)
+    {
+        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;
+        if (host == NULL)
+        {
+            config = config_get_config();
+            snprintf (httpclient->refbuf->data, BUFSIZE,
+                    "HTTP/1.0 200 OK\r\n"
+                    "Content-Type: audio/x-pn-realaudio\r\n\r\n"
+                    "http://%s:%d%s\r\n", 
+                    config->hostname, config->port,
+                    sourceuri
+                    );
+            config_release_config();
+        }
+        else
+        {
+            snprintf (httpclient->refbuf->data, BUFSIZE,
+                    "HTTP/1.0 200 OK\r\n"
+                    "Content-Type: audio/x-pn-realaudio\r\n\r\n"
+                    "http://%s%s\r\n", 
+                    host, 
+                    sourceuri
+                    );
+        }
+        httpclient->refbuf->len = strlen (httpclient->refbuf->data);
+        fserve_add_client (httpclient, NULL);
+        free (sourceuri);
+        free (fullpath);
+        return 0;
+    }
+	if (qtl_requested && qtl_file_available == 0)
+    {
+        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;
+        if (host == NULL)
+        {
+            config = config_get_config();
+            snprintf (httpclient->refbuf->data, BUFSIZE,
+                    "HTTP/1.0 200 OK\r\n"
+                    "Content-Type: application/x-quicktimeplayer\r\n\r\n"
+                    "<?xml version=\"1.0\"?>\r\n"
+                    "<?quicktime type=\"application/x-quicktime-media-link\"?>\r\n"
+                    "<embed autoplay=\"true\" moviename=\"\" src=\"http://%s:%d%s.pls\" />\r\n",
+                    config->hostname, config->port,
+                    sourceuri
+                    );
+            config_release_config();
+        }
+        else
+        {
+            snprintf (httpclient->refbuf->data, BUFSIZE,
+                    "HTTP/1.0 200 OK\r\n"
+                    "Content-Type: application/x-quicktimeplayer\r\n\r\n"
+                    "<?xml version=\"1.0\"?>\r\n"
+                    "<?quicktime type=\"application/x-quicktime-media-link\"?>\r\n"
+                    "<embed autoplay=\"true\" moviename=\"\" src=\"http://%s%s.pls\" />\r\n",
+                    host, 
+                    sourceuri
+                    );
+        }
+        httpclient->refbuf->len = strlen (httpclient->refbuf->data);
+        fserve_add_client (httpclient, NULL);
+        free (sourceuri);
+        free (fullpath);
+        return 0;
+    }
 
     /* on demand file serving check */
     config = config_get_config();
--- web/auth.xsl	2005-08-20 01:20:56.000000000 +0200
+++ web/auth.xsl	2006-09-22 15:12:54.234812000 +0200
@@ -31,6 +31,42 @@
 </table>
 <input type="hidden" name="mount" value="{@mount}"/>
 </form>
+<br></br>
+<form method="GET" action="/admin/buildpls">
+<table border="0" cellpadding="4">
+<tr><td>Username : <input type="text" name="username"/></td></tr>
+<tr><td>Password : <input type="password" name="password"/></td></tr>
+<tr><td><input type="Submit" value="Login"/></td></tr>
+</table>
+<input type="hidden" name="mount" value="{@mount}"/>
+</form>
+<br></br>
+<form method="GET" action="/admin/buildasx">
+<table border="0" cellpadding="4">
+<tr><td>Username : <input type="text" name="username"/></td></tr>
+<tr><td>Password : <input type="password" name="password"/></td></tr>
+<tr><td><input type="Submit" value="Login"/></td></tr>
+</table>
+<input type="hidden" name="mount" value="{@mount}"/>
+</form>
+<br></br>
+<form method="GET" action="/admin/buildram">
+<table border="0" cellpadding="4">
+<tr><td>Username : <input type="text" name="username"/></td></tr>
+<tr><td>Password : <input type="password" name="password"/></td></tr>
+<tr><td><input type="Submit" value="Login"/></td></tr>
+</table>
+<input type="hidden" name="mount" value="{@mount}"/>
+</form>
+<br></br>
+<form method="GET" action="/admin/buildqtl">
+<table border="0" cellpadding="4">
+<tr><td>Username : <input type="text" name="username"/></td></tr>
+<tr><td>Password : <input type="password" name="password"/></td></tr>
+<tr><td><input type="Submit" value="Login"/></td></tr>
+</table>
+<input type="hidden" name="mount" value="{@mount}"/>
+</form>
 </xsl:if>
 </xsl:when>
 <xsl:otherwise>
--- web/status.xsl	2005-09-27 22:17:53.000000000 +0200
+++ web/status.xsl	2006-09-22 15:17:56.286132000 +0200
@@ -44,7 +44,15 @@
 <a href="/auth.xsl"><img border="0" src="/key.png"/></a>
 </xsl:when>
 <xsl:otherwise>
-<a href="{@mount}.m3u"><img border="0" src="/tunein.png"/></a>
+<a href="{@mount}.m3u"><img border="0" src="/tunein.png" alt="M3U"/></a>
+<xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;
+<a href="{@mount}.pls"><img border="0" src="/tunein.png" alt="PLS"/></a>
+<xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;
+<a href="{@mount}.asx"><img border="0" src="/tunein.png" alt="ASX"/></a>
+<xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;
+<a href="{@mount}.ram"><img border="0" src="/tunein.png" alt="RAM"/></a>
+<xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;
+<a href="{@mount}.qtl"><img border="0" src="/tunein.png" alt="QTL"/></a>
 </xsl:otherwise>
 </xsl:choose>
 Mount Point : (<xsl:value-of select="@mount" />) : 
@@ -53,7 +61,17 @@
 <a href="/auth.xsl">Click to Listen</a>
 </xsl:when>
 <xsl:otherwise>
-<a href="{@mount}.m3u">Click to Listen</a>
+Click to Listen :
+<xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;
+<a href="{@mount}.m3u">M3U</a>
+<xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;
+<a href="{@mount}.pls">PLS</a>
+<xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;
+<a href="{@mount}.asx">ASX</a>
+<xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;
+<a href="{@mount}.ram">RAM</a>
+<xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;
+<a href="{@mount}.qtl">QTL</a>
 </xsl:otherwise>
 </xsl:choose>
 </h3>


More information about the Icecast mailing list