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