3
MediaTomb - http://www.mediatomb.cc/
5
url.cc - this file is part of MediaTomb.
7
Copyright (C) 2005 Gena Batyan <bgeradz@mediatomb.cc>,
8
Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc>
10
Copyright (C) 2006-2008 Gena Batyan <bgeradz@mediatomb.cc>,
11
Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc>,
12
Leonhard Wimmer <leo@mediatomb.cc>
14
MediaTomb is free software; you can redistribute it and/or modify
15
it under the terms of the GNU General Public License version 2
16
as published by the Free Software Foundation.
18
MediaTomb is distributed in the hope that it will be useful,
19
but WITHOUT ANY WARRANTY; without even the implied warranty of
20
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
GNU General Public License for more details.
23
You should have received a copy of the GNU General Public License
24
version 2 along with MediaTomb; if not, write to the Free Software
25
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
27
$Id: url.cc 1714 2008-03-01 17:33:21Z lww $
33
#include "autoconfig.h"
46
URL::URL(size_t buffer_hint)
48
this->buffer_hint = buffer_hint;
51
Ref<StringBuffer> URL::download(String URL, long *HTTP_retcode,
52
CURL *curl_handle, bool only_header,
53
bool verbose, bool redirect)
57
char error_buffer[CURL_ERROR_SIZE] = {'\0'};
59
if (curl_handle == NULL)
61
curl_handle = curl_easy_init();
63
if (curl_handle == NULL)
64
throw _Exception(_("Invalid curl handle!\n"));
67
Ref<StringBuffer> buffer(new StringBuffer(buffer_hint));
69
curl_easy_reset(curl_handle);
71
curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1);
73
curl_easy_setopt(curl_handle, CURLOPT_URL, URL.c_str());
74
curl_easy_setopt(curl_handle, CURLOPT_ERRORBUFFER, error_buffer);
78
curl_easy_setopt(curl_handle, CURLOPT_NOBODY);
79
curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, URL::dl);
80
curl_easy_setopt(curl_handle, CURLOPT_HEADERDATA,
81
(void *)buffer.getPtr());
85
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, URL::dl);
86
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA,
87
(void *)buffer.getPtr());
92
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
93
curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, -1);
96
res = curl_easy_perform(curl_handle);
99
log_error("%s\n", error_buffer);
101
curl_easy_cleanup(curl_handle);
102
throw _Exception(String(error_buffer));
105
res = curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, HTTP_retcode);
108
log_error("%s\n", error_buffer);
110
curl_easy_cleanup(curl_handle);
111
throw _Exception(String(error_buffer));
115
curl_easy_cleanup(curl_handle);
120
Ref<URL::Stat> URL::getInfo(String URL, CURL *curl_handle)
123
bool cleanup = false;
127
char error_buffer[CURL_ERROR_SIZE] = {'\0'};
130
if (curl_handle == NULL)
132
curl_handle = curl_easy_init();
134
if (curl_handle == NULL)
135
throw _Exception(_("Invalid curl handle!\n"));
138
Ref<StringBuffer> buffer = download(URL, &retcode, curl_handle, true);
142
curl_easy_cleanup(curl_handle);
143
throw _Exception(_("Error retrieving information from ") +
144
URL + _(" HTTP return code: ") +
145
String::from(retcode));
148
Ref<RExp> getMT(new RExp());
152
getMT->compile(_("\nContent-Type: ([^\n]+)\n"), REG_ICASE);
157
curl_easy_cleanup(curl_handle);
162
Ref<Matcher> matcher = getMT->matcher(buffer->toString());
165
mt = trim_string(matcher->group(1));
167
mt = _(MIMETYPE_DEFAULT);
169
log_debug("Extracted content type: %s\n", mt.c_str());
171
Ref<RExp> getCL(new RExp());
175
getCL->compile(_("\nContent-Length: ([^\n]+)\n"), REG_ICASE);
180
curl_easy_cleanup(curl_handle);
185
matcher = getCL->matcher(buffer->toString());
188
cl = trim_string(matcher->group(1)).toOFF_T();
192
res = curl_easy_getinfo(curl_handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &cl);
195
log_error("%s\n", error_buffer);
197
curl_easy_cleanup(curl_handle);
198
throw _Exception(String(error_buffer));
201
res = curl_easy_getinfo(curl_handle, CURLINFO_CONTENT_TYPE, &ct);
204
log_error("%s\n", error_buffer);
206
curl_easy_cleanup(curl_handle);
207
throw _Exception(String(error_buffer));
211
mt = _(MIMETYPE_DEFAULT);
215
log_debug("Extracted content length: %ld\n", cl);
217
Ref<Stat> st(new Stat((off_t)cl, mt));
220
curl_easy_cleanup(curl_handle);
226
size_t URL::dl(void *buf, size_t size, size_t nmemb, void *data)
228
StringBuffer *buffer = (StringBuffer *)data;
232
size_t s = size * nmemb;
233
*buffer << String((char *)buf, s);