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