~ubuntu-branches/ubuntu/precise/libmusicbrainz/precise-updates

« back to all changes in this revision

Viewing changes to src/HTTPFetch.cc

  • Committer: Package Import Robot
  • Author(s): Timo Aaltonen
  • Date: 2012-02-01 17:18:10 UTC
  • Revision ID: package-import@ubuntu.com-20120201171810-jzz90w51dx6shdr1
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* --------------------------------------------------------------------------
 
2
 
 
3
   libmusicbrainz4 - Client library to access MusicBrainz
 
4
 
 
5
   Copyright (C) 2011 Andrew Hawkins
 
6
 
 
7
   This file is part of libmusicbrainz4.
 
8
 
 
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.
 
12
 
 
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.
 
17
 
 
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/>.
 
20
 
 
21
     $Id: HTTPFetch.cc 13259 2011-08-10 12:02:50Z adhawkins $
 
22
 
 
23
----------------------------------------------------------------------------*/
 
24
 
 
25
#include "musicbrainz4/HTTPFetch.h"
 
26
 
 
27
#include <stdlib.h>
 
28
#include <string.h>
 
29
 
 
30
#include "ne_session.h"
 
31
#include "ne_auth.h"
 
32
#include "ne_string.h"
 
33
#include "ne_request.h"
 
34
 
 
35
class MusicBrainz4::CHTTPFetchPrivate
 
36
{
 
37
        public:
 
38
                CHTTPFetchPrivate()
 
39
                :       m_Port(80),
 
40
                        m_Result(0),
 
41
                        m_Status(0),
 
42
                        m_ProxyPort(0)
 
43
                {
 
44
                }
 
45
 
 
46
                std::string m_UserAgent;
 
47
                std::string m_Host;
 
48
                int m_Port;
 
49
                std::vector<unsigned char> m_Data;
 
50
                int m_Result;
 
51
                int m_Status;
 
52
                std::string m_ErrorMessage;
 
53
                std::string m_UserName;
 
54
                std::string m_Password;
 
55
                std::string m_ProxyHost;
 
56
                int m_ProxyPort;
 
57
                std::string m_ProxyUserName;
 
58
                std::string m_ProxyPassword;
 
59
};
 
60
 
 
61
MusicBrainz4::CHTTPFetch::CHTTPFetch(const std::string& UserAgent, const std::string& Host, int Port)
 
62
:       m_d(new CHTTPFetchPrivate)
 
63
{
 
64
        m_d->m_UserAgent=UserAgent;
 
65
 
 
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]='/';
 
69
 
 
70
        m_d->m_Host=Host;
 
71
        m_d->m_Port=Port;
 
72
 
 
73
        // Parse http_proxy environmnent variable
 
74
        const char *http_proxy = getenv("http_proxy");
 
75
        if (http_proxy)
 
76
        {
 
77
                ne_uri uri;
 
78
                if (!ne_uri_parse(http_proxy, &uri))
 
79
                {
 
80
                        if (uri.host)
 
81
                                m_d->m_ProxyHost = uri.host;
 
82
                        if (uri.port)
 
83
                                m_d->m_ProxyPort = uri.port;
 
84
 
 
85
                        if (uri.userinfo)
 
86
                        {
 
87
                                char *pos = strchr(uri.userinfo, ':');
 
88
                                if (pos)
 
89
                                {
 
90
                                        *pos = '\0';
 
91
                                        m_d->m_ProxyUserName = uri.userinfo;
 
92
                                        m_d->m_ProxyPassword = pos + 1;
 
93
                                }
 
94
                                else
 
95
                                {
 
96
                                        m_d->m_ProxyUserName = uri.userinfo;
 
97
                                }
 
98
                        }
 
99
                }
 
100
 
 
101
                ne_uri_free(&uri);
 
102
        }
 
103
}
 
104
 
 
105
MusicBrainz4::CHTTPFetch::~CHTTPFetch()
 
106
{
 
107
        delete m_d;
 
108
}
 
109
 
 
110
void MusicBrainz4::CHTTPFetch::SetUserName(const std::string& UserName)
 
111
{
 
112
        m_d->m_UserName=UserName;
 
113
}
 
114
 
 
115
void MusicBrainz4::CHTTPFetch::SetPassword(const std::string& Password)
 
116
{
 
117
        m_d->m_Password=Password;
 
118
}
 
119
 
 
120
void MusicBrainz4::CHTTPFetch::SetProxyHost(const std::string& ProxyHost)
 
121
{
 
122
        m_d->m_ProxyHost=ProxyHost;
 
123
}
 
124
 
 
125
void MusicBrainz4::CHTTPFetch::SetProxyPort(int ProxyPort)
 
126
{
 
127
        m_d->m_ProxyPort=ProxyPort;
 
128
}
 
129
 
 
130
void MusicBrainz4::CHTTPFetch::SetProxyUserName(const std::string& ProxyUserName)
 
131
{
 
132
        m_d->m_ProxyUserName=ProxyUserName;
 
133
}
 
134
 
 
135
void MusicBrainz4::CHTTPFetch::SetProxyPassword(const std::string& ProxyPassword)
 
136
{
 
137
        m_d->m_ProxyPassword=ProxyPassword;
 
138
}
 
139
 
 
140
int MusicBrainz4::CHTTPFetch::Fetch(const std::string& URL, const std::string& Request)
 
141
{
 
142
        int Ret=0;
 
143
 
 
144
        m_d->m_Data.clear();
 
145
 
 
146
        ne_sock_init();
 
147
 
 
148
        ne_session *sess=ne_session_create("http", m_d->m_Host.c_str(), m_d->m_Port);
 
149
        if (sess)
 
150
        {
 
151
                ne_set_useragent(sess, m_d->m_UserAgent.c_str());
 
152
 
 
153
                ne_set_server_auth(sess, httpAuth, this);
 
154
 
 
155
                // Use proxy server
 
156
                if (!m_d->m_ProxyHost.empty())
 
157
                {
 
158
                        ne_session_proxy(sess, m_d->m_ProxyHost.c_str(), m_d->m_ProxyPort);
 
159
                        ne_set_proxy_auth(sess, proxyAuth, this);
 
160
                }
 
161
 
 
162
                ne_request *req = ne_request_create(sess, Request.c_str(), URL.c_str());
 
163
                if (Request=="PUT")
 
164
                        ne_set_request_body_buffer(req,0,0);
 
165
 
 
166
                if (Request!="GET")
 
167
                        ne_set_request_flag(req, NE_REQFLAG_IDEMPOTENT, 0);
 
168
 
 
169
                ne_add_response_body_reader(req, ne_accept_2xx, httpResponseReader, &m_d->m_Data);
 
170
 
 
171
                m_d->m_Result = ne_request_dispatch(req);
 
172
                m_d->m_Status = ne_get_status(req)->code;
 
173
 
 
174
                Ret=m_d->m_Data.size();
 
175
 
 
176
                ne_request_destroy(req);
 
177
 
 
178
                m_d->m_ErrorMessage = ne_get_error(sess);
 
179
 
 
180
                ne_session_destroy(sess);
 
181
 
 
182
                switch (m_d->m_Result)
 
183
                {
 
184
                        case NE_OK:
 
185
                                break;
 
186
 
 
187
                        case NE_CONNECT:
 
188
                        case NE_LOOKUP:
 
189
                                throw CConnectionError(m_d->m_ErrorMessage);
 
190
                                break;
 
191
 
 
192
                        case NE_TIMEOUT:
 
193
                                throw CTimeoutError(m_d->m_ErrorMessage);
 
194
                                break;
 
195
 
 
196
                        case NE_AUTH:
 
197
                        case NE_PROXYAUTH:
 
198
                                throw CAuthenticationError(m_d->m_ErrorMessage);
 
199
                                break;
 
200
 
 
201
                        default:
 
202
                                throw CFetchError(m_d->m_ErrorMessage);
 
203
                                break;
 
204
                }
 
205
 
 
206
                switch (m_d->m_Status)
 
207
                {
 
208
                        case 200:
 
209
                                break;
 
210
 
 
211
                        case 400:
 
212
                                throw CRequestError(m_d->m_ErrorMessage);
 
213
                                break;
 
214
 
 
215
                        case 401:
 
216
                                throw CAuthenticationError(m_d->m_ErrorMessage);
 
217
                                break;
 
218
 
 
219
                        case 404:
 
220
                                throw CResourceNotFoundError(m_d->m_ErrorMessage);
 
221
                                break;
 
222
 
 
223
                        default:
 
224
                                throw CFetchError(m_d->m_ErrorMessage);
 
225
                                break;
 
226
                }
 
227
        }
 
228
 
 
229
        ne_sock_exit();
 
230
 
 
231
        return Ret;
 
232
}
 
233
 
 
234
int MusicBrainz4::CHTTPFetch::httpAuth(void *userdata, const char *realm, int attempts,
 
235
                                         char *username, char *password)
 
236
{
 
237
        realm=realm;
 
238
 
 
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);
 
242
        return attempts;
 
243
}
 
244
 
 
245
int MusicBrainz4::CHTTPFetch::proxyAuth(void *userdata, const char *realm, int attempts,
 
246
                                         char *username, char *password)
 
247
{
 
248
        realm=realm;
 
249
 
 
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);
 
253
        return attempts;
 
254
}
 
255
 
 
256
int MusicBrainz4::CHTTPFetch::httpResponseReader(void *userdata, const char *buf, size_t len)
 
257
{
 
258
        std::vector<unsigned char> *buffer = reinterpret_cast<std::vector<unsigned char> *>(userdata);
 
259
 
 
260
        buffer->insert(buffer->end(),buf,buf+len);
 
261
 
 
262
        return 0;
 
263
}
 
264
 
 
265
std::vector<unsigned char> MusicBrainz4::CHTTPFetch::Data() const
 
266
{
 
267
        return m_d->m_Data;
 
268
}
 
269
 
 
270
int MusicBrainz4::CHTTPFetch::Result() const
 
271
{
 
272
        return m_d->m_Result;
 
273
}
 
274
 
 
275
int MusicBrainz4::CHTTPFetch::Status() const
 
276
{
 
277
        return m_d->m_Status;
 
278
}
 
279
 
 
280
std::string MusicBrainz4::CHTTPFetch::ErrorMessage() const
 
281
{
 
282
        return m_d->m_ErrorMessage;
 
283
}