vdr-plugin-streamdev/server/connectionHTTP.c

205 lines
5.2 KiB
C
Raw Normal View History

2004-12-30 23:43:55 +01:00
/*
* $Id: connectionHTTP.c,v 1.12 2007/05/09 09:12:42 schmirl Exp $
2004-12-30 23:43:55 +01:00
*/
#include <ctype.h>
2004-12-30 23:43:55 +01:00
#include "server/connectionHTTP.h"
#include "server/setup.h"
2005-02-11 17:44:14 +01:00
cConnectionHTTP::cConnectionHTTP(void):
cServerConnection("HTTP"),
m_Status(hsRequest),
m_LiveStreamer(NULL),
m_Channel(NULL),
m_Apid(0),
m_StreamType((eStreamType)StreamdevServerSetup.HTTPStreamType),
m_ListChannel(NULL)
{
Dprintf("constructor hsRequest\n");
2004-12-30 23:43:55 +01:00
}
2005-02-11 17:44:14 +01:00
cConnectionHTTP::~cConnectionHTTP()
{
delete m_LiveStreamer;
2004-12-30 23:43:55 +01:00
}
2005-02-11 17:44:14 +01:00
bool cConnectionHTTP::Command(char *Cmd)
{
Dprintf("command %s\n", Cmd);
2004-12-30 23:43:55 +01:00
switch (m_Status) {
case hsRequest:
2005-02-11 17:44:14 +01:00
Dprintf("Request\n");
m_Request = Cmd;
m_Status = hsHeaders;
return true;
2004-12-30 23:43:55 +01:00
case hsHeaders:
if (*Cmd == '\0') {
2005-02-11 17:44:14 +01:00
m_Status = hsBody;
return ProcessRequest();
}
Dprintf("header\n");
return true;
default:
break;
2005-02-11 17:44:14 +01:00
}
return false; // ??? shouldn't happen
}
2005-05-09 22:22:29 +02:00
bool cConnectionHTTP::ProcessRequest(void)
{
2005-02-11 17:44:14 +01:00
Dprintf("process\n");
if (m_Request.substr(0, 4) == "GET " && CmdGET(m_Request.substr(4))) {
switch (m_Job) {
case hjListing:
return Respond("HTTP/1.0 200 OK")
&& Respond("Content-Type: text/html")
&& Respond("")
&& Respond("<html><head><title>VDR Channel Listing</title></head>")
&& Respond("<body><ul>");
case hjTransfer:
if (m_Channel == NULL) {
2004-12-30 23:43:55 +01:00
DeferClose();
return Respond("HTTP/1.0 404 not found");
}
2005-02-11 17:44:14 +01:00
2004-12-30 23:43:55 +01:00
m_LiveStreamer = new cStreamdevLiveStreamer(0);
cDevice *device = GetDevice(m_Channel, 0);
if (device != NULL) {
device->SwitchChannel(m_Channel, false);
if (m_LiveStreamer->SetChannel(m_Channel, m_StreamType, m_Apid)) {
2005-02-08 20:54:52 +01:00
m_LiveStreamer->SetDevice(device);
if (!SetDSCP())
LOG_ERROR_STR("unable to set DSCP sockopt");
2005-02-11 17:44:14 +01:00
if (m_StreamType == stES && (m_Apid != 0 || ISRADIO(m_Channel))) {
2004-12-30 23:43:55 +01:00
return Respond("HTTP/1.0 200 OK")
2005-02-11 17:44:14 +01:00
&& Respond("Content-Type: audio/mpeg")
2005-05-09 22:22:29 +02:00
&& Respond("icy-name: %s", true, m_Channel->Name())
2005-02-11 17:44:14 +01:00
&& Respond("");
2004-12-30 23:43:55 +01:00
} else {
return Respond("HTTP/1.0 200 OK")
2005-02-11 17:44:14 +01:00
&& Respond("Content-Type: video/mpeg")
&& Respond("");
2004-12-30 23:43:55 +01:00
}
}
}
DELETENULL(m_LiveStreamer);
DeferClose();
2006-01-26 20:40:18 +01:00
return Respond("HTTP/1.0 409 Channel not available")
&& Respond("");
2004-12-30 23:43:55 +01:00
}
}
2005-02-11 17:44:14 +01:00
DeferClose();
2006-01-26 20:40:18 +01:00
return Respond("HTTP/1.0 400 Bad Request")
&& Respond("");
2004-12-30 23:43:55 +01:00
}
2005-05-09 22:22:29 +02:00
void cConnectionHTTP::Flushed(void)
{
2005-02-11 17:44:14 +01:00
std::string line;
if (m_Status != hsBody)
return;
switch (m_Job) {
case hjListing:
2004-12-30 23:43:55 +01:00
if (m_ListChannel == NULL) {
Respond("</ul></body></html>");
DeferClose();
2005-02-11 17:44:14 +01:00
m_Status = hsFinished;
2004-12-30 23:43:55 +01:00
return;
}
if (m_ListChannel->GroupSep())
2005-02-08 18:22:35 +01:00
line = (std::string)"<li>--- " + m_ListChannel->Name() + "---</li>";
2005-02-11 17:44:14 +01:00
else {
int index = 1;
2005-02-08 18:22:35 +01:00
line = (std::string)"<li><a href=\"http://" + LocalIp() + ":"
+ (const char*)itoa(StreamdevServerSetup.HTTPServerPort) + "/"
2005-02-11 17:44:14 +01:00
+ StreamTypes[m_StreamType] + "/"
2005-02-08 18:22:35 +01:00
+ (const char*)m_ListChannel->GetChannelID().ToString() + "\">"
2005-02-11 17:44:14 +01:00
+ m_ListChannel->Name() + "</a> ";
for (int i = 0; m_ListChannel->Apid(i) != 0; ++i, ++index) {
line += "<a href=\"http://" + LocalIp() + ":"
+ (const char*)itoa(StreamdevServerSetup.HTTPServerPort) + "/"
+ StreamTypes[m_StreamType] + "/"
+ (const char*)m_ListChannel->GetChannelID().ToString() + "+"
+ (const char*)itoa(index) + "\">("
+ m_ListChannel->Alang(i) + ")</a> ";
}
for (int i = 0; m_ListChannel->Dpid(i) != 0; ++i, ++index) {
line += "<a href=\"http://" + LocalIp() + ":"
+ (const char*)itoa(StreamdevServerSetup.HTTPServerPort) + "/"
+ StreamTypes[m_StreamType] + "/"
+ (const char*)m_ListChannel->GetChannelID().ToString() + "+"
+ (const char*)itoa(index) + "\">("
+ m_ListChannel->Dlang(i) + ")</a> ";
}
line += "</li>";
}
2005-05-09 22:22:29 +02:00
if (!Respond(line.c_str()))
2004-12-30 23:43:55 +01:00
DeferClose();
m_ListChannel = Channels.Next(m_ListChannel);
2005-02-11 17:44:14 +01:00
break;
case hjTransfer:
2004-12-30 23:43:55 +01:00
Dprintf("streamer start\n");
m_LiveStreamer->Start(this);
2005-02-11 17:44:14 +01:00
m_Status = hsFinished;
break;
2004-12-30 23:43:55 +01:00
}
}
2005-05-09 22:22:29 +02:00
bool cConnectionHTTP::CmdGET(const std::string &Opts)
{
2005-02-11 17:44:14 +01:00
const char *sp = Opts.c_str(), *ptr = sp, *ep;
const cChannel *chan;
int apid = 0;
2004-12-30 23:43:55 +01:00
2005-02-11 17:44:14 +01:00
ptr = skipspace(ptr);
while (*ptr == '/')
++ptr;
2004-12-30 23:43:55 +01:00
2005-02-11 17:44:14 +01:00
if (strncasecmp(ptr, "PS/", 3) == 0) {
2004-12-30 23:43:55 +01:00
m_StreamType = stPS;
2005-02-11 17:44:14 +01:00
ptr += 3;
} else if (strncasecmp(ptr, "PES/", 4) == 0) {
2004-12-30 23:43:55 +01:00
m_StreamType = stPES;
2005-02-11 17:44:14 +01:00
ptr += 4;
} else if (strncasecmp(ptr, "TS/", 3) == 0) {
2004-12-30 23:43:55 +01:00
m_StreamType = stTS;
2005-02-11 17:44:14 +01:00
ptr += 3;
} else if (strncasecmp(ptr, "ES/", 3) == 0) {
2004-12-30 23:43:55 +01:00
m_StreamType = stES;
2005-02-11 17:44:14 +01:00
ptr += 3;
} else if (strncasecmp(ptr, "Extern/", 3) == 0) {
m_StreamType = stExtern;
ptr += 7;
2004-12-30 23:43:55 +01:00
}
2005-02-11 17:44:14 +01:00
while (*ptr == '/')
++ptr;
for (ep = ptr + strlen(ptr); ep >= ptr && !isspace(*ep); --ep)
2004-12-30 23:43:55 +01:00
;
2005-02-11 17:44:14 +01:00
std::string filespec = Opts.substr(ptr - sp, ep - ptr);
Dprintf("substr: %s\n", filespec.c_str());
2004-12-30 23:43:55 +01:00
Dprintf("before channelfromstring\n");
2005-02-11 17:44:14 +01:00
if (filespec == "" || filespec.substr(0, 12) == "channels.htm") {
2004-12-30 23:43:55 +01:00
m_ListChannel = Channels.First();
2005-02-11 17:44:14 +01:00
m_Job = hjListing;
} else if ((chan = ChannelFromString(filespec.c_str(), &apid)) != NULL) {
2004-12-30 23:43:55 +01:00
m_Channel = chan;
m_Apid = apid;
Dprintf("Apid is %d\n", apid);
2005-02-11 17:44:14 +01:00
m_Job = hjTransfer;
2004-12-30 23:43:55 +01:00
}
Dprintf("after channelfromstring\n");
2004-12-30 23:43:55 +01:00
return true;
}