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