00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00012
00013 #ifndef HTTPREQUEST_H_
00014 #define HTTPREQUEST_H_
00015
00016 #include <QFile>
00017 #include <QRegExp>
00018 #include <QBuffer>
00019 #include <QTextStream>
00020
00021 using namespace std;
00022
00023 #include "upnpexp.h"
00024 #include "upnputil.h"
00025 #include "bufferedsocketdevice.h"
00026 #include "serializers/serializer.h"
00027
00028 #define SOAP_ENVELOPE_BEGIN "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" " \
00029 "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" \
00030 "<s:Body>"
00031 #define SOAP_ENVELOPE_END "</s:Body>\r\n</s:Envelope>";
00032
00033
00035
00037
00038 typedef enum
00039 {
00040 RequestTypeUnknown = 0x0000,
00041 RequestTypeGet = 0x0001,
00042 RequestTypeHead = 0x0002,
00043 RequestTypePost = 0x0004,
00044 RequestTypeMSearch = 0x0008,
00045 RequestTypeSubscribe = 0x0010,
00046 RequestTypeUnsubscribe = 0x0020,
00047 RequestTypeNotify = 0x0040,
00048 RequestTypeResponse = 0x0080
00049
00050 } RequestType;
00051
00052 typedef enum
00053 {
00054 ContentType_Unknown = 0,
00055 ContentType_Urlencoded = 1,
00056 ContentType_XML = 2
00057
00058 } ContentType;
00059
00060 typedef enum
00061 {
00062 ResponseTypeNone = -1,
00063 ResponseTypeUnknown = 0,
00064 ResponseTypeXML = 1,
00065 ResponseTypeHTML = 2,
00066 ResponseTypeFile = 3,
00067 ResponseTypeOther = 4
00068
00069 } ResponseType;
00070
00071
00072 typedef struct
00073 {
00074 const char *pszExtension;
00075 const char *pszType;
00076
00077 } MIMETypes;
00078
00080
00081 class IPostProcess
00082 {
00083 public:
00084 virtual void ExecutePostProcess( ) = 0;
00085 virtual ~IPostProcess() {};
00086 };
00087
00089
00091
00092 class UPNP_PUBLIC HTTPRequest
00093 {
00094 protected:
00095
00096 static const char *m_szServerHeaders;
00097
00098 QRegExp m_procReqLineExp;
00099 QRegExp m_parseRangeExp;
00100
00101 public:
00102
00103 RequestType m_eType;
00104 ContentType m_eContentType;
00105
00106 QString m_sRawRequest;
00107
00108 QString m_sBaseUrl;
00109 QString m_sResourceUrl;
00110 QString m_sMethod;
00111
00112 QStringMap m_mapParams;
00113 QStringMap m_mapHeaders;
00114
00115 QString m_sPayload;
00116
00117 QString m_sProtocol;
00118 int m_nMajor;
00119 int m_nMinor;
00120
00121 bool m_bProtected;
00122
00123 bool m_bSOAPRequest;
00124 QString m_sNameSpace;
00125
00126
00127
00128 ResponseType m_eResponseType;
00129 QString m_sResponseTypeText;
00130
00131 long m_nResponseStatus;
00132 QStringMap m_mapRespHeaders;
00133
00134 QString m_sFileName;
00135
00136 QBuffer m_response;
00137
00138 IPostProcess *m_pPostProcess;
00139
00140 protected:
00141
00142 RequestType SetRequestType ( const QString &sType );
00143 void SetRequestProtocol ( const QString &sLine );
00144 ContentType SetContentType ( const QString &sType );
00145
00146 void SetServerHeaders ( void );
00147
00148 void ProcessRequestLine ( const QString &sLine );
00149 bool ProcessSOAPPayload ( const QString &sSOAPAction );
00150 void ExtractMethodFromURL( );
00151
00152 QString GetResponseStatus ( void );
00153 QString GetResponseType ( void );
00154 QString GetAdditionalHeaders( void );
00155
00156 bool ParseRange ( QString sRange,
00157 long long llSize,
00158 long long *pllStart,
00159 long long *pllEnd );
00160
00161 QString BuildHeader ( long long nSize );
00162
00163 qint64 SendData ( QIODevice *pDevice, qint64 llStart, qint64 llBytes );
00164 qint64 SendFile ( QFile &file, qint64 llStart, qint64 llBytes );
00165
00166 bool IsUrlProtected ( const QString &sBaseUrl );
00167 bool Authenticated ();
00168
00169 public:
00170
00171 HTTPRequest ();
00172 virtual ~HTTPRequest () {};
00173
00174 bool ParseRequest ();
00175
00176 void FormatErrorResponse ( bool bServerError,
00177 const QString &sFaultString,
00178 const QString &sDetails );
00179
00180 void FormatActionResponse( Serializer *ser );
00181 void FormatActionResponse( const NameValues &pArgs );
00182 void FormatFileResponse ( const QString &sFileName );
00183 void FormatRawResponse ( const QString &sXML );
00184
00185 long SendResponse ( void );
00186 long SendResponseFile( QString sFileName );
00187
00188 QString GetHeaderValue ( const QString &sKey, QString sDefault );
00189
00190 bool GetKeepAlive ();
00191
00192 Serializer * GetSerializer ();
00193
00194 static QString GetMimeType ( const QString &sFileExtension );
00195 static QString TestMimeType ( const QString &sFileName );
00196 static long GetParameters ( QString sParams, QStringMap &mapParams );
00197 static QString Encode ( const QString &sIn );
00198 static QString GetETagHash ( const QByteArray &data );
00199
00200
00201
00202 virtual qlonglong BytesAvailable () = 0;
00203 virtual qulonglong WaitForMore ( int msecs, bool *timeout = NULL ) = 0;
00204 virtual bool CanReadLine () = 0;
00205 virtual QString ReadLine ( int msecs = 0 ) = 0;
00206 virtual qlonglong ReadBlock ( char *pData, qulonglong nMaxLen, int msecs = 0 ) = 0;
00207 virtual qlonglong WriteBlock ( const char *pData,
00208 qulonglong nLen ) = 0;
00209 virtual qlonglong WriteBlockDirect( const char *pData,
00210 qulonglong nLen ) = 0;
00211 virtual QString GetHostAddress () = 0;
00212 virtual QString GetPeerAddress () = 0;
00213 virtual void Flush () = 0;
00214 virtual bool IsValid () = 0;
00215 virtual int getSocketHandle () = 0;
00216 virtual void SetBlocking ( bool bBlock ) = 0;
00217 virtual bool IsBlocking () = 0;
00218 };
00219
00221
00223
00224 class BufferedSocketDeviceRequest : public HTTPRequest
00225 {
00226 public:
00227
00228 BufferedSocketDevice *m_pSocket;
00229
00230 public:
00231
00232 BufferedSocketDeviceRequest( BufferedSocketDevice *pSocket );
00233 virtual ~BufferedSocketDeviceRequest() {};
00234
00235 virtual qlonglong BytesAvailable ();
00236 virtual qulonglong WaitForMore ( int msecs, bool *timeout = NULL );
00237 virtual bool CanReadLine ();
00238 virtual QString ReadLine ( int msecs = 0 );
00239 virtual qlonglong ReadBlock ( char *pData, qulonglong nMaxLen, int msecs = 0 );
00240 virtual qlonglong WriteBlock ( const char *pData, qulonglong nLen );
00241 virtual qlonglong WriteBlockDirect( const char *pData, qulonglong nLen );
00242 virtual QString GetHostAddress ();
00243 virtual QString GetPeerAddress ();
00244 virtual void Flush () { m_pSocket->Flush(); }
00245 virtual bool IsValid () {return( m_pSocket->IsValid() ); }
00246 virtual int getSocketHandle () {return( m_pSocket->socket() ); }
00247 virtual void SetBlocking ( bool bBlock );
00248 virtual bool IsBlocking ();
00249
00250 };
00251
00253
00255
00256 class UPNP_PUBLIC HttpException
00257 {
00258 public:
00259 int code;
00260 QString msg;
00261
00262 HttpException( int nCode = -1, const QString &sMsg = "")
00263 : code( nCode ), msg ( sMsg )
00264 {}
00265
00266
00267 virtual ~HttpException()
00268 {}
00269 };
00270
00271 class UPNP_PUBLIC HttpRedirectException : public HttpException
00272 {
00273 public:
00274
00275 QString hostName;
00276
00277
00278 HttpRedirectException( const QString &sHostName = "",
00279 int nCode = -1,
00280 const QString &sMsg = "" )
00281 : HttpException( nCode, sMsg ), hostName( sHostName )
00282 {}
00283
00284 virtual ~HttpRedirectException()
00285 {}
00286
00287 };
00288
00289 #endif