3
MediaTomb - http://www.mediatomb.cc/
5
url_request_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: url_request_handler.cc 1723 2008-03-01 22:34:27Z jin_eld $
30
/// \file url_request_handler.cc
33
#include "autoconfig.h"
42
#include "buffered_io_handler.h"
43
#include "dictionary.h"
44
#include "url_request_handler.h"
45
#include "cds_objects.h"
46
#ifdef ONLINE_SERVICES
47
#include "online_service_helper.h"
50
#include "curl_io_handler.h"
51
#ifdef EXTERNAL_TRANSCODING
52
#include "transcoding/transcode_dispatcher.h"
58
URLRequestHandler::URLRequestHandler() : RequestHandler()
62
void URLRequestHandler::get_info(IN const char *filename, OUT struct File_Info *info)
68
#ifdef EXTERNAL_TRANSCODING
72
String url, parameters;
73
split_url(filename, URL_PARAM_SEPARATOR, url, parameters);
75
Ref<Dictionary> dict(new Dictionary());
76
dict->decode(parameters);
78
log_debug("full url (filename): %s, url: %s, parameters: %s\n",
79
filename, url.c_str(), parameters.c_str());
81
String objID = dict->get(_("object_id"));
84
//log_error("object_id not found in url\n");
85
throw _Exception(_("get_info: object_id not found"));
88
objectID = objID.toInt();
90
//log_debug("got ObjectID: [%s]\n", object_id.c_str());
92
Ref<Storage> storage = Storage::getInstance();
94
Ref<CdsObject> obj = storage->loadObject(objectID);
96
int objectType = obj->getObjectType();
98
if (!IS_CDS_ITEM_EXTERNAL_URL(objectType))
100
throw _Exception(_("get_info: object is not an external url item"));
103
#ifdef EXTERNAL_TRANSCODING
104
tr_profile = dict->get(_(URL_PARAM_TRANSCODE_PROFILE_NAME));
106
if (string_ok(tr_profile))
108
Ref<TranscodingProfile> tp = ConfigManager::getInstance()->getTranscodingProfileListOption(CFG_TRANSCODING_PROFILE_LIST)->getByName(tr_profile);
111
throw _Exception(_("Transcoding requested but no profile "
112
"matching the name ") + tr_profile + " found");
114
mimeType = tp->getTargetMimeType();
115
info->file_length = -1;
120
Ref<CdsItemExternalURL> item = RefCast(obj, CdsItemExternalURL);
122
#ifdef ONLINE_SERVICES
123
if (item->getFlag(OBJECT_FLAG_ONLINE_SERVICE))
125
/// \todo write a helper class that will handle various online
127
Ref<OnlineServiceHelper> helper (new OnlineServiceHelper());
128
url = helper->resolveURL(item);
133
url = item->getLocation();
136
log_debug("Online content url: %s\n", url.c_str());
137
Ref<URL> u(new URL(1024));
141
st = u->getInfo(url);
142
info->file_length = st->getSize();
146
log_warning("%s\n", ex.getMessage().c_str());
147
info->file_length = -1;
150
mimeType = item->getMimeType();
153
info->is_readable = 1;
154
info->last_modified = 0;
155
info->is_directory = 0;
156
info->http_header = NULL;
158
info->content_type = ixmlCloneDOMString(mimeType.c_str());
159
log_debug("web_get_info(): end\n");
161
/// \todo transcoding for get_info
164
Ref<IOHandler> URLRequestHandler::open(IN const char *filename, OUT struct File_Info *info, IN enum UpnpOpenFileMode mode)
168
#ifdef EXTERNAL_TRANSCODING
172
log_debug("start\n");
174
// Currently we explicitly do not support UPNP_WRITE
175
// due to security reasons.
176
if (mode != UPNP_READ)
177
throw _Exception(_("UPNP_WRITE unsupported"));
179
String url, parameters;
180
split_url(filename, URL_PARAM_SEPARATOR, url, parameters);
182
Ref<Dictionary> dict(new Dictionary());
183
dict->decode(parameters);
184
log_debug("full url (filename): %s, url: %s, parameters: %s\n",
185
filename, url.c_str(), parameters.c_str());
187
String objID = dict->get(_("object_id"));
190
throw _Exception(_("object_id not found"));
193
objectID = objID.toInt();
195
Ref<Storage> storage = Storage::getInstance();
197
Ref<CdsObject> obj = storage->loadObject(objectID);
199
int objectType = obj->getObjectType();
201
if (!IS_CDS_ITEM_EXTERNAL_URL(objectType))
203
throw _Exception(_("object is not an external url item"));
206
Ref<CdsItemExternalURL> item = RefCast(obj, CdsItemExternalURL);
208
#ifdef ONLINE_SERVICES
209
if (item->getFlag(OBJECT_FLAG_ONLINE_SERVICE))
211
Ref<OnlineServiceHelper> helper (new OnlineServiceHelper());
212
url = helper->resolveURL(item);
217
url = item->getLocation();
220
log_debug("Online content url: %s\n", url.c_str());
222
info->is_readable = 1;
223
info->last_modified = 0;
224
info->is_directory = 0;
225
info->http_header = NULL;
227
#ifdef EXTERNAL_TRANSCODING
228
tr_profile = dict->get(_(URL_PARAM_TRANSCODE_PROFILE_NAME));
230
if (string_ok(tr_profile))
232
Ref<TranscodingProfile> tp = ConfigManager::getInstance()->getTranscodingProfileListOption(CFG_TRANSCODING_PROFILE_LIST)->getByName(tr_profile);
235
throw _Exception(_("Transcoding of file ") + url +
236
" but no profile matching the name " +
237
tr_profile + " found");
239
Ref<TranscodeDispatcher> tr_d(new TranscodeDispatcher());
240
return tr_d->open(tp, url, item->getObjectType(), info);
245
Ref<URL> u(new URL(1024));
249
st = u->getInfo(url);
250
info->file_length = st->getSize();
254
log_warning("%s\n", ex.getMessage().c_str());
255
info->file_length = -1;
257
mimeType = item->getMimeType();
258
info->content_type = ixmlCloneDOMString(mimeType.c_str());
261
///\todo make curl io handler configurable for url request handler
262
Ref<IOHandler> io_handler(new CurlIOHandler(url, NULL, 1024*1024, 0));
264
io_handler->open(mode);