3
MediaTomb - http://www.mediatomb.cc/
5
curl_io_handler.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: curl_io_handler.cc 1698 2008-02-23 20:48:30Z lww $
30
/// \file curl_io_handler.cc
33
#include "autoconfig.h"
39
#include "curl_io_handler.h"
43
CurlIOHandler::CurlIOHandler(String URL, CURL *curl_handle, size_t bufSize, size_t initialFillSize) : IOHandlerBufferHelper(bufSize, initialFillSize)
46
throw _Exception(_("URL has not been set correctly"));
47
if (bufSize < CURL_MAX_WRITE_SIZE)
48
throw _Exception(_("bufSize must be at least CURL_MAX_WRITE_SIZE(")+CURL_MAX_WRITE_SIZE+')');
51
this->external_curl_handle = (curl_handle != NULL);
52
this->curl_handle = curl_handle;
54
signalAfterEveryRead = true;
57
void CurlIOHandler::open(IN enum UpnpOpenFileMode mode)
60
if (curl_handle == NULL)
62
curl_handle = curl_easy_init();
63
if (curl_handle == NULL)
64
throw _Exception(_("failed to init curl"));
67
curl_easy_reset(curl_handle);
69
IOHandlerBufferHelper::open(mode);
72
void CurlIOHandler::close()
74
IOHandlerBufferHelper::close();
76
if (external_curl_handle && curl_handle != NULL)
77
curl_easy_cleanup(curl_handle);
80
void CurlIOHandler::threadProc()
83
assert(curl_handle != NULL);
84
assert(string_ok(URL));
86
//char error_buffer[CURL_ERROR_SIZE] = {'\0'};
87
//curl_easy_setopt(curl_handle, CURLOPT_ERRORBUFFER, error_buffer);
89
curl_easy_setopt(curl_handle, CURLOPT_URL, URL.c_str());
90
curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
91
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
92
curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, -1);
93
//curl_easy_setopt(curl_handle, CURLOPT_CONNECTTIMEOUT,
97
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, CurlIOHandler::curlCallback);
98
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)this);
100
res = curl_easy_perform(curl_handle);
111
size_t CurlIOHandler::curlCallback(void *ptr, size_t size, size_t nmemb, void *data)
113
CurlIOHandler * ego = (CurlIOHandler *) data;
114
size_t wantWrite = size * nmemb;
116
assert(wantWrite <= ego->bufSize);
118
//log_debug("URL: %s; size: %d; nmemb: %d; wantWrite: %d\n", ego->URL.c_str(), size, nmemb, wantWrite);
120
AUTOLOCK(ego->mutex);
134
if (ego->threadShutdown)
140
bufFree = ego->bufSize;
144
bufFree = ego->a - ego->b;
146
bufFree += ego->bufSize;
149
while ((size_t)bufFree < wantWrite);
152
size_t maxWrite = (ego->empty ? ego->bufSize : (ego->a < ego->b ? ego->bufSize - ego->b : ego->a - ego->b));
153
size_t write1 = (wantWrite > maxWrite ? maxWrite : wantWrite);
154
size_t write2 = (write1 < wantWrite ? wantWrite - write1 : 0);
156
size_t bLocal = ego->b;
160
memcpy(ego->buffer + bLocal, ptr, write1);
162
memcpy(ego->buffer, (char *)ptr + maxWrite, write2);
167
if (ego->b >= ego->bufSize)
168
ego->b -= ego->bufSize;
174
if (ego->waitForInitialFillSize)
176
int currentFillSize = ego->b - ego->a;
177
if (currentFillSize <= 0)
178
currentFillSize += ego->bufSize;
179
if ((size_t)currentFillSize >= ego->initialFillSize)
181
log_debug("buffer: initial fillsize reached\n");
182
ego->waitForInitialFillSize = false;
187
//ego->bytesCurl += wantWrite;