1
/* --------------------------------------------------------------------------
3
libmusicbrainz4 - Client library to access MusicBrainz
5
Copyright (C) 2011 Andrew Hawkins
7
This file is part of libmusicbrainz4.
9
This library is free software; you can redistribute it and/or
10
modify it under the terms of v2 of the GNU Lesser General Public
11
License as published by the Free Software Foundation.
13
libmusicbrainz4 is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
Lesser General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with this library. If not, see <http://www.gnu.org/licenses/>.
21
$Id: HTTPFetch.cc 13259 2011-08-10 12:02:50Z adhawkins $
23
----------------------------------------------------------------------------*/
25
#include "musicbrainz4/HTTPFetch.h"
30
#include "ne_session.h"
32
#include "ne_string.h"
33
#include "ne_request.h"
35
class MusicBrainz4::CHTTPFetchPrivate
46
std::string m_UserAgent;
49
std::vector<unsigned char> m_Data;
52
std::string m_ErrorMessage;
53
std::string m_UserName;
54
std::string m_Password;
55
std::string m_ProxyHost;
57
std::string m_ProxyUserName;
58
std::string m_ProxyPassword;
61
MusicBrainz4::CHTTPFetch::CHTTPFetch(const std::string& UserAgent, const std::string& Host, int Port)
62
: m_d(new CHTTPFetchPrivate)
64
m_d->m_UserAgent=UserAgent;
66
for (std::string::size_type Pos=0;Pos<m_d->m_UserAgent.length();Pos++)
67
if (m_d->m_UserAgent[Pos]=='-')
68
m_d->m_UserAgent[Pos]='/';
73
// Parse http_proxy environmnent variable
74
const char *http_proxy = getenv("http_proxy");
78
if (!ne_uri_parse(http_proxy, &uri))
81
m_d->m_ProxyHost = uri.host;
83
m_d->m_ProxyPort = uri.port;
87
char *pos = strchr(uri.userinfo, ':');
91
m_d->m_ProxyUserName = uri.userinfo;
92
m_d->m_ProxyPassword = pos + 1;
96
m_d->m_ProxyUserName = uri.userinfo;
105
MusicBrainz4::CHTTPFetch::~CHTTPFetch()
110
void MusicBrainz4::CHTTPFetch::SetUserName(const std::string& UserName)
112
m_d->m_UserName=UserName;
115
void MusicBrainz4::CHTTPFetch::SetPassword(const std::string& Password)
117
m_d->m_Password=Password;
120
void MusicBrainz4::CHTTPFetch::SetProxyHost(const std::string& ProxyHost)
122
m_d->m_ProxyHost=ProxyHost;
125
void MusicBrainz4::CHTTPFetch::SetProxyPort(int ProxyPort)
127
m_d->m_ProxyPort=ProxyPort;
130
void MusicBrainz4::CHTTPFetch::SetProxyUserName(const std::string& ProxyUserName)
132
m_d->m_ProxyUserName=ProxyUserName;
135
void MusicBrainz4::CHTTPFetch::SetProxyPassword(const std::string& ProxyPassword)
137
m_d->m_ProxyPassword=ProxyPassword;
140
int MusicBrainz4::CHTTPFetch::Fetch(const std::string& URL, const std::string& Request)
148
ne_session *sess=ne_session_create("http", m_d->m_Host.c_str(), m_d->m_Port);
151
ne_set_useragent(sess, m_d->m_UserAgent.c_str());
153
ne_set_server_auth(sess, httpAuth, this);
156
if (!m_d->m_ProxyHost.empty())
158
ne_session_proxy(sess, m_d->m_ProxyHost.c_str(), m_d->m_ProxyPort);
159
ne_set_proxy_auth(sess, proxyAuth, this);
162
ne_request *req = ne_request_create(sess, Request.c_str(), URL.c_str());
164
ne_set_request_body_buffer(req,0,0);
167
ne_set_request_flag(req, NE_REQFLAG_IDEMPOTENT, 0);
169
ne_add_response_body_reader(req, ne_accept_2xx, httpResponseReader, &m_d->m_Data);
171
m_d->m_Result = ne_request_dispatch(req);
172
m_d->m_Status = ne_get_status(req)->code;
174
Ret=m_d->m_Data.size();
176
ne_request_destroy(req);
178
m_d->m_ErrorMessage = ne_get_error(sess);
180
ne_session_destroy(sess);
182
switch (m_d->m_Result)
189
throw CConnectionError(m_d->m_ErrorMessage);
193
throw CTimeoutError(m_d->m_ErrorMessage);
198
throw CAuthenticationError(m_d->m_ErrorMessage);
202
throw CFetchError(m_d->m_ErrorMessage);
206
switch (m_d->m_Status)
212
throw CRequestError(m_d->m_ErrorMessage);
216
throw CAuthenticationError(m_d->m_ErrorMessage);
220
throw CResourceNotFoundError(m_d->m_ErrorMessage);
224
throw CFetchError(m_d->m_ErrorMessage);
234
int MusicBrainz4::CHTTPFetch::httpAuth(void *userdata, const char *realm, int attempts,
235
char *username, char *password)
239
MusicBrainz4::CHTTPFetch *Fetch = (MusicBrainz4::CHTTPFetch *)userdata;
240
strncpy(username, Fetch->m_d->m_UserName.c_str(), NE_ABUFSIZ);
241
strncpy(password, Fetch->m_d->m_Password.c_str(), NE_ABUFSIZ);
245
int MusicBrainz4::CHTTPFetch::proxyAuth(void *userdata, const char *realm, int attempts,
246
char *username, char *password)
250
MusicBrainz4::CHTTPFetch *Fetch = (MusicBrainz4::CHTTPFetch *)userdata;
251
strncpy(username, Fetch->m_d->m_ProxyUserName.c_str(), NE_ABUFSIZ);
252
strncpy(password, Fetch->m_d->m_ProxyPassword.c_str(), NE_ABUFSIZ);
256
int MusicBrainz4::CHTTPFetch::httpResponseReader(void *userdata, const char *buf, size_t len)
258
std::vector<unsigned char> *buffer = reinterpret_cast<std::vector<unsigned char> *>(userdata);
260
buffer->insert(buffer->end(),buf,buf+len);
265
std::vector<unsigned char> MusicBrainz4::CHTTPFetch::Data() const
270
int MusicBrainz4::CHTTPFetch::Result() const
272
return m_d->m_Result;
275
int MusicBrainz4::CHTTPFetch::Status() const
277
return m_d->m_Status;
280
std::string MusicBrainz4::CHTTPFetch::ErrorMessage() const
282
return m_d->m_ErrorMessage;