diff --git a/HISTORY b/HISTORY index 7972b60..715be4d 100644 --- a/HISTORY +++ b/HISTORY @@ -1,7 +1,6 @@ VDR Plugin 'streamdev' Revision History --------------------------------------- -- dropped cServerConnection::m_Pending - the icy-name HTTP header sent with radio streams makes VLC pick the wrong demuxer. Send icy-name only for ES audio streams. - fixed regression of "live TV must be switched in VDR main thread" change: diff --git a/server/connection.c b/server/connection.c index 64b912c..a73470b 100644 --- a/server/connection.c +++ b/server/connection.c @@ -66,6 +66,7 @@ cServerConnection::cServerConnection(const char *Protocol, int Type): cTBSocket(Type), m_Protocol(Protocol), m_DeferClose(false), + m_Pending(false), m_ReadBytes(0), m_WriteBytes(0), m_WriteIndex(0) @@ -195,6 +196,8 @@ bool cServerConnection::Write(void) if (m_WriteIndex == m_WriteBytes) { m_WriteIndex = 0; m_WriteBytes = 0; + if (m_Pending) + Command(NULL); if (m_DeferClose) return false; Flushed(); @@ -202,12 +205,12 @@ bool cServerConnection::Write(void) return true; } -bool cServerConnection::Respond(const char *Message, ...) +bool cServerConnection::Respond(const char *Message, bool Last, ...) { char *buffer; int length; va_list ap; - va_start(ap, Message); + va_start(ap, Last); length = vasprintf(&buffer, Message, ap); va_end(ap); @@ -230,6 +233,7 @@ bool cServerConnection::Respond(const char *Message, ...) m_WriteBytes += length; m_WriteBuffer[m_WriteBytes++] = '\015'; m_WriteBuffer[m_WriteBytes++] = '\012'; + m_Pending = !Last; return true; } diff --git a/server/connection.h b/server/connection.h index e269ec3..6cc6764 100644 --- a/server/connection.h +++ b/server/connection.h @@ -25,6 +25,7 @@ class cServerConnection: public cListObject, public cTBSocket private: const char *m_Protocol; bool m_DeferClose; + bool m_Pending; char m_ReadBuffer[MAXPARSEBUFFER]; uint m_ReadBytes; @@ -52,8 +53,12 @@ protected: virtual bool Command(char *Cmd) = 0; /* Will put Message into the response queue, which will be sent in the next - server cycle. Note that Message will be line-terminated by Respond. */ - virtual bool Respond(const char *Message, ...); + server cycle. Note that Message will be line-terminated by Respond. + Only one line at a time may be sent. If there are lines to follow, set + Last to false. Command(NULL) will be called in the next cycle, so you can + post the next line. */ + virtual bool Respond(const char *Message, bool Last = true, ...); + //__attribute__ ((format (printf, 2, 4))); /* Add a request header */ void SetHeader(const char *Name, const char *Value, const char *Prefix = "") { m_Headers.insert(tStrStr(std::string(Prefix) + Name, Value)); } @@ -82,8 +87,8 @@ public: virtual bool HasData(void) const; /* Gets called by server when the socket can accept more data. Writes - the buffer filled up by Respond(). Returns false in case of an - error */ + the buffer filled up by Respond(). Calls Command(NULL) if there is a + command pending. Returns false in case of an error */ virtual bool Write(void); /* Gets called by server when there is incoming data to read. Calls @@ -123,7 +128,7 @@ public: inline bool cServerConnection::HasData(void) const { - return m_WriteBytes > 0 || m_DeferClose; + return m_WriteBytes > 0 || m_Pending || m_DeferClose; } #endif // VDR_STREAMDEV_SERVER_CONNECTION_H diff --git a/server/connectionHTTP.c b/server/connectionHTTP.c index 7dd2d11..ffcc924 100644 --- a/server/connectionHTTP.c +++ b/server/connectionHTTP.c @@ -147,7 +147,7 @@ bool cConnectionHTTP::ProcessRequest(void) esyslog("streamdev-server connectionHTTP: Missing method or pathinfo"); } else if (it_method->second.compare("GET") == 0 && ProcessURI(it_pathinfo->second)) { if (m_ChannelList) - return Respond("%s", m_ChannelList->HttpHeader().c_str()); + return Respond("%s", true, m_ChannelList->HttpHeader().c_str()); else if (m_Channel != NULL) { cDevice *device = NULL; if (ProvidesChannel(m_Channel, 0)) @@ -164,7 +164,7 @@ bool cConnectionHTTP::ProcessRequest(void) } else if (m_StreamType == stES && (m_Apid[0] || m_Dpid[0] || ISRADIO(m_Channel))) { return Respond("HTTP/1.0 200 OK") && Respond("Content-Type: audio/mpeg") - && Respond("icy-name: %s", m_Channel->Name()) + && Respond("icy-name: %s", true, m_Channel->Name()) && Respond(""); } else if (ISRADIO(m_Channel)) { return Respond("HTTP/1.0 200 OK") @@ -190,7 +190,7 @@ bool cConnectionHTTP::ProcessRequest(void) } else if (it_method->second.compare("HEAD") == 0 && ProcessURI(it_pathinfo->second)) { DeferClose(); if (m_ChannelList) - return Respond("%s", m_ChannelList->HttpHeader().c_str()); + return Respond("%s", true, m_ChannelList->HttpHeader().c_str()); else if (m_Channel != NULL) { if (ProvidesChannel(m_Channel, 0)) { if (m_StreamType == stEXT) { @@ -200,7 +200,7 @@ bool cConnectionHTTP::ProcessRequest(void) } else if (m_StreamType == stES && (m_Apid[0] || m_Dpid[0] || ISRADIO(m_Channel))) { return Respond("HTTP/1.0 200 OK") && Respond("Content-Type: audio/mpeg") - && Respond("icy-name: %s", m_Channel->Name()) + && Respond("icy-name: %s", true, m_Channel->Name()) && Respond(""); } else if (ISRADIO(m_Channel)) { return Respond("HTTP/1.0 200 OK") @@ -235,7 +235,7 @@ void cConnectionHTTP::Flushed(void) if (m_ChannelList) { if (m_ChannelList->HasNext()) { - if (!Respond("%s", m_ChannelList->Next().c_str())) + if (!Respond("%s", true, m_ChannelList->Next().c_str())) DeferClose(); } else {