sock->writeLineF("%s %s",HTTP_HS_CONTENT,MIME_MMS);
}else
{
- sock->writeLine("Content-Type: application/vnd.ms.wms-hdr.asfv1");
- if (ch)
- sock->writeLineF("Content-Length: %d",ch->headPack.len);
- sock->writeLine("Connection: Keep-Alive");
+ if (agent.contains("Android"))
+ {
+ LOG_DEBUG("INFO: Android client detected.");
+ sock->writeLineF("%s %s", HTTP_HS_CONTENT, MIME_WMV);
+ } else
+ {
+ sock->writeLine("Content-Type: application/vnd.ms.wms-hdr.asfv1");
+ if (ch)
+ sock->writeLineF("Content-Length: %d",ch->headPack.len);
+ sock->writeLine("Connection: Keep-Alive");
+ }
}
} else if (outputProtocol == ChanInfo::SP_PCP)
handshakeICY(Channel::SRC_ICECAST,isHTTP);
sock = NULL; // socket is taken over by channel, so don`t close it
- }else if (http.isRequest(servMgr->password))
+ } else if (http.isRequest("HEAD")) // for android client
+ {
+ char *str = in + 4;
+
+ if (str = stristr(str, "/stream/"))
+ {
+ int cnt = 0;
+
+ str += 8;
+ while (*str && (('0' <= *str && *str <= '9') || ('A' <= *str && *str <= 'F') || ('a' <= *str && *str <= 'f')))
+ ++cnt, ++str;
+
+ if (cnt == 32 && !strncmp(str, ".wmv", 4))
+ {
+ // interpret "HEAD /stream/[0-9a-fA-F]{32}.wmv" as GET
+ LOG_DEBUG("INFO: interpret as GET");
+
+ char *fn = in+5;
+
+ char *pt = strstr(fn,HTTP_PROTO1);
+ if (pt)
+ pt[-1] = 0;
+
+ if (!sock->host.isLocalhost())
+ if (!isAllowed(ALLOW_DIRECT) || !isFiltered(ServFilter::F_DIRECT))
+ throw HTTPException(HTTP_SC_UNAVAILABLE,503);
+
+ triggerChannel(fn+8,ChanInfo::SP_HTTP,isPrivate());
+
+ return;
+ }
+ }
+
+ if (http.isRequest(servMgr->password))
+ {
+ if (!isAllowed(ALLOW_BROADCAST))
+ throw HTTPException(HTTP_SC_UNAVAILABLE,503);
+
+ loginPassword.set(servMgr->password); // pwd already checked
+
+ sock->writeLine("OK2");
+ sock->writeLine("icy-caps:11");
+ sock->writeLine("");
+ LOG_DEBUG("ShoutCast client");
+
+ handshakeICY(Channel::SRC_SHOUTCAST,isHTTP);
+ sock = NULL; // socket is taken over by channel, so don`t close it
+
+ }else
+ {
+ throw HTTPException(HTTP_SC_BADREQUEST,400);
+ }
+ } else if (http.isRequest(servMgr->password))
{
if (!isAllowed(ALLOW_BROADCAST))
throw HTTPException(HTTP_SC_UNAVAILABLE,503);
#if 1 /* for VP extend version */
//#define VERSION_EX 1
static const char *PCP_CLIENT_VERSION_EX_PREFIX = "IM"; // 2bytes only
-static const int PCP_CLIENT_VERSION_EX_NUMBER = 40;
-static const char *PCX_AGENTEX = "PeerCast/0.1218(IM0040)";
-static const char *PCX_VERSTRING_EX = "v0.1218(IM0040)";
+static const int PCP_CLIENT_VERSION_EX_NUMBER = 41;
+static const char *PCX_AGENTEX = "PeerCast/0.1218(IM0041)";
+static const char *PCX_VERSTRING_EX = "v0.1218(IM0041)";
static const char *PCP_CLIENT_DIST_URL = "http://pecaim.net/";
static const char *PCP_CLIENT_VERSION_URL = "version.pecaim.net";
sock->writeLineF("%s %s",HTTP_HS_CONTENT,MIME_MMS);
}else
{
- sock->writeLine("Content-Type: application/vnd.ms.wms-hdr.asfv1");
- if (ch)
- sock->writeLineF("Content-Length: %d",ch->headPack.len);
- sock->writeLine("Connection: Keep-Alive");
+ if (agent.contains("Android"))
+ {
+ LOG_DEBUG("INFO: Android client detected.");
+ sock->writeLineF("%s %s", HTTP_HS_CONTENT, MIME_WMV);
+ } else
+ {
+ sock->writeLine("Content-Type: application/vnd.ms.wms-hdr.asfv1");
+ if (ch)
+ sock->writeLineF("Content-Length: %d",ch->headPack.len);
+ sock->writeLine("Connection: Keep-Alive");
+ }
}
} else if (outputProtocol == ChanInfo::SP_PCP)
handshakeICY(Channel::SRC_ICECAST,isHTTP);
sock = NULL; // socket is taken over by channel, so don`t close it
- }else if (http.isRequest(servMgr->password))
+ } else if (http.isRequest("HEAD")) // for android client
+ {
+ char *str = in + 4;
+
+ if (str = stristr(str, "/stream/"))
+ {
+ int cnt = 0;
+
+ str += 8;
+ while (*str && (('0' <= *str && *str <= '9') || ('A' <= *str && *str <= 'F') || ('a' <= *str && *str <= 'f')))
+ ++cnt, ++str;
+
+ if (cnt == 32 && !strncmp(str, ".wmv", 4))
+ {
+ // interpret "HEAD /stream/[0-9a-fA-F]{32}.wmv" as GET
+ LOG_DEBUG("INFO: interpret as GET");
+
+ char *fn = in+5;
+
+ char *pt = strstr(fn,HTTP_PROTO1);
+ if (pt)
+ pt[-1] = 0;
+
+ if (!sock->host.isLocalhost())
+ if (!isAllowed(ALLOW_DIRECT) || !isFiltered(ServFilter::F_DIRECT))
+ throw HTTPException(HTTP_SC_UNAVAILABLE,503);
+
+ triggerChannel(fn+8,ChanInfo::SP_HTTP,isPrivate());
+
+ return;
+ }
+ }
+
+ if (http.isRequest(servMgr->password))
+ {
+ if (!isAllowed(ALLOW_BROADCAST))
+ throw HTTPException(HTTP_SC_UNAVAILABLE,503);
+
+ loginPassword.set(servMgr->password); // pwd already checked
+
+ sock->writeLine("OK2");
+ sock->writeLine("icy-caps:11");
+ sock->writeLine("");
+ LOG_DEBUG("ShoutCast client");
+
+ handshakeICY(Channel::SRC_SHOUTCAST,isHTTP);
+ sock = NULL; // socket is taken over by channel, so don`t close it
+
+ }else
+ {
+ throw HTTPException(HTTP_SC_BADREQUEST,400);
+ }
+ } else if (http.isRequest(servMgr->password))
{
if (!isAllowed(ALLOW_BROADCAST))
throw HTTPException(HTTP_SC_UNAVAILABLE,503);
#if 1 /* for VP extend version */
//#define VERSION_EX 1
static const char *PCP_CLIENT_VERSION_EX_PREFIX = "IM"; // 2bytes only
-static const int PCP_CLIENT_VERSION_EX_NUMBER = 40;
-static const char *PCX_AGENTEX = "PeerCast/0.1218(IM0040)";
-static const char *PCX_VERSTRING_EX = "v0.1218(IM0040)";
+static const int PCP_CLIENT_VERSION_EX_NUMBER = 41;
+static const char *PCX_AGENTEX = "PeerCast/0.1218(IM0041)";
+static const char *PCX_VERSTRING_EX = "v0.1218(IM0041)";
static const char *PCP_CLIENT_DIST_URL = "http://pecaim.net/";
static const char *PCP_CLIENT_VERSION_URL = "version.pecaim.net";