/*
** ice.c
** $Id: ice.c,v 1.16 2003/06/16 17:41:01 brian Exp $
*/
#include "mod_mp3.h"
MP3_EXPORT(void) send_icecast_headers(request_rec *r, mp3_conf* cfg, request_data *request) {
#ifdef DEBUG
printf("Doing Icecast\n");
#endif
ap_rputs("HTTP/1.0 200 OK\n", r);
ap_rputs("Server: Apache/mod_mp3
\n", r);
ap_rprintf(r, "Content-Type: %s\n", cfg->content_type);
ap_rprintf(r, "x-audiocast-name:%s\n",cfg->cast_name);
ap_rprintf(r, "x-audiocast-genre:%s\n", cfg->genre_name);
ap_rprintf(r, "x-audiocast-url:%s\n", request->url);
ap_rprintf(r, "x-audiocast-streamid:\n");
ap_rprintf(r, "x-audiocast-public:1\n");
ap_rprintf(r, "x-audiocast-br:%d\n", BITRATE); /* Yes, this is a lie */
ap_rputs("x-audiocast-description: Served by Apache's mod_mp3
\n", r);
/* This means we are doing both types at once */
if(request->shout)
ap_rprintf(r, "icy-metaint:METADATA_INTERVAL\n");
if(mp3_match(ap_table_get(r->headers_in, "user-agent"), "*mozilla*")){
ap_rprintf(r, "Content-type:%s%s", cfg->content_type, MP3_CRLF);
}
ap_rputs("\n",r);
}
MP3_EXPORT(const char *) get_udp_message(pool *p, const char *name, const char *artist, const char *url, const char *title) {
if(artist) {
return ap_pstrcat(p,
"x-audiocast-udpseqnr:", ap_psprintf(p,"%d", (int)time(NULL)), MP3_CRLF,
"x-audiocast-streamtitle:", name, " - ", artist, MP3_CRLF,
"x-audiocast-streamurl:", url, MP3_CRLF,
// "x-audiocast-streammsg:", title, MP3_CRLF,
// "x-audiocast-streamlength:", "3.50", MP3_CRLF, // Fake it
NULL
);
} else {
return ap_pstrcat(p,
"x-audiocast-udpseqnr:", ap_psprintf(p,"%d", (int)time(NULL)), MP3_CRLF,
"x-audiocast-streamtitle:", name, MP3_CRLF,
"x-audiocast-streamurl:", url, MP3_CRLF,
// "x-audiocast-streammsg:", title, MP3_CRLF,
// "x-audiocast-streamlength:", "3.50", MP3_CRLF, // Fake it
NULL
);
}
}
MP3_EXPORT(void) send_udp_message(request_rec *r, int port, const char *message) {
struct sockaddr_in serv;
struct hostent *hp;
int socket = -1;
memset(&serv, 0, sizeof(serv));
serv.sin_family = AF_INET;
serv.sin_port = htons(port);
/* Yes, this is a waste */
hp = gethostbyname(r->connection->remote_ip);
memcpy(&serv.sin_addr, hp->h_addr, hp->h_length);
if((socket = ap_psocket (r->pool, AF_INET, SOCK_DGRAM, 0)) < 0) {
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, "Failing socket creation(%s)", strerror(errno));
return;
}
if(fcntl(socket, F_SETFL, O_NONBLOCK) < 0) {
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
"Failing blocking for %s(%s)",
r->connection->remote_ip,
strerror(errno));
ap_pclosesocket(r->pool, socket);
return;
}
if (sendto(socket, message, strlen(message), MSG_DONTWAIT, (struct sockaddr *)&serv, sizeof(serv)) == -1) {
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
"Failing sending a message to %s(%s)",
r->connection->remote_ip,
strerror(errno));
}
ap_pclosesocket(r->pool, socket);
return;
}