1 /* --------------------------------------------------------------------------
2 
3    libmusicbrainz5 - Client library to access MusicBrainz
4 
5    Copyright (C) 2012 Andrew Hawkins
6 
7    This file is part of libmusicbrainz5.
8 
9    This library is free software; you can redistribute it and/or
10    modify it under the terms of the GNU Lesser General Public
11    License as published by the Free Software Foundation; either
12    version 2.1 of the License, or (at your option) any later version.
13 
14    libmusicbrainz5 is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17    Lesser General Public License for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this library.  If not, see <http://www.gnu.org/licenses/>.
21 
22      $Id$
23 
24 ----------------------------------------------------------------------------*/
25 
26 #ifndef _MUSICBRAINZ5_HTTP_FETCH_
27 #define _MUSICBRAINZ5_HTTP_FETCH_
28 
29 #include <string>
30 #include <vector>
31 
32 // Visibility patch derived from https://gcc.gnu.org/wiki/Visibility ,
33 // extended for clang support.
34 #if (__clang__) || (__GNUC__ >= 4)
35 	#define DLL_PUBLIC __attribute__ ((visibility ("default")))
36 	#define DLL_LOCAL  __attribute__ ((visibility ("hidden")))
37 #else
38 	#define DLL_PUBLIC
39 	#define DLL_LOCAL
40 #endif
41 
42 
43 
44 namespace MusicBrainz5
45 {
46 	class CHTTPFetchPrivate;
47 
48 	class DLL_PUBLIC CExceptionBase: public std::exception
49 	{
50 	public:
CExceptionBase(const std::string & ErrorMessage,const std::string & Exception)51 		CExceptionBase(const std::string& ErrorMessage, const std::string& Exception)
52 		:	m_ErrorMessage(ErrorMessage),
53 			m_Exception(Exception)
54 		{
55 			m_FullMessage=m_Exception + ": " + m_ErrorMessage;
56 		}
57 
~CExceptionBase()58 		virtual ~CExceptionBase() throw() {};
59 
what()60 	  virtual const char* what() const throw()
61 	  {
62 	    return m_FullMessage.c_str();
63 	  }
64 
65 	 private:
66 		std::string m_ErrorMessage;
67 		std::string m_Exception;
68 		std::string m_FullMessage;
69 	};
70 
71 	/**
72 	 * Exception thrown when an error occurs connecting to web service
73 	 */
74 
75 	class DLL_PUBLIC CConnectionError: public CExceptionBase
76 	{
77 	public:
CConnectionError(const std::string & ErrorMessage)78 			CConnectionError(const std::string& ErrorMessage)
79 			: CExceptionBase(ErrorMessage,"Connection error")
80 			{
81 			}
82 	};
83 
84 	/**
85 	 * Exception thrown when a connection to the web service times out
86 	 */
87 
88 	class DLL_PUBLIC CTimeoutError: public CExceptionBase
89 	{
90 	public:
CTimeoutError(const std::string & ErrorMessage)91 			CTimeoutError(const std::string& ErrorMessage)
92 			: CExceptionBase(ErrorMessage,"Timeout error")
93 			{
94 			}
95 	};
96 
97 	/**
98 	 * Exception thrown when an authentication error occurs
99 	 */
100 
101 	class DLL_PUBLIC CAuthenticationError: public CExceptionBase
102 	{
103 	public:
CAuthenticationError(const std::string & ErrorMessage)104 			CAuthenticationError(const std::string& ErrorMessage)
105 			: CExceptionBase(ErrorMessage,"Authentication error")
106 			{
107 			}
108 	};
109 
110 	/**
111 	 * Exception thrown when an error occurs fetching data
112 	 */
113 
114 	class DLL_PUBLIC CFetchError: public CExceptionBase
115 	{
116 	public:
CFetchError(const std::string & ErrorMessage)117 			CFetchError(const std::string& ErrorMessage)
118 			: CExceptionBase(ErrorMessage,"Fetch error")
119 			{
120 			}
121 	};
122 
123 	/**
124 	 * Exception thrown when an invalid request is made
125 	 */
126 
127 	class DLL_PUBLIC CRequestError: public CExceptionBase
128 	{
129 	public:
CRequestError(const std::string & ErrorMessage)130 			CRequestError(const std::string& ErrorMessage)
131 			: CExceptionBase(ErrorMessage,"Request error")
132 			{
133 			}
134 	};
135 
136 	/**
137 	 * Exception thrown when the requested resource is not found
138 	 */
139 
140 	class DLL_PUBLIC CResourceNotFoundError: public CExceptionBase
141 	{
142 	public:
CResourceNotFoundError(const std::string & ErrorMessage)143 			CResourceNotFoundError(const std::string& ErrorMessage)
144 			: CExceptionBase(ErrorMessage,"Resource not found error")
145 			{
146 			}
147 	};
148 
149 	/**
150 	 * @brief Object for make HTTP requests
151 	 *
152 	 * Object to be used to make HTTP requests
153 	 *
154 	 */
155 	class CHTTPFetch
156 	{
157 	public:
158 		/**
159 		 * @brief Constructor
160 		 *
161 		 * Constructor
162 		 *
163 		 * @param UserAgent User agent string to send
164 		 * @param Host Host name to connect to
165 		 * @param Port Port to connect to (80 by default)
166 		 */
167 
168 
169 		CHTTPFetch(const std::string& UserAgent, const std::string& Host, int Port=80);
170 		~CHTTPFetch();
171 
172 		/**
173 		 * @brief Set the user name to use
174 		 *
175 		 * Set the user name to use when authenticating with the web server
176 		 *
177 		 * @param UserName User name to use
178 		 */
179 
180 		void SetUserName(const std::string& UserName);
181 
182 		/**
183 		 * @brief Set the password to use
184 		 *
185 		 * Set the password to use when authenticating with the web server
186 		 *
187 		 * @param Password Password to use
188 		 */
189 
190 		void SetPassword(const std::string& Password);
191 
192 		/**
193 		 * @brief Set the proxy server to use
194 		 *
195 		 * Set the proxy server to use when connecting with the web server
196 		 *
197 		 * @param ProxyHost Proxy server to use
198 		 */
199 
200 		void SetProxyHost(const std::string& ProxyHost);
201 
202 		/**
203 		 * @brief Set the proxy port to use
204 		 *
205 		 * Set the proxy server port to use when connecting to the web server
206 		 *
207 		 * @param ProxyPort Proxy server port to use
208 		 */
209 
210 		void SetProxyPort(int ProxyPort);
211 
212 		/**
213 		 * @brief Set the proxy user name to use
214 		 *
215 		 * Set the user name to use when authenticating with the proxy server
216 		 *
217 		 * @param ProxyUserName Proxy user name to use
218 		 */
219 
220 		void SetProxyUserName(const std::string& ProxyUserName);
221 
222 		/**
223 		 * @brief Set the proxy password to use
224 		 *
225 		 * Set the password to use when authenticating with the proxy server
226 		 *
227 		 * @param ProxyPassword Proxy server password to use
228 		 */
229 
230 		void SetProxyPassword(const std::string& ProxyPassword);
231 
232 		/**
233 		 * @brief Make a request to the server
234 		 *
235 		 * Make a request to the server
236 		 *
237 		 * @param URL URL to request
238 		 * @param Request Request type (GET by default)
239 		 *
240 		 * @return Number of bytes received
241 		 *
242 		 * @throw CConnectionError An error occurred connecting to the web server
243 		 * @throw CTimeoutError A timeout occurred when connecting to the web server
244 		 * @throw CAuthenticationError An authentication error occurred
245 		 * @throw CFetchError An error occurred fetching data
246 		 * @throw CRequestError The request was invalid
247 		 * @throw CResourceNotFoundError The requested resource was not found
248 		 */
249 
250 		int Fetch(const std::string& URL, const std::string& Request="GET");
251 
252 		/**
253 		 * @brief Get the data receieved
254 		 *
255 		 * Get the data received from the request
256 		 *
257 		 * @return Data received
258 		 */
259 
260 		std::vector<unsigned char> Data() const;
261 
262 		/**
263 		 * @brief libneon result code from the request
264 		 *
265 		 * Return the result code from the request
266 		 *
267 		 * @return libneon result code from the request
268 		 */
269 
270 		int Result() const;
271 
272 		/**
273 		 * @brief Status
274 		 *
275 		 * Return the HTTP status code from the request
276 		 *
277 		 * @return HTTP status code from the request
278 		 */
279 
280 		int Status() const;
281 
282 		/**
283 		 * @brief Return the error message from the request
284 		 *
285 		 * Return the error message from the request
286 		 *
287 		 * @return Error message from the request
288 		 */
289 
290 		std::string ErrorMessage() const;
291 
292 	private:
293 		CHTTPFetchPrivate * const m_d;
294 
295 		static int httpAuth(void *userdata, const char *realm, int attempts, char *username, char *password);
296 		static int proxyAuth(void *userdata, const char *realm, int attempts, char *username, char *password);
297 		static int httpResponseReader(void *userdata, const char *buf, size_t len);
298 	};
299 }
300 
301 #endif
302