~vanvugt/+junk/mediatomb

« back to all changes in this revision

Viewing changes to src/curl_io_handler.cc

  • Committer: Bazaar Package Importer
  • Author(s): Andres Mejia
  • Date: 2008-03-02 13:09:16 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080302130916-zlljdze3kt7vuq4b
Tags: 0.11.0-1
* New upstream release.
* Include message about which inotify headers will be used when enabling
  inotify runtime support.
* Fixed error with use of INTERFACE in init script. Also removed use of -m
  option.
* Including new config.xml options.
* Added more build dependencies for new upstream release.
* Removed build dependency of libid3-dev, taglib is now preferred.
* mediatomb.xpm and manpage.xml is now included in orig tarball.
* inotify patch is not needed anymore.
* md5 patch has been committed upstream and is no longer needed. Also removed
  README.Debian.
* TwinHelix PNG fix is now used. Removed from TODO.
* Adding dependency of iceweasel for mediatomb package.
* Updated copyright file.
* Updated watch file.
* Updated rules file for proper configure options.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*MT*
 
2
    
 
3
    MediaTomb - http://www.mediatomb.cc/
 
4
    
 
5
    curl_io_handler.cc - this file is part of MediaTomb.
 
6
    
 
7
    Copyright (C) 2005 Gena Batyan <bgeradz@mediatomb.cc>,
 
8
                       Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc>
 
9
    
 
10
    Copyright (C) 2006-2008 Gena Batyan <bgeradz@mediatomb.cc>,
 
11
                            Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc>,
 
12
                            Leonhard Wimmer <leo@mediatomb.cc>
 
13
    
 
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.
 
17
    
 
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.
 
22
    
 
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.
 
26
    
 
27
    $Id: curl_io_handler.cc 1698 2008-02-23 20:48:30Z lww $
 
28
*/
 
29
 
 
30
/// \file curl_io_handler.cc
 
31
 
 
32
#ifdef HAVE_CONFIG_H
 
33
    #include "autoconfig.h"
 
34
#endif
 
35
 
 
36
#ifdef HAVE_CURL
 
37
 
 
38
#include "tools.h"
 
39
#include "curl_io_handler.h"
 
40
 
 
41
using namespace zmm;
 
42
 
 
43
CurlIOHandler::CurlIOHandler(String URL, CURL *curl_handle, size_t bufSize, size_t initialFillSize) : IOHandlerBufferHelper(bufSize, initialFillSize)
 
44
{
 
45
    if (! string_ok(URL))
 
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+')');
 
49
    
 
50
    this->URL = URL;
 
51
    this->external_curl_handle = (curl_handle != NULL);
 
52
    this->curl_handle = curl_handle;
 
53
    //bytesCurl = 0;
 
54
    signalAfterEveryRead = true;
 
55
}
 
56
 
 
57
void CurlIOHandler::open(IN enum UpnpOpenFileMode mode)
 
58
{
 
59
    
 
60
    if (curl_handle == NULL)
 
61
    {
 
62
        curl_handle = curl_easy_init();
 
63
        if (curl_handle == NULL)
 
64
            throw _Exception(_("failed to init curl"));
 
65
    }
 
66
    else
 
67
        curl_easy_reset(curl_handle);
 
68
    
 
69
    IOHandlerBufferHelper::open(mode);
 
70
}
 
71
 
 
72
void CurlIOHandler::close()
 
73
{
 
74
    IOHandlerBufferHelper::close();
 
75
    
 
76
    if (external_curl_handle && curl_handle != NULL)
 
77
        curl_easy_cleanup(curl_handle);
 
78
}
 
79
 
 
80
void CurlIOHandler::threadProc()
 
81
{
 
82
    CURLcode res;
 
83
    assert(curl_handle != NULL);
 
84
    assert(string_ok(URL));
 
85
    
 
86
    //char error_buffer[CURL_ERROR_SIZE] = {'\0'};
 
87
    //curl_easy_setopt(curl_handle, CURLOPT_ERRORBUFFER, error_buffer);
 
88
    
 
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,
 
94
    
 
95
    //proxy..
 
96
    
 
97
    curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, CurlIOHandler::curlCallback);
 
98
    curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)this);
 
99
    
 
100
    res = curl_easy_perform(curl_handle);
 
101
    if (res != CURLE_OK)
 
102
        readError = true;
 
103
    else
 
104
        eof = true;
 
105
    
 
106
    cond->signal();
 
107
}
 
108
 
 
109
 
 
110
 
 
111
size_t CurlIOHandler::curlCallback(void *ptr, size_t size, size_t nmemb, void *data)
 
112
{
 
113
    CurlIOHandler * ego = (CurlIOHandler *) data;
 
114
    size_t wantWrite = size * nmemb;
 
115
    
 
116
    assert(wantWrite <= ego->bufSize);
 
117
    
 
118
    //log_debug("URL: %s; size: %d; nmemb: %d; wantWrite: %d\n", ego->URL.c_str(), size, nmemb, wantWrite);
 
119
    
 
120
    AUTOLOCK(ego->mutex);
 
121
    
 
122
    bool first = true;
 
123
    
 
124
    int bufFree = 0;
 
125
    do
 
126
    {
 
127
        if (! first)
 
128
        {
 
129
            ego->cond->wait();
 
130
        }
 
131
        else
 
132
            first = false;
 
133
        
 
134
        if (ego->threadShutdown)
 
135
            return 0;
 
136
        
 
137
        if (ego->empty)
 
138
        {
 
139
            ego->a = ego->b = 0;
 
140
            bufFree = ego->bufSize;
 
141
        }
 
142
        else
 
143
        {
 
144
            bufFree = ego->a - ego->b;
 
145
            if (bufFree < 0)
 
146
                bufFree += ego->bufSize;
 
147
        }
 
148
    }
 
149
    while ((size_t)bufFree < wantWrite);
 
150
    
 
151
    
 
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);
 
155
    
 
156
    size_t bLocal = ego->b;
 
157
    
 
158
    AUTOUNLOCK();
 
159
    
 
160
    memcpy(ego->buffer + bLocal, ptr, write1);
 
161
    if (write2)
 
162
        memcpy(ego->buffer, (char *)ptr + maxWrite, write2);
 
163
    
 
164
    AUTORELOCK();
 
165
    
 
166
    ego->b += wantWrite;
 
167
    if (ego->b >= ego->bufSize)
 
168
        ego->b -= ego->bufSize;
 
169
    if (ego->empty)
 
170
    {
 
171
        ego->empty = false;
 
172
        ego->cond->signal();
 
173
    }
 
174
    if (ego->waitForInitialFillSize)
 
175
    {
 
176
        int currentFillSize = ego->b - ego->a;
 
177
        if (currentFillSize <= 0)
 
178
            currentFillSize += ego->bufSize;
 
179
        if ((size_t)currentFillSize >= ego->initialFillSize)
 
180
        {
 
181
            log_debug("buffer: initial fillsize reached\n");
 
182
            ego->waitForInitialFillSize = false;
 
183
            ego->cond->signal();
 
184
        }
 
185
    }
 
186
    
 
187
    //ego->bytesCurl += wantWrite;
 
188
    return wantWrite;
 
189
}
 
190
 
 
191
#endif//HAVE_CURL