1 #ifndef	_NETWORKING_H_
2 #define	_NETWORKING_H_
3 
4 #include	<map>
5 #include	<vector>
6 #include	<curl/curl.h>
7 #include	<curl/easy.h>
8 #include	<curl/multi.h>
9 #include	<boost/thread.hpp>
10 
11 #include	"base.h"
12 #include	"SmartPtr.h"
13 #include	"Singleton.h"
14 
15 #ifdef LINUX_GNU
16 #undef Status
17 #endif
18 
19 namespace	Network
20 {
21 
22 /*
23 	CCurlTransfer.
24 	Baseclass for curl handled transfers.
25 */
26 class	CCurlTransfer
27 {
28 	friend class CManager;
29 
30 
31 	//	Identifier;
32 	std::string	m_Name;
33 	std::string m_Status;
34 	std::string m_AverageSpeed;
35 	long		m_HttpCode;
36     char errorBuffer[ CURL_ERROR_SIZE ];
37 
38 	//	Map of respons codes allowed. This is checkd on failed perform's.
39 	std::vector< uint32 > m_AllowedResponses;
40 
41 	protected:
42 		CURL		*m_pCurl;
43 		CURLM		*m_pCurlM;
44 
45 		bool	Verify( CURLcode _code );
46 		bool	VerifyM( CURLMcode _code );
Status(const std::string & _status)47 		void	Status( const std::string &_status )	{	m_Status = _status; };
48 
49 	public:
50 		CCurlTransfer( const std::string &_name );
51 		virtual ~CCurlTransfer();
52 
53 		static int32 customProgressCallback( void *_pUserData, fp8 _downTotal, fp8 _downNow, fp8 _upTotal, fp8 _upNow );
54 
55 		virtual bool	InterruptiblePerform();
56 
57 		virtual bool	Perform( const std::string &_url );
58 
59 		//	Add a response code to the list of allowed ones.
Allow(const uint32 _code)60 		void	Allow( const uint32 _code )				{	m_AllowedResponses.push_back( _code );	}
61 
Name()62 		const std::string	&Name() const				{	return m_Name;			};
Status()63 		const std::string	&Status() const				{	return m_Status;		};
ResponseCode()64 		long 			ResponseCode() const		{	return m_HttpCode;		};
SpeedString()65 		const std::string	SpeedString() const			{	return m_AverageSpeed;	};
66 };
67 
68 //
69 class	CFileDownloader : public CCurlTransfer
70 {
71 	std::string	m_Data;
72 
73 	public:
74 		static int32 customWrite( void *_pBuffer, size_t _size, size_t _nmemb, void *_pUserData );
75 
76 		CFileDownloader( const std::string &_name );
77 		virtual ~CFileDownloader();
78 
79 		virtual bool	Perform( const std::string &_url );
80 		bool	Save( const std::string &_output );
81 
Data()82 		const std::string &Data()								{ return m_Data;			};
83 };
84 
85 //
86 class	CFileDownloader_TimeCondition : public CFileDownloader
87 {
88 	public:
89 		CFileDownloader_TimeCondition( const std::string &_name );
90 		virtual ~CFileDownloader_TimeCondition();
91 
92 		bool	PerformDownloadWithTC( const std::string &_url, const time_t _lastTime );
93 };
94 
95 //
96 class	CFileUploader : public CCurlTransfer
97 {
98 	public:
99 		CFileUploader( const std::string &_name );
100 		virtual ~CFileUploader();
101 
102 		bool	PerformUpload( const std::string &_url, const std::string &_file, const uint32 _filesize );
103 };
104 
105 //	Def some smart pointers for these.
106 MakeSmartPointers( CCurlTransfer );
107 MakeSmartPointers( CFileDownloader );
108 MakeSmartPointers( CFileDownloader_TimeCondition );
109 MakeSmartPointers( CFileUploader );
110 
111 
112 /*
113 	CManager().
114 	The main manager.
115 */
116 MakeSmartPointers( CManager );
117 class	CManager : public Base::CSingleton<CManager>
118 {
119 	friend class Base::CSingleton<CManager>;
120 
121 	boost::mutex	m_Lock;
122 
123 	//	Private constructor accessible only to CSingleton.
124 	CManager();
125 
126 	//	No copy constructor or assignment operator.
127     NO_CLASS_STANDARDS( CManager );
128 
129 	//	To keep track of progress.
130 	std::map< std::string, std::string> m_ProgressMap;
131 
132 	//	User/password for http authentication.
133 	std::string	m_UserPass;
134 
135 	//	Proxy url and corresponding user/pass.
136 	std::string	m_ProxyUrl, m_ProxyUserPass;
137 
138 	bool			m_Aborted;
139 
140 	public:
141 			bool	Startup();
142 			bool	Shutdown();
~CManager()143 			virtual ~CManager()	{m_bSingletonActive = false;};
144 
Description()145 			const char *Description()	{	return "Network manager";	};
146 
147 			//	Called by CCurlTransfer destructors.
148 			void	Remove( CCurlTransfer *_pTransfer );
149 
150 			//	Session wide proxy settings & user/pass.
151 			void	Proxy( const std::string &_url, const std::string &_userName, const std::string &_password );
152 			void	Login( const std::string &_userName, const std::string &_password );
153 			void	Logout();
154 
155 			//	Called by CCurlTransfer prior to each Perform() call to handle proxy & authentication.
156 			CURLcode Prepare( CURL *_pCurl );
157 
158 			//	Used by the transfers to update progress.
159 			void	UpdateProgress( CCurlTransfer *_pTransfer, const fp8 _percentComplete, const fp8 _bytesTransferred );
160 
161 			// Used to abort any curl transfer
162 
163 			void	Abort( void );
164 			bool	IsAborted( void );
165 
166 			//	Fills in a vector of status strings for all active transfers.
167 			std::string Status();
168 
169 			//	Urlencode string.
170 			static std::string Encode( const std::string &_src );
171 
172 			//	Threadsafe.
Instance(const char *,const uint32,const char *)173 			static CManager *Instance( const char * /*_pFileStr*/, const uint32 /*_line*/, const char * /*_pFunc*/ )
174 			{
175 				//printf( "g_NetworkManager( %s(%d): %s )\n", _pFileStr, _line, _pFunc );
176 				//fflush( stdout );
177 
178 				static	CManager networkManager;
179 
180 				if( networkManager.SingletonActive() == false )
181 				{
182 					printf( "Trying to access shutdown singleton %s\n", networkManager.Description() );
183 				}
184 
185 				return( &networkManager );
186 			}
187 };
188 
189 };
190 
191 //	Helper for less typing...
192 #define	g_NetworkManager	Network::CManager::Instance( __FILE__, __LINE__, __FUNCTION__ )
193 
194 
195 #endif
196