1/* ---------------------------------------------------------------------------
2** This software is in the public domain, furnished "as is", without technical
3** support, and with no warranty, express or implied, as to its usefulness for
4** any purpose.
5**
6** HTTPServer.h
7**
8** V4L2 RTSP streamer
9**
10** HTTP server that serves HLS & MPEG-DASH playlist and segments
11**
12** -------------------------------------------------------------------------*/
13
14
15#include "RTSPServer.hh"
16#include "RTSPCommon.hh"
17
18// ---------------------------------------------------------
19// Extend RTSP server to add support for HLS and MPEG-DASH
20// ---------------------------------------------------------
21class HTTPServer : public RTSPServer
22{
23
24 class HTTPClientConnection : public RTSPServer::RTSPClientConnection
25 {
26 public:
27 HTTPClientConnection(RTSPServer& ourServer, int clientSocket, struct sockaddr_in clientAddr)
28 : RTSPServer::RTSPClientConnection(ourServer, clientSocket, clientAddr), fTCPSink(NULL), fStreamToken(NULL), fSubsession(NULL), fSource(NULL) {
29 }
30 virtual ~HTTPClientConnection();
31
32 private:
33
34 void sendHeader(const char* contentType, unsigned int contentLength);
35 void streamSource(FramedSource* source);
36 void streamSource(const std::string & content);
37 ServerMediaSubsession* getSubsesion(const char* urlSuffix);
38 bool sendFile(char const* urlSuffix);
39 bool sendM3u8PlayList(char const* urlSuffix);
40 bool sendMpdPlayList(char const* urlSuffix);
41 virtual void handleHTTPCmd_StreamingGET(char const* urlSuffix, char const* fullRequestStr);
42 virtual void handleCmd_notFound();
43 static void afterStreaming(void* clientData);
44
45 private:
46 static u_int32_t fClientSessionId;
47 TCPStreamSink* fTCPSink;
48 void* fStreamToken;
49 ServerMediaSubsession* fSubsession;
50 FramedSource* fSource;
51 };
52
53 public:
54 static HTTPServer* createNew(UsageEnvironment& env, Port rtspPort, UserAuthenticationDatabase* authDatabase, unsigned reclamationTestSeconds, unsigned int hlsSegment, const std::string webroot)
55 {
56 HTTPServer* httpServer = NULL;
57 int ourSocket = setUpOurSocket(env, rtspPort);
58 if (ourSocket != -1)
59 {
60 httpServer = new HTTPServer(env, ourSocket, rtspPort, authDatabase, reclamationTestSeconds, hlsSegment, webroot);
61 }
62 return httpServer;
63 }
64
65 HTTPServer(UsageEnvironment& env, int ourSocket, Port rtspPort, UserAuthenticationDatabase* authDatabase, unsigned reclamationTestSeconds, unsigned int hlsSegment, const std::string & webroot)
66 : RTSPServer(env, ourSocket, rtspPort, authDatabase, reclamationTestSeconds), m_hlsSegment(hlsSegment), m_webroot(webroot)
67 {
68 if ( (!m_webroot.empty()) && (*m_webroot.rend() != '/') ) {
69 m_webroot += "/";
70 }
71 }
72
73 RTSPServer::RTSPClientConnection* createNewClientConnection(int clientSocket, struct sockaddr_in clientAddr)
74 {
75 return new HTTPClientConnection(*this, clientSocket, clientAddr);
76 }
77
78 private:
79 const unsigned int m_hlsSegment;
80 std::string m_webroot;
81};
82
83