aboutsummaryrefslogtreecommitdiff
path: root/oggcast~
diff options
context:
space:
mode:
authorFrank Barknecht <fbar@users.sourceforge.net>2003-09-13 20:36:38 +0000
committerFrank Barknecht <fbar@users.sourceforge.net>2003-09-13 20:36:38 +0000
commitb58e26cf0b0d8d31d7ce00293531e348cc85b172 (patch)
tree7402fb9d2c1afcac9a41a617d80a3f0991b4720a /oggcast~
parent714f584a5926f67180aef3d212c65224f629b416 (diff)
Added Olaf's support for newer Icecast2 servers using basic HTTP-auth.
svn path=/trunk/externals/pdogg/; revision=960
Diffstat (limited to 'oggcast~')
-rw-r--r--oggcast~/oggcast~.c77
1 files changed, 62 insertions, 15 deletions
diff --git a/oggcast~/oggcast~.c b/oggcast~/oggcast~.c
index 70b269b..f3f031d 100644
--- a/oggcast~/oggcast~.c
+++ b/oggcast~/oggcast~.c
@@ -98,7 +98,7 @@ areas.
#define MAXSTREAMCHANS 2 /* maximum number of channels: restricted to 2 by Ogg specs */
#define UPDATE_INTERVAL 250 /* time in milliseconds between updates of output values */
-static char *oggcast_version = "oggcast~: ogg/vorbis streaming client version 0.2h, written by Olaf Matthes";
+static char *oggcast_version = "oggcast~: ogg/vorbis streaming client version 0.2i, written by Olaf Matthes";
static t_class *oggcast_class;
@@ -191,6 +191,49 @@ typedef struct _oggcast
pthread_t x_childthread;
} t_oggcast;
+
+static char base64table[65] = {
+ 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
+ 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
+ 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
+ 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/',
+};
+
+ /* This isn't efficient, but it doesn't need to be */
+char *oggcast_util_base64_encode(char *data)
+{
+ int len = strlen(data);
+ char *out = malloc(len*4/3 + 4);
+ char *result = out;
+ int chunk;
+
+ while(len > 0) {
+ chunk = (len >3)?3:len;
+ *out++ = base64table[(*data & 0xFC)>>2];
+ *out++ = base64table[((*data & 0x03)<<4) | ((*(data+1) & 0xF0) >> 4)];
+
+ switch(chunk) {
+ case 3:
+ *out++ = base64table[((*(data+1) & 0x0F)<<2) | ((*(data+2) & 0xC0)>>6)];
+ *out++ = base64table[(*(data+2)) & 0x3F];
+ break;
+ case 2:
+ *out++ = base64table[((*(data+1) & 0x0F)<<2)];
+ *out++ = '=';
+ break;
+ case 1:
+ *out++ = '=';
+ *out++ = '=';
+ break;
+ }
+ data += chunk;
+ len -= chunk;
+ }
+ *out = 0;
+
+ return result;
+}
+
/* check server for writeability */
static int oggcast_checkserver(t_int sock)
{
@@ -564,20 +607,24 @@ static int oggcast_child_connect(char *hostname, char *mountpoint, t_int portno,
}
else /* or try to log in at IceCast2 server using HTTP/1.0 base auth scheme */
{
- /* send the request, a string like: "SOURCE /<mountpoint> HTTP/1.0\nContent-Type: application/x-ogg" */
- buf = "SOURCE ";
- send(sockfd, buf, strlen(buf), 0);
- buf = "/";
+ /* send the request, a string like: "SOURCE /<mountpoint> HTTP/1.0\n\r" */
+ buf = "SOURCE /";
send(sockfd, buf, strlen(buf), 0);
buf = mountpoint;
send(sockfd, buf, strlen(buf), 0);
- buf = " HTTP/1.0";
+ buf = " HTTP/1.0\r\n";
send(sockfd, buf, strlen(buf), 0);
- buf = "\nContent-Type: application/x-ogg";
+ /* send basic authorization */
+ sprintf(resp, "source:%s", passwd);
+ buf = oggcast_util_base64_encode(resp);
+ sprintf(resp, "Authorization: Basic %s\r\n", buf);
+ send(sockfd, resp, strlen(resp), 0);
+ /* send content type */
+ buf = "Content-Type: application/x-ogg";
send(sockfd, buf, strlen(buf), 0);
/* send the ice headers */
/* password */
- buf = "\nice-password: ";
+ buf = "\r\nice-password: ";
send(sockfd, buf, strlen(buf), 0);
buf = passwd;
send(sockfd, buf, strlen(buf), 0);
@@ -601,11 +648,11 @@ static int oggcast_child_connect(char *hostname, char *mountpoint, t_int portno,
send(sockfd, buf, strlen(buf), 0);
if(bcpublic==0) /* set the public flag for broadcast */
{
- buf = "no";
+ buf = "0";
}
else
{
- buf ="yes";
+ buf = "1";
}
send(sockfd, buf, strlen(buf), 0);
/* bitrate */
@@ -619,10 +666,10 @@ static int oggcast_child_connect(char *hostname, char *mountpoint, t_int portno,
/* description */
buf = "\r\nice-description: ";
send(sockfd, buf, strlen(buf), 0);
- buf = "ogg/vorbis streamed from pure-data with oggcast~";
+ buf = "Ogg/Vorbis streamed from Pure Data with oggcast~\r\n";
send(sockfd, buf, strlen(buf), 0);
- /* end of header */
- buf = "\r\n\r\n";
+ /* end of header: write an empty line */
+ buf = "\r\n";
send(sockfd, buf, strlen(buf), 0);
/* end login for IceCast2 using ICE/1.0 scheme */
}
@@ -1012,7 +1059,7 @@ static void *oggcast_new(t_floatarg fnchannels, t_floatarg fbufsize)
x->x_bcdate = "";
x->x_bcpublic = 1;
x->x_mountpoint = "puredata.ogg";
- x->x_servertype = 0; /* ICE/1.0 protocol for JRoar and old Icecast2 */
+ x->x_servertype = 1; /* HTTP/1.0 protocol for Icecast2 */
post(oggcast_version);
post("oggcast~: set buffer to %dk bytes", bufsize / 1024);
@@ -1390,4 +1437,4 @@ void oggcast_tilde_setup(void)
class_addmethod(oggcast_class, (t_method)oggcast_server, gensym("server"), A_FLOAT, 0);
class_addanything(oggcast_class, oggcast_comment);
class_sethelpsymbol(oggcast_class, gensym("help-oggcast~.pd"));
-} \ No newline at end of file
+}