1 /////////////////////////////////////////
2 //
3 //   OpenLieroX
4 //
5 //   Auxiliary Software class library
6 //
7 //   based on the work of JasonB
8 //   enhanced by Dark Charlie and Albert Zeyer
9 //
10 //   code under LGPL
11 //
12 /////////////////////////////////////////
13 
14 
15 // HTTP class
16 // Created 9/4/02
17 // Jason Boettcher
18 
19 #ifndef __HTTP_H__
20 #define __HTTP_H__
21 
22 #include <string>
23 
24 #include "Networking.h"
25 #include "Event.h"
26 #include "SmartPointer.h"
27 #include "Mutex.h"
28 
29 #include "ThreadPool.h"
30 
31 typedef void CURL;
32 
33 //
34 // Functions
35 //
36 void AutoSetupHTTPProxy();
37 
38 //
39 // Classes
40 //
41 
42 // HTTP Post Field structure
43 class HTTPPostField  {
44 private:
45 	std::string sData;
46 	std::string sMimeType;
47 	std::string sName;
48 	std::string sFileName;
49 public:
HTTPPostField()50 	HTTPPostField() {}
HTTPPostField(const std::string & data,const std::string & mimetype,const std::string & name,const std::string & file)51 	HTTPPostField(const std::string& data, const std::string& mimetype, const std::string& name, const std::string& file) :
52 		sData(data), sMimeType(mimetype), sName(name), sFileName(file) {}
HTTPPostField(const HTTPPostField & oth)53 	HTTPPostField(const HTTPPostField& oth)  { operator= (oth); }
54 
55 
56 	HTTPPostField& operator= (const HTTPPostField& oth)  {
57 		if (&oth == this)
58 			return *this;
59 		sData = oth.sData;
60 		sMimeType = oth.sMimeType;
61 		sName = oth.sName;
62 		sFileName = oth.sFileName;
63 
64 		return *this;
65 	}
66 
setFileName(const std::string & n)67 	void setFileName(const std::string& n)	{ sFileName = n; }
getFileName()68 	const std::string& getFileName() const	{ return sFileName; }
69 
setName(const std::string & n)70 	void setName(const std::string& n)	{ sName = n; }
getName()71 	const std::string& getName() const	{ return sName; }
72 
setMimeType(const std::string & n)73 	void setMimeType(const std::string& n)	{ sMimeType = n; }
getMimeType()74 	const std::string& getMimeType() const	{ return sMimeType; }
75 
setData(const std::string & d)76 	void setData(const std::string& d)	{ sData = d; }
getData()77 	const std::string& getData() const	{ return sData; }
78 };
79 
80 // HTTP error struct
81 class HttpError  { public:
82 	std::string sErrorMsg;
83 	int			iError;
84 
85 	HttpError& operator=(const HttpError& oth)  {
86 		if (&oth != this)  {
87 			sErrorMsg = oth.sErrorMsg;
88 			iError = oth.iError;
89 		}
90 		return *this;
91 	}
92 };
93 
94 // HTTP errors
95 // NOTE: If you change this, change also error strings in HTTP.cpp!!
96 enum  {
97 	HTTP_NO_ERROR = 0,
98 	HTTP_NO_SOCKET_ERROR,
99 	HTTP_CANNOT_RESOLVE_DNS,
100 	HTTP_INVALID_URL,
101 	HTTP_DNS_TIMEOUT,
102 	HTTP_ERROR_SENDING_REQ,
103 	HTTP_NO_CONNECTION,
104 	HTTP_ERROR_TIMEOUT,
105 	HTTP_NET_ERROR,
106 	HTTP_BAD_RESPONSE,
107 	HTTP_FILE_NOT_FOUND = 404
108 	// HINT: Add more if you need them
109 };
110 
111 // HTTP processing results
112 enum HttpProc_t {
113 	HTTP_PROC_ERROR = -1,
114 	HTTP_PROC_PROCESSING = 0,
115 	HTTP_PROC_FINISHED = 1
116 };
117 
118 
119 
120 struct CurlThread;
121 
122 class CHttp {
123 public:
124 	enum Action  {
125 		htaGet = 0,
126 		htaHead,
127 		htaPost
128 	};
129 
130 	struct HttpEventData  {
HttpEventDataHttpEventData131 		HttpEventData(CHttp *h, bool succeeded) : cHttp(h), bSucceeded(succeeded) {}
132 		CHttp *cHttp;
133 		bool bSucceeded;
134 	};
135 
136 
137 	CHttp();
138 	~CHttp();
139 
140 	Event<HttpEventData>	onFinished;
141 
142 	//void				SendSimpleData(const std::string& data, const std::string url, const std::string& proxy = "");
143 	void				SendData(const std::list<HTTPPostField>& data, const std::string url, const std::string& proxy = "");
144 	void				RequestData(const std::string& url, const std::string& proxy = "");
ProcessRequest()145 	HttpProc_t			ProcessRequest()			{ Mutex::ScopedLock l(Lock); return ProcessingResult; };
146 	void				CancelProcessing();
ClearReceivedData()147 	void				ClearReceivedData()			{ Mutex::ScopedLock l(const_cast<Mutex &>(Lock)); Data = ""; }
GetError()148 	HttpError			GetError() const			{ Mutex::ScopedLock l(const_cast<Mutex &>(Lock)); return Error; }
GetData()149 	const std::string&	GetData() const				{ Mutex::ScopedLock l(const_cast<Mutex &>(Lock)); return curlThread != NULL ? Empty : Data; }
150 	std::string			GetMimeType() const;
151 	//const std::string&	GetDataToSend() const		{ Mutex::ScopedLock l(Lock); return DataToSend; }
152 	size_t				GetDataToSendLength() const;
153 	size_t				GetDataLength() const;
GetReceivedDataLen()154 	size_t				GetReceivedDataLen() const	{ Mutex::ScopedLock l(const_cast<Mutex &>(Lock)); return Data.size(); }
155 	size_t				GetSentDataLen() const;
RequestedData()156 	bool				RequestedData()	const		{ Mutex::ScopedLock l(const_cast<Mutex &>(Lock)); return curlThread != NULL; }
157 
GetDownloadTime()158 	TimeDiff			GetDownloadTime() const		{ Mutex::ScopedLock l(const_cast<Mutex &>(Lock)); return DownloadEnd - DownloadStart; }
159 
160 	float				GetDownloadSpeed() const;
161 	float				GetUploadSpeed() const;
162 
163 	std::string			GetHostName() const;
GetUrl()164 	const std::string&	GetUrl() const			{ return Url; }
IsRedirecting()165 	bool				IsRedirecting() const	{ return false; }
166 
167 
168 private:
169 	// they are not allowed atm
CHttp(const CHttp & oth)170 	CHttp(const CHttp& oth)  { operator= (oth); }
171 	CHttp& operator=(const CHttp& http);
172 
173 
174 	CURL *			InitializeTransfer(const std::string& url, const std::string& proxy);
175 
176 	// All string data passed to libcurl should be not freed until curl_easy_cleanup, that's fixed in libcurl 7.17.0 (Sep 2007)
177 	std::string		Url;
178 	std::string		Proxy;
179 	std::string		Useragent;
180 
181 	std::string		Data;  // Data received from the network
182 
183 	HttpProc_t		ProcessingResult;
184 	HttpError		Error;
185 
186 	std::string		Empty; // Returned when Data is being processed
187 
188 	friend struct CurlThread;
189 	CurlThread *	curlThread;
190 	Mutex			Lock;
191 
192 	// Bandwidth measurement
193 	AbsTime			DownloadStart;
194 	AbsTime			DownloadEnd;
195 
196 };
197 
198 #endif  // __HTTP_H__
199