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=\"htstp://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
62 
63 };
64 
66 {
71 };
72 
74 {
86 };
87 
88 struct MIMETypes
89 {
90  const char *pszExtension;
91  const char *pszType;
92 
93 };
94 
96 
98 {
99  public:
100  virtual void ExecutePostProcess( ) = 0;
101  virtual ~IPostProcess() = default;
102 };
103 
105 //
107 
109 {
110  protected:
111 
112  static const char *s_szServerHeaders;
113 
114  QRegularExpression m_procReqLineExp {"\\s+"};
115  QRegularExpression m_parseRangeExp {"(\\d|\\-)"};
116 
117  public:
118 
121 
122  QString m_sRawRequest; // e.g. GET /foo/bar.html HTTP/1.1
123 
124  QString m_sOriginalUrl; // Raw request URL before % decoded
125  QString m_sRequestUrl; // Raw request URL
126  QString m_sBaseUrl; // Path section of URL, without parameters
127  QString m_sResourceUrl; // Duplicate of Base URL!?
128  QString m_sMethod;
129 
133 
134  QString m_sPayload;
135 
136  QString m_sProtocol;
137  int m_nMajor {0};
138  int m_nMinor {0};
139 
140  bool m_bProtected {false};
141  bool m_bEncrypted {false};
142 
143  bool m_bSOAPRequest {false};
144  QString m_sNameSpace;
145 
146  // Response
147 
149  QString m_sResponseTypeText; // used for ResponseTypeOther
150 
151  long m_nResponseStatus {200};
153 
154  QString m_sFileName;
155 
156  QBuffer m_response;
157 
158  IPostProcess *m_pPostProcess {nullptr};
159 
162 
163  private:
164 
165  bool m_bKeepAlive {true};
166  std::chrono::seconds m_nKeepAliveTimeout {0s};
167 
168  protected:
169 
170  HttpRequestType SetRequestType ( const QString &sType );
171  void SetRequestProtocol ( const QString &sLine );
172  HttpContentType SetContentType ( const QString &sType );
173 
174  void ProcessRequestLine ( const QString &sLine );
175  bool ProcessSOAPPayload ( const QString &sSOAPAction );
176  void ExtractMethodFromURL( ); // Service method, not HTTP method
177 
178  QString GetResponseStatus ( void ) const;
179  QString GetResponseType ( void ) const;
180  QString GetResponseHeaders ( void );
181 
182  bool ParseRange ( QString sRange,
183  long long llSize,
184  long long *pllStart,
185  long long *pllEnd );
186 
187  bool ParseKeepAlive ( void );
188 
189  void ParseCookies ( void );
190 
191  QString BuildResponseHeader ( long long nSize );
192 
193  qint64 SendData ( QIODevice *pDevice, qint64 llStart, qint64 llBytes );
194  qint64 SendFile ( QFile &file, qint64 llStart, qint64 llBytes );
195 
196  bool IsProtected () const { return m_bProtected; }
197  bool IsEncrypted () const { return m_bEncrypted; }
198  bool Authenticated ();
199 
200  QString GetAuthenticationHeader (bool isStale = false);
201  QString CalculateDigestNonce ( const QString &timeStamp) const;
202 
203  bool BasicAuthentication ();
204  bool DigestAuthentication ();
205  void AddCORSHeaders ( const QString &sOrigin );
206 
207  public:
208 
209  HTTPRequest () { m_response.open( QIODevice::ReadWrite ); }
210  virtual ~HTTPRequest () = default;
211 
212  bool ParseRequest ();
213 
214  void FormatErrorResponse ( bool bServerError,
215  const QString &sFaultString,
216  const QString &sDetails );
217 
218  void FormatActionResponse( Serializer *ser );
219  void FormatActionResponse( const NameValues &pArgs );
220  void FormatFileResponse ( const QString &sFileName );
221  void FormatRawResponse ( const QString &sXML );
222 
223  qint64 SendResponse ( void );
224  qint64 SendResponseFile( const QString& sFileName );
225 
226  void SetResponseHeader ( const QString &sKey,
227  const QString &sValue,
228  bool replace = false );
229 
230  void SetCookie ( const QString &sKey, const QString &sValue,
231  const QDateTime &expiryDate,
232  bool secure );
233 
234  QString GetRequestHeader ( const QString &sKey, const QString &sDefault );
235 
236  bool GetKeepAlive () const { return m_bKeepAlive; }
237 
238  Serializer * GetSerializer ();
239 
240  QByteArray GetResponsePage ( void ); // Static response e.g. 400, 404, 501
241 
242  QString GetRequestProtocol () const;
243  static QString GetResponseProtocol () ;
244 
245  QString GetRequestType () const;
246  QString GetLastHeader( const QString &sType ) const;
247 
248  static QString GetMimeType ( const QString &sFileExtension );
249  static QStringList GetSupportedMimeTypes ();
250  static QString TestMimeType ( const QString &sFileName );
251  static long GetParameters ( QString sParams, QStringMap &mapParams );
252  static QString Encode ( const QString &sIn );
253  static QString Decode ( const QString &sIn );
254  static QString GetETagHash ( const QByteArray &data );
255 
256  void SetKeepAliveTimeout ( std::chrono::seconds nTimeout ) { m_nKeepAliveTimeout = nTimeout; }
257 
258  static bool IsUrlProtected ( const QString &sBaseUrl );
259 
260  // ------------------------------------------------------------------
261 
262  virtual QString ReadLine ( std::chrono::milliseconds msecs ) = 0;
263  virtual qint64 ReadBlock ( char *pData, qint64 nMaxLen, std::chrono::milliseconds msecs = 0ms ) = 0;
264  virtual qint64 WriteBlock ( const char *pData,
265  qint64 nLen ) = 0;
266  virtual QString GetHostName (); // RFC 3875 - The name in the client request
267  virtual QString GetHostAddress () = 0;
268  virtual quint16 GetHostPort () = 0;
269  virtual QString GetPeerAddress () = 0;
270  virtual int getSocketHandle () = 0;
271 };
272 
274 //
276 
278 {
279  public:
280 
281  QTcpSocket *m_pSocket {nullptr};
282 
283  public:
284 
285  explicit BufferedSocketDeviceRequest( QTcpSocket *pSocket )
286  : m_pSocket(pSocket) {}
287  ~BufferedSocketDeviceRequest() override = default;
288 
289  QString ReadLine ( std::chrono::milliseconds msecs ) override; // HTTPRequest
290  qint64 ReadBlock ( char *pData, qint64 nMaxLen, std::chrono::milliseconds msecs = 0ms ) override; // HTTPRequest
291  qint64 WriteBlock ( const char *pData, qint64 nLen ) override; // HTTPRequest
292  QString GetHostAddress () override; // HTTPRequest
293  quint16 GetHostPort () override; // HTTPRequest
294  QString GetPeerAddress () override; // HTTPRequest
295  int getSocketHandle () override // HTTPRequest
296  {return( m_pSocket->socketDescriptor() ); }
297 
298 };
299 
301 //
303 
305 {
306  public:
307  int m_code {-1};
308  QString m_msg;
309 
310  explicit HttpException( int nCode = -1, QString sMsg = "")
311  : m_code( nCode ), m_msg (std::move( sMsg ))
312  {}
313 
314  // Needed to force a v-table.
315  virtual ~HttpException() = default;
316 };
317 
319 {
320  public:
321 
322  QString m_hostName;
323  //int m_port;
324 
325  explicit HttpRedirectException( QString sHostName = "",
326  int nCode = -1,
327  const QString &sMsg = "" )
328  : HttpException( nCode, sMsg ), m_hostName(std::move( sHostName ))
329  {}
330 
331  ~HttpRedirectException() override = default;
332 
333 };
334 
335 #endif
BufferedSocketDeviceRequest::getSocketHandle
int getSocketHandle() override
Definition: httprequest.h:295
ContentType_XML
@ ContentType_XML
Definition: httprequest.h:69
HTTPRequest::m_sBaseUrl
QString m_sBaseUrl
Definition: httprequest.h:126
HttpException::m_msg
QString m_msg
Definition: httprequest.h:308
HTTPRequest
Definition: httprequest.h:108
ContentType_Unknown
@ ContentType_Unknown
Definition: httprequest.h:67
ContentType_Urlencoded
@ ContentType_Urlencoded
Definition: httprequest.h:68
HttpRedirectException::m_hostName
QString m_hostName
Definition: httprequest.h:322
ResponseTypeCSS
@ ResponseTypeCSS
Definition: httprequest.h:80
Serializer
Definition: serializer.h:31
HTTPRequest::SetKeepAliveTimeout
void SetKeepAliveTimeout(std::chrono::seconds nTimeout)
Definition: httprequest.h:256
BufferedSocketDeviceRequest::GetHostPort
quint16 GetHostPort() override
Definition: httprequest.cpp:2481
BufferedSocketDeviceRequest::GetPeerAddress
QString GetPeerAddress() override
Definition: httprequest.cpp:2491
HTTPRequest::m_sMethod
QString m_sMethod
Definition: httprequest.h:128
HTTPRequest::m_sResourceUrl
QString m_sResourceUrl
Definition: httprequest.h:127
BufferedSocketDeviceRequest::GetHostAddress
QString GetHostAddress() override
Definition: httprequest.cpp:2472
ResponseTypeUnknown
@ ResponseTypeUnknown
Definition: httprequest.h:76
HTTPRequest::IsEncrypted
bool IsEncrypted() const
Definition: httprequest.h:197
HTTPRequest::m_sProtocol
QString m_sProtocol
Definition: httprequest.h:136
HTTPRequest::m_sResponseTypeText
QString m_sResponseTypeText
Definition: httprequest.h:149
HTTPRequest::m_sOriginalUrl
QString m_sOriginalUrl
Definition: httprequest.h:124
HttpRedirectException::HttpRedirectException
HttpRedirectException(QString sHostName="", int nCode=-1, const QString &sMsg="")
Definition: httprequest.h:325
MIMETypes
Definition: httprequest.h:88
ResponseTypeJS
@ ResponseTypeJS
Definition: httprequest.h:79
ResponseTypeNone
@ ResponseTypeNone
Definition: httprequest.h:75
RequestTypePost
@ RequestTypePost
Definition: httprequest.h:49
RequestTypeOptions
@ RequestTypeOptions
Definition: httprequest.h:53
ContentType_JSON
@ ContentType_JSON
Definition: httprequest.h:70
RequestTypeResponse
@ RequestTypeResponse
Definition: httprequest.h:61
HTTPRequest::m_userSession
MythUserSession m_userSession
Definition: httprequest.h:161
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:160
ResponseTypeFile
@ ResponseTypeFile
Definition: httprequest.h:83
MythUserSession
Definition: mythsession.h:16
ResponseTypeHeader
@ ResponseTypeHeader
Definition: httprequest.h:85
HTTPRequest::m_mapRespHeaders
QStringMap m_mapRespHeaders
Definition: httprequest.h:152
NameValues
Definition: upnputil.h:89
hardwareprofile.smolt.secure
secure
Definition: smolt.py:95
HTTPRequest::s_szServerHeaders
static const char * s_szServerHeaders
Definition: httprequest.h:112
IPostProcess::~IPostProcess
virtual ~IPostProcess()=default
HttpContentType
HttpContentType
Definition: httprequest.h:65
RequestTypeMSearch
@ RequestTypeMSearch
Definition: httprequest.h:56
HTTPRequest::m_mapParams
QStringMap m_mapParams
Definition: httprequest.h:130
QStringMap
QMap< QString, QString > QStringMap
Definition: upnputil.h:44
RequestTypeHead
@ RequestTypeHead
Definition: httprequest.h:48
BufferedSocketDeviceRequest::ReadBlock
qint64 ReadBlock(char *pData, qint64 nMaxLen, std::chrono::milliseconds msecs=0ms) override
Definition: httprequest.cpp:2420
IPostProcess::ExecutePostProcess
virtual void ExecutePostProcess()=0
BufferedSocketDeviceRequest::BufferedSocketDeviceRequest
BufferedSocketDeviceRequest(QTcpSocket *pSocket)
Definition: httprequest.h:285
HTTPRequest::m_sRequestUrl
QString m_sRequestUrl
Definition: httprequest.h:125
HttpException
Definition: httprequest.h:304
ResponseTypeXML
@ ResponseTypeXML
Definition: httprequest.h:77
MIMETypes::pszType
const char * pszType
Definition: httprequest.h:91
serializer.h
HTTPRequest::HTTPRequest
HTTPRequest()
Definition: httprequest.h:209
HTTPRequest::m_sRawRequest
QString m_sRawRequest
Definition: httprequest.h:122
QStringMultiMap
QMultiMap< QString, QString > QStringMultiMap
Definition: upnputil.h:45
HTTPRequest::m_mapHeaders
QStringMultiMap m_mapHeaders
Definition: httprequest.h:131
ResponseTypeOther
@ ResponseTypeOther
Definition: httprequest.h:84
HTTPRequest::m_sFileName
QString m_sFileName
Definition: httprequest.h:154
IPostProcess
Definition: httprequest.h:97
ResponseTypeHTML
@ ResponseTypeHTML
Definition: httprequest.h:78
ResponseTypeText
@ ResponseTypeText
Definition: httprequest.h:81
RequestTypeNotify
@ RequestTypeNotify
Definition: httprequest.h:59
BufferedSocketDeviceRequest
Definition: httprequest.h:277
BufferedSocketDeviceRequest::WriteBlock
qint64 WriteBlock(const char *pData, qint64 nLen) override
Definition: httprequest.cpp:2455
std
Definition: mythchrono.h:23
HTTPRequest::IsProtected
bool IsProtected() const
Definition: httprequest.h:196
HttpRedirectException
Definition: httprequest.h:318
HttpResponseType
HttpResponseType
Definition: httprequest.h:73
HTTPRequest::m_sPayload
QString m_sPayload
Definition: httprequest.h:134
HTTPRequest::GetKeepAlive
bool GetKeepAlive() const
Definition: httprequest.h:236
UPNP_PUBLIC
#define UPNP_PUBLIC
Definition: upnpexp.h:9
BufferedSocketDeviceRequest::ReadLine
QString ReadLine(std::chrono::milliseconds msecs) override
Definition: httprequest.cpp:2388
HTTPRequest::m_sNameSpace
QString m_sNameSpace
Definition: httprequest.h:144
HttpException::HttpException
HttpException(int nCode=-1, QString sMsg="")
Definition: httprequest.h:310
RequestTypeUnknown
@ RequestTypeUnknown
Definition: httprequest.h:45
BufferedSocketDeviceRequest::m_pSocket
QTcpSocket * m_pSocket
Definition: httprequest.h:281
ResponseTypeSVG
@ ResponseTypeSVG
Definition: httprequest.h:82
RequestTypeGet
@ RequestTypeGet
Definition: httprequest.h:47
upnputil.h
MIMETypes::pszExtension
const char * pszExtension
Definition: httprequest.h:90
HTTPRequest::m_response
QBuffer m_response
Definition: httprequest.h:156
mythsession.h
HttpRequestType
HttpRequestType
Definition: httprequest.h:43
upnpexp.h
HTTPRequest::m_mapCookies
QStringMap m_mapCookies
Definition: httprequest.h:132