MythTV  master
httprequest.h
Go to the documentation of this file.
1 // Program Name: httprequest.h
3 // Created : Oct. 21, 2005
4 //
5 // Purpose : Http Request/Response
6 //
7 // Copyright (c) 2005 David Blain <dblain@mythtv.org>
8 //
9 // Licensed under the GPL v2 or later, see COPYING for details
10 //
12 
13 #ifndef HTTPREQUEST_H_
14 #define HTTPREQUEST_H_
15 
16 #include <utility>
17 
18 // Qt headers
19 #include <QBuffer>
20 #include <QDateTime>
21 #include <QFile>
22 #include <QRegularExpression>
23 #include <QTcpSocket>
24 #include <QTextStream>
25 
26 // MythTV headers
27 #include "mythsession.h"
28 
29 #include "upnpexp.h"
30 #include "upnputil.h"
31 #include "serializers/serializer.h"
32 
33 #define SOAP_ENVELOPE_BEGIN "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" " \
34  "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" \
35  "<s:Body>"
36 #define SOAP_ENVELOPE_END "</s:Body>\r\n</s:Envelope>";
37 
38 
40 // Typedefs / Defines
42 
44 {
46  // HTTP 1.1
47  RequestTypeGet = 0x0001,
48  RequestTypeHead = 0x0002,
49  RequestTypePost = 0x0004,
50 // RequestTypePut = 0x0008,
51 // RequestTypeDelete = 0x0010,
52 // RequestTypeConnect = 0x0020,
54 // RequestTypeTrace = 0x0080, // SECURITY: XST attack risk, shouldn't include cookies or other sensitive info
55  // UPnP
60  // Not a request type
61  RequestTypeResponse = 0x1000
62 
63 };
64 
66 {
69  ContentType_XML = 2
70 };
71 
73 {
85 };
86 
87 struct MIMETypes
88 {
89  const char *pszExtension;
90  const char *pszType;
91 
92 };
93 
95 
97 {
98  public:
99  virtual void ExecutePostProcess( ) = 0;
100  virtual ~IPostProcess() = default;
101 };
102 
104 //
106 
108 {
109  protected:
110 
111  static const char *s_szServerHeaders;
112 
113  QRegularExpression m_procReqLineExp {"\\s+"};
114  QRegularExpression m_parseRangeExp {"(\\d|\\-)"};
115 
116  public:
117 
120 
121  QString m_sRawRequest; // e.g. GET /foo/bar.html HTTP/1.1
122 
123  QString m_sOriginalUrl; // Raw request URL before % decoded
124  QString m_sRequestUrl; // Raw request URL
125  QString m_sBaseUrl; // Path section of URL, without parameters
126  QString m_sResourceUrl; // Duplicate of Base URL!?
127  QString m_sMethod;
128 
132 
133  QString m_sPayload;
134 
135  QString m_sProtocol;
136  int m_nMajor {0};
137  int m_nMinor {0};
138 
139  bool m_bProtected {false};
140  bool m_bEncrypted {false};
141 
142  bool m_bSOAPRequest {false};
143  QString m_sNameSpace;
144 
145  // Response
146 
148  QString m_sResponseTypeText; // used for ResponseTypeOther
149 
150  long m_nResponseStatus {200};
152 
153  QString m_sFileName;
154 
155  QBuffer m_response;
156 
157  IPostProcess *m_pPostProcess {nullptr};
158 
161 
162  private:
163 
164  bool m_bKeepAlive {true};
165  uint m_nKeepAliveTimeout {0};
166 
167  protected:
168 
169  HttpRequestType SetRequestType ( const QString &sType );
170  void SetRequestProtocol ( const QString &sLine );
171  HttpContentType SetContentType ( const QString &sType );
172 
173  void ProcessRequestLine ( const QString &sLine );
174  bool ProcessSOAPPayload ( const QString &sSOAPAction );
175  void ExtractMethodFromURL( ); // Service method, not HTTP method
176 
177  QString GetResponseStatus ( void ) const;
178  QString GetResponseType ( void ) const;
179  QString GetResponseHeaders ( void );
180 
181  bool ParseRange ( QString sRange,
182  long long llSize,
183  long long *pllStart,
184  long long *pllEnd );
185 
186  bool ParseKeepAlive ( void );
187 
188  void ParseCookies ( void );
189 
190  QString BuildResponseHeader ( long long nSize );
191 
192  qint64 SendData ( QIODevice *pDevice, qint64 llStart, qint64 llBytes );
193  qint64 SendFile ( QFile &file, qint64 llStart, qint64 llBytes );
194 
195  bool IsProtected () const { return m_bProtected; }
196  bool IsEncrypted () const { return m_bEncrypted; }
197  bool Authenticated ();
198 
199  QString GetAuthenticationHeader (bool isStale = false);
200  QString CalculateDigestNonce ( const QString &timeStamp) const;
201 
202  bool BasicAuthentication ();
203  bool DigestAuthentication ();
204  void AddCORSHeaders ( const QString &sOrigin );
205 
206  public:
207 
208  HTTPRequest () { m_response.open( QIODevice::ReadWrite ); }
209  virtual ~HTTPRequest () = default;
210 
211  bool ParseRequest ();
212 
213  void FormatErrorResponse ( bool bServerError,
214  const QString &sFaultString,
215  const QString &sDetails );
216 
217  void FormatActionResponse( Serializer *ser );
218  void FormatActionResponse( const NameValues &pArgs );
219  void FormatFileResponse ( const QString &sFileName );
220  void FormatRawResponse ( const QString &sXML );
221 
222  qint64 SendResponse ( void );
223  qint64 SendResponseFile( const QString& sFileName );
224 
225  void SetResponseHeader ( const QString &sKey,
226  const QString &sValue,
227  bool replace = false );
228 
229  void SetCookie ( const QString &sKey, const QString &sValue,
230  const QDateTime &expiryDate,
231  bool secure );
232 
233  QString GetRequestHeader ( const QString &sKey, const QString &sDefault );
234 
235  bool GetKeepAlive () const { return m_bKeepAlive; }
236 
237  Serializer * GetSerializer ();
238 
239  QByteArray GetResponsePage ( void ); // Static response e.g. 400, 404, 501
240 
241  QString GetRequestProtocol () const;
242  static QString GetResponseProtocol () ;
243 
244  QString GetRequestType () const;
245  QString GetLastHeader( const QString &sType ) const;
246 
247  static QString GetMimeType ( const QString &sFileExtension );
248  static QStringList GetSupportedMimeTypes ();
249  static QString TestMimeType ( const QString &sFileName );
250  static long GetParameters ( QString sParams, QStringMap &mapParams );
251  static QString Encode ( const QString &sIn );
252  static QString Decode ( const QString &sIn );
253  static QString GetETagHash ( const QByteArray &data );
254 
255  void SetKeepAliveTimeout ( int nTimeout ) { m_nKeepAliveTimeout = nTimeout; }
256 
257  static bool IsUrlProtected ( const QString &sBaseUrl );
258 
259  // ------------------------------------------------------------------
260 
261  virtual QString ReadLine ( int msecs ) = 0;
262  virtual qint64 ReadBlock ( char *pData, qint64 nMaxLen, int msecs = 0 ) = 0;
263  virtual qint64 WriteBlock ( const char *pData,
264  qint64 nLen ) = 0;
265  virtual QString GetHostName (); // RFC 3875 - The name in the client request
266  virtual QString GetHostAddress () = 0;
267  virtual quint16 GetHostPort () = 0;
268  virtual QString GetPeerAddress () = 0;
269  virtual int getSocketHandle () = 0;
270 };
271 
273 //
275 
277 {
278  public:
279 
280  QTcpSocket *m_pSocket {nullptr};
281 
282  public:
283 
284  explicit BufferedSocketDeviceRequest( QTcpSocket *pSocket )
285  : m_pSocket(pSocket) {}
286  ~BufferedSocketDeviceRequest() override = default;
287 
288  QString ReadLine ( int msecs ) override; // HTTPRequest
289  qint64 ReadBlock ( char *pData, qint64 nMaxLen, int msecs = 0 ) override; // HTTPRequest
290  qint64 WriteBlock ( const char *pData, qint64 nLen ) override; // HTTPRequest
291  QString GetHostAddress () override; // HTTPRequest
292  quint16 GetHostPort () override; // HTTPRequest
293  QString GetPeerAddress () override; // HTTPRequest
294  int getSocketHandle () override // HTTPRequest
295  {return( m_pSocket->socketDescriptor() ); }
296 
297 };
298 
300 //
302 
304 {
305  public:
306  int m_code {-1};
307  QString m_msg;
308 
309  explicit HttpException( int nCode = -1, QString sMsg = "")
310  : m_code( nCode ), m_msg (std::move( sMsg ))
311  {}
312 
313  // Needed to force a v-table.
314  virtual ~HttpException() = default;
315 };
316 
318 {
319  public:
320 
321  QString m_hostName;
322  //int m_port;
323 
324  explicit HttpRedirectException( QString sHostName = "",
325  int nCode = -1,
326  const QString &sMsg = "" )
327  : HttpException( nCode, sMsg ), m_hostName(std::move( sHostName ))
328  {}
329 
330  ~HttpRedirectException() override = default;
331 
332 };
333 
334 #endif
HTTPRequest::~HTTPRequest
virtual ~HTTPRequest()=default
BufferedSocketDeviceRequest::getSocketHandle
int getSocketHandle() override
Definition: httprequest.h:294
ContentType_XML
@ ContentType_XML
Definition: httprequest.h:69
HTTPRequest::m_sBaseUrl
QString m_sBaseUrl
Definition: httprequest.h:125
HttpException::m_msg
QString m_msg
Definition: httprequest.h:307
HTTPRequest
Definition: httprequest.h:108
ContentType_Unknown
@ ContentType_Unknown
Definition: httprequest.h:67
ContentType_Urlencoded
@ ContentType_Urlencoded
Definition: httprequest.h:68
HttpRedirectException::~HttpRedirectException
~HttpRedirectException() override=default
HttpRedirectException::m_hostName
QString m_hostName
Definition: httprequest.h:321
ResponseTypeCSS
@ ResponseTypeCSS
Definition: httprequest.h:79
Serializer
Definition: serializer.h:32
HTTPRequest::GetHostPort
virtual quint16 GetHostPort()=0
BufferedSocketDeviceRequest::GetHostPort
quint16 GetHostPort() override
Definition: httprequest.cpp:2479
BufferedSocketDeviceRequest::GetPeerAddress
QString GetPeerAddress() override
Definition: httprequest.cpp:2489
HTTPRequest::m_sMethod
QString m_sMethod
Definition: httprequest.h:127
HTTPRequest::m_sResourceUrl
QString m_sResourceUrl
Definition: httprequest.h:126
BufferedSocketDeviceRequest::GetHostAddress
QString GetHostAddress() override
Definition: httprequest.cpp:2470
ResponseTypeUnknown
@ ResponseTypeUnknown
Definition: httprequest.h:75
HTTPRequest::IsEncrypted
bool IsEncrypted() const
Definition: httprequest.h:196
HTTPRequest::m_sProtocol
QString m_sProtocol
Definition: httprequest.h:135
HTTPRequest::m_sResponseTypeText
QString m_sResponseTypeText
Definition: httprequest.h:148
HTTPRequest::m_sOriginalUrl
QString m_sOriginalUrl
Definition: httprequest.h:123
HTTPRequest::GetPeerAddress
virtual QString GetPeerAddress()=0
HttpRedirectException::HttpRedirectException
HttpRedirectException(QString sHostName="", int nCode=-1, const QString &sMsg="")
Definition: httprequest.h:324
MIMETypes
Definition: httprequest.h:88
ResponseTypeJS
@ ResponseTypeJS
Definition: httprequest.h:78
ResponseTypeNone
@ ResponseTypeNone
Definition: httprequest.h:74
RequestTypePost
@ RequestTypePost
Definition: httprequest.h:49
RequestTypeOptions
@ RequestTypeOptions
Definition: httprequest.h:53
RequestTypeResponse
@ RequestTypeResponse
Definition: httprequest.h:61
HTTPRequest::m_userSession
MythUserSession m_userSession
Definition: httprequest.h:160
build_compdb.file
file
Definition: build_compdb.py:55
RequestTypeSubscribe
@ RequestTypeSubscribe
Definition: httprequest.h:57
RequestTypeUnsubscribe
@ RequestTypeUnsubscribe
Definition: httprequest.h:58
BufferedSocketDeviceRequest::~BufferedSocketDeviceRequest
~BufferedSocketDeviceRequest() override=default
HTTPRequest::m_sPrivateToken
QString m_sPrivateToken
Definition: httprequest.h:159
ResponseTypeFile
@ ResponseTypeFile
Definition: httprequest.h:82
MythUserSession
Definition: mythsession.h:17
ResponseTypeHeader
@ ResponseTypeHeader
Definition: httprequest.h:84
HTTPRequest::m_mapRespHeaders
QStringMap m_mapRespHeaders
Definition: httprequest.h:151
HTTPRequest::WriteBlock
virtual qint64 WriteBlock(const char *pData, qint64 nLen)=0
NameValues
Definition: upnputil.h:89
hardwareprofile.smolt.secure
secure
Definition: smolt.py:95
HTTPRequest::s_szServerHeaders
static const char * s_szServerHeaders
Definition: httprequest.h:111
IPostProcess::~IPostProcess
virtual ~IPostProcess()=default
HttpContentType
HttpContentType
Definition: httprequest.h:66
RequestTypeMSearch
@ RequestTypeMSearch
Definition: httprequest.h:56
HTTPRequest::m_mapParams
QStringMap m_mapParams
Definition: httprequest.h:129
HTTPRequest::SetKeepAliveTimeout
void SetKeepAliveTimeout(int nTimeout)
Definition: httprequest.h:255
QStringMap
QMap< QString, QString > QStringMap
Definition: upnputil.h:44
RequestTypeHead
@ RequestTypeHead
Definition: httprequest.h:48
IPostProcess::ExecutePostProcess
virtual void ExecutePostProcess()=0
BufferedSocketDeviceRequest::BufferedSocketDeviceRequest
BufferedSocketDeviceRequest(QTcpSocket *pSocket)
Definition: httprequest.h:284
HTTPRequest::m_sRequestUrl
QString m_sRequestUrl
Definition: httprequest.h:124
HttpException
Definition: httprequest.h:304
ResponseTypeXML
@ ResponseTypeXML
Definition: httprequest.h:76
MIMETypes::pszType
const char * pszType
Definition: httprequest.h:90
serializer.h
HTTPRequest::HTTPRequest
HTTPRequest()
Definition: httprequest.h:208
HTTPRequest::m_sRawRequest
QString m_sRawRequest
Definition: httprequest.h:121
uint
unsigned int uint
Definition: compat.h:141
QStringMultiMap
QMultiMap< QString, QString > QStringMultiMap
Definition: upnputil.h:45
HTTPRequest::m_mapHeaders
QStringMultiMap m_mapHeaders
Definition: httprequest.h:130
ResponseTypeOther
@ ResponseTypeOther
Definition: httprequest.h:83
HTTPRequest::m_sFileName
QString m_sFileName
Definition: httprequest.h:153
IPostProcess
Definition: httprequest.h:97
ResponseTypeHTML
@ ResponseTypeHTML
Definition: httprequest.h:77
ResponseTypeText
@ ResponseTypeText
Definition: httprequest.h:80
RequestTypeNotify
@ RequestTypeNotify
Definition: httprequest.h:59
BufferedSocketDeviceRequest
Definition: httprequest.h:277
BufferedSocketDeviceRequest::WriteBlock
qint64 WriteBlock(const char *pData, qint64 nLen) override
Definition: httprequest.cpp:2453
HTTPRequest::getSocketHandle
virtual int getSocketHandle()=0
HTTPRequest::IsProtected
bool IsProtected() const
Definition: httprequest.h:195
HttpRedirectException
Definition: httprequest.h:318
HttpResponseType
HttpResponseType
Definition: httprequest.h:73
HTTPRequest::m_sPayload
QString m_sPayload
Definition: httprequest.h:133
HTTPRequest::GetKeepAlive
bool GetKeepAlive() const
Definition: httprequest.h:235
UPNP_PUBLIC
#define UPNP_PUBLIC
Definition: upnpexp.h:9
HTTPRequest::m_sNameSpace
QString m_sNameSpace
Definition: httprequest.h:143
HttpException::HttpException
HttpException(int nCode=-1, QString sMsg="")
Definition: httprequest.h:309
RequestTypeUnknown
@ RequestTypeUnknown
Definition: httprequest.h:45
BufferedSocketDeviceRequest::m_pSocket
QTcpSocket * m_pSocket
Definition: httprequest.h:280
HttpException::~HttpException
virtual ~HttpException()=default
ResponseTypeSVG
@ ResponseTypeSVG
Definition: httprequest.h:81
HTTPRequest::GetHostAddress
virtual QString GetHostAddress()=0
HTTPRequest::ReadBlock
virtual qint64 ReadBlock(char *pData, qint64 nMaxLen, int msecs=0)=0
RequestTypeGet
@ RequestTypeGet
Definition: httprequest.h:47
upnputil.h
BufferedSocketDeviceRequest::ReadLine
QString ReadLine(int msecs) override
Definition: httprequest.cpp:2386
MIMETypes::pszExtension
const char * pszExtension
Definition: httprequest.h:89
HTTPRequest::m_response
QBuffer m_response
Definition: httprequest.h:155
HTTPRequest::ReadLine
virtual QString ReadLine(int msecs)=0
mythsession.h
HttpRequestType
HttpRequestType
Definition: httprequest.h:44
BufferedSocketDeviceRequest::ReadBlock
qint64 ReadBlock(char *pData, qint64 nMaxLen, int msecs=0) override
Definition: httprequest.cpp:2418
upnpexp.h
HTTPRequest::m_mapCookies
QStringMap m_mapCookies
Definition: httprequest.h:131