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 <QRegExp>
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
62 
63 };
64 
66 {
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  QRegExp m_procReqLineExp {"[ \r\n][ \r\n]*"};
114  QRegExp 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 );
178  QString GetResponseType ( void );
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);
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, QString sDefault );
234 
235  bool GetKeepAlive () { 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 
246  static QString GetMimeType ( const QString &sFileExtension );
247  static QStringList GetSupportedMimeTypes ();
248  static QString TestMimeType ( const QString &sFileName );
249  static long GetParameters ( QString sParams, QStringMap &mapParams );
250  static QString Encode ( const QString &sIn );
251  static QString Decode ( const QString &sIn );
252  static QString GetETagHash ( const QByteArray &data );
253 
254  void SetKeepAliveTimeout ( int nTimeout ) { m_nKeepAliveTimeout = nTimeout; }
255 
256  static bool IsUrlProtected ( const QString &sBaseUrl );
257 
258  // ------------------------------------------------------------------
259 
260  virtual QString ReadLine ( int msecs ) = 0;
261  virtual qint64 ReadBlock ( char *pData, qint64 nMaxLen, int msecs = 0 ) = 0;
262  virtual qint64 WriteBlock ( const char *pData,
263  qint64 nLen ) = 0;
264  virtual QString GetHostName (); // RFC 3875 - The name in the client request
265  virtual QString GetHostAddress () = 0;
266  virtual quint16 GetHostPort () = 0;
267  virtual QString GetPeerAddress () = 0;
268  virtual int getSocketHandle () = 0;
269 };
270 
272 //
274 
276 {
277  public:
278 
279  QTcpSocket *m_pSocket {nullptr};
280 
281  public:
282 
283  explicit BufferedSocketDeviceRequest( QTcpSocket *pSocket )
284  : m_pSocket(pSocket) {}
285  ~BufferedSocketDeviceRequest() override = default;
286 
287  QString ReadLine ( int msecs ) override; // HTTPRequest
288  qint64 ReadBlock ( char *pData, qint64 nMaxLen, int msecs = 0 ) override; // HTTPRequest
289  qint64 WriteBlock ( const char *pData, qint64 nLen ) override; // HTTPRequest
290  QString GetHostAddress () override; // HTTPRequest
291  quint16 GetHostPort () override; // HTTPRequest
292  QString GetPeerAddress () override; // HTTPRequest
293  int getSocketHandle () override // HTTPRequest
294  {return( m_pSocket->socketDescriptor() ); }
295 
296 };
297 
299 //
301 
303 {
304  public:
305  int m_code {-1};
306  QString m_msg;
307 
308  explicit HttpException( int nCode = -1, QString sMsg = "")
309  : m_code( nCode ), m_msg (std::move( sMsg ))
310  {}
311 
312  // Needed to force a v-table.
313  virtual ~HttpException() = default;
314 };
315 
317 {
318  public:
319 
320  QString m_hostName;
321  //int m_port;
322 
323  explicit HttpRedirectException( QString sHostName = "",
324  int nCode = -1,
325  const QString &sMsg = "" )
326  : HttpException( nCode, sMsg ), m_hostName(std::move( sHostName ))
327  {}
328 
329  ~HttpRedirectException() override = default;
330 
331 };
332 
333 #endif
HttpRequestType
Definition: httprequest.h:43
QMap< QString, QString > QStringMap
Definition: upnputil.h:44
QString m_sOriginalUrl
Definition: httprequest.h:123
QString m_sBaseUrl
Definition: httprequest.h:125
MythUserSession m_userSession
Definition: httprequest.h:160
QString m_sPrivateToken
Definition: httprequest.h:159
QString m_sMethod
Definition: httprequest.h:127
QStringMap m_mapRespHeaders
Definition: httprequest.h:151
HttpContentType
Definition: httprequest.h:65
QString m_sResponseTypeText
Definition: httprequest.h:148
qint64 WriteBlock(const char *pData, qint64 nLen) override
QString m_sResourceUrl
Definition: httprequest.h:126
bool IsEncrypted() const
Definition: httprequest.h:196
QString m_sProtocol
Definition: httprequest.h:135
static const char * s_szServerHeaders
Definition: httprequest.h:111
void SetKeepAliveTimeout(int nTimeout)
Definition: httprequest.h:254
~BufferedSocketDeviceRequest() override=default
QString m_sRawRequest
Definition: httprequest.h:121
bool GetKeepAlive()
Definition: httprequest.h:235
BufferedSocketDeviceRequest(QTcpSocket *pSocket)
Definition: httprequest.h:283
QString m_msg
Definition: httprequest.h:306
QString GetHostAddress() override
unsigned int uint
Definition: compat.h:140
QString m_sFileName
Definition: httprequest.h:153
HttpRedirectException(QString sHostName="", int nCode=-1, const QString &sMsg="")
Definition: httprequest.h:323
HttpResponseType
Definition: httprequest.h:72
QString m_sRequestUrl
Definition: httprequest.h:124
QString GetPeerAddress() override
QStringMap m_mapParams
Definition: httprequest.h:129
bool IsProtected() const
Definition: httprequest.h:195
int getSocketHandle() override
Definition: httprequest.h:293
const char * pszExtension
Definition: httprequest.h:89
#define UPNP_PUBLIC
Definition: upnpexp.h:9
HttpException(int nCode=-1, QString sMsg="")
Definition: httprequest.h:308
const char * pszType
Definition: httprequest.h:90
virtual void ExecutePostProcess()=0
QBuffer m_response
Definition: httprequest.h:155
QString m_sPayload
Definition: httprequest.h:133
virtual ~IPostProcess()=default
QStringMap m_mapCookies
Definition: httprequest.h:131
QStringMap m_mapHeaders
Definition: httprequest.h:130
QString m_sNameSpace
Definition: httprequest.h:143
qint64 ReadBlock(char *pData, qint64 nMaxLen, int msecs=0) override
QString ReadLine(int msecs) override
quint16 GetHostPort() override