1
// NetConnection.cpp: Open local connections for FLV files or URLs.
3
// Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
5
// This program is free software; you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation; either version 3 of the License, or
8
// (at your option) any later version.
10
// This program is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
// GNU General Public License for more details.
15
// You should have received a copy of the GNU General Public License
16
// along with this program; if not, write to the Free Software
17
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
/* $Id: NetConnection.cpp,v 1.57.2.1 2008/02/22 14:16:39 strk Exp $ */
23
#include "gnashconfig.h"
29
#include "NetConnection.h"
31
#include "GnashException.h"
32
#include "builtin_function.h"
33
#include "movie_root.h"
34
#include "Object.h" // for getObjectInterface
36
#include "StreamProvider.h"
37
#include "URLAccessManager.h"
42
static as_value netconnection_new(const fn_call& fn);
43
//static as_object* getNetConnectionInterface();
45
/// \class NetConnection
46
/// \brief Opens a local connection through which you can play
47
/// back video (FLV) files from an HTTP address or from the local file
48
/// system, using curl.
51
NetConnection::NetConnection()
53
as_object(getNetConnectionInterface()),
60
NetConnection::~NetConnection()
66
bool NetConnection::openConnection(const std::string& url)
68
// if already running there is no need to setup things again
69
if ( _loader.get() ) {
70
log_debug("NetConnection::openConnection() called when already connected to a stream. Checking if the existing connection can be used.");
72
if (_prefixUrl.size() > 0) {
73
newurl += _prefixUrl + "/" + url;
77
if (newurl.compare(_completeUrl) == 0) {
84
if ( _prefixUrl.size() > 0 ) {
85
_completeUrl += _prefixUrl + "/" + url;
90
URL uri( _completeUrl, get_base_url() );
92
std::string uriStr( uri.str() );
93
assert( uriStr.find( "://" ) != std::string::npos );
95
// Check if we're allowed to open url
96
if ( ! URLAccessManager::allow( uri ) ) {
97
log_security( _("Gnash is not allowed to open this url: %s"), uriStr.c_str() );
101
log_security( _("Connecting to movie: %s"), uriStr.c_str() );
103
_loader.reset( new LoadThread() );
105
if ( ! _loader->setStream( std::auto_ptr<tu_file>(StreamProvider::getDefaultInstance().getStream( uri ) ) ) ) {
106
log_error( _("Gnash could not open this url: %s"), uriStr.c_str() );
112
log_debug( _("Connection established to movie: %s"), uriStr.c_str() );
122
if (!_loader.get()) return true; // @@ correct ?
123
return _loader->eof();
128
std::string NetConnection::validateURL(const std::string& url)
130
std::string completeUrl;
131
if (_prefixUrl.size() > 0) {
132
completeUrl += _prefixUrl + "/" + url;
137
URL uri(completeUrl, get_base_url());
139
std::string uriStr(uri.str());
140
assert(uriStr.find("://") != std::string::npos);
142
// Check if we're allowed to open url
143
if (!URLAccessManager::allow(uri)) {
144
log_security(_("Gnash is not allowed to open this url: %s"), uriStr.c_str());
148
log_debug(_("Connection to movie: %s"), uriStr.c_str());
155
NetConnection::addToURL(const std::string& url)
157
// What is this ? It is NOT documented in the header !!
158
//if (url == "null" || url == "NULL") return;
160
// If there already is something in _prefixUrl, then we already have a url,
161
// so no need to renew it. This may not correct, needs some testing.
162
if (_prefixUrl.size() > 0) return;
170
NetConnection::read( void *dst, size_t bytes )
172
if ( ! _loader.get() ) {
176
return _loader->read( dst, bytes );
182
NetConnection::seek( size_t pos )
184
if ( ! _loader.get() ) {
188
return _loader->seek( pos );
194
NetConnection::tell()
196
if (!_loader.get()) return 0; // @@ correct ?
197
return _loader->tell();
203
NetConnection::getBytesLoaded()
205
if (!_loader.get()) return 0; // @@ correct ?
206
return _loader->getBytesLoaded();
212
NetConnection::getBytesTotal()
214
if (!_loader.get()) return 0; // @@ correct ?
215
return _loader->getBytesTotal();
221
NetConnection::loadCompleted()
223
if ( ! _loader.get() ) {
227
return _loader->completed();
231
std::auto_ptr<FLVParser>
232
NetConnection::getConnectedParser() const
234
std::auto_ptr<FLVParser> ret;
236
if ( _loader.get() ) {
237
ret.reset( new FLVParser(*_loader) );
244
/// \brief callback to instantiate a new NetConnection object.
245
/// \param fn the parameters from the Flash movie
246
/// \return nothing from the function call.
247
/// \note The return value is returned through the fn.result member.
249
netconnection_new(const fn_call& /* fn */)
251
GNASH_REPORT_FUNCTION;
253
NetConnection *netconnection_obj = new NetConnection;
255
return as_value(netconnection_obj);
259
NetConnection::connect_method(const fn_call& fn)
263
// NetConnection::connect() is *documented*, I repeat, *documented*, to require the
264
// "url" argument to be NULL in AS <= 2. This is *legal* and *required*. Anything
265
// other than NULL is undocumented behaviour, and I would like to know if there
266
// are any movies out there relying on it. --bjacques.
268
GNASH_REPORT_FUNCTION;
270
boost::intrusive_ptr<NetConnection> ptr = ensureType<NetConnection>(fn.this_ptr);
274
IF_VERBOSE_ASCODING_ERRORS(
275
log_aserror(_("NetConnection.connect(): needs at least one argument"));
277
return as_value(false);
280
as_value& url_val = fn.arg(0);
282
// Check first arg for validity
283
if ( url_val.is_null())
285
// Null URL was passed. This is expected. Of course, it also makes this
286
// function (and, this class) rather useless. We return true, even though
287
// returning true has no meaning.
289
return as_value(true);
292
// The remainder of this function is undocumented.
294
if (url_val.is_undefined()) {
295
IF_VERBOSE_ASCODING_ERRORS(
296
log_aserror(_("NetConnection.connect(): first argument shouldn't be undefined"));
298
return as_value(false);
302
/// .. TODO: checkme ... addToURL ?? shoudnl't we attempt a connection ??
303
ptr->addToURL(url_val.to_string());
307
std::stringstream ss; fn.dump_args(ss);
308
log_unimpl("NetConnection.connect(%s): args after the first are not supported", ss.str().c_str());
312
// TODO: FIXME: should return true *or false* for RTMP connections
313
return as_value(true);
317
NetConnection::addHeader_method(const fn_call& fn)
319
boost::intrusive_ptr<NetConnection> ptr = ensureType<NetConnection>(fn.this_ptr);
322
log_unimpl("NetConnection.addHeader()");
327
NetConnection::call_method(const fn_call& fn)
329
boost::intrusive_ptr<NetConnection> ptr = ensureType<NetConnection>(fn.this_ptr);
332
log_unimpl("NetConnection.call()");
337
NetConnection::close_method(const fn_call& fn)
339
boost::intrusive_ptr<NetConnection> ptr = ensureType<NetConnection>(fn.this_ptr);
342
log_unimpl("NetConnection.close()");
347
NetConnection::isConnected_getset(const fn_call& fn)
349
boost::intrusive_ptr<NetConnection> ptr = ensureType<NetConnection>(fn.this_ptr);
352
if ( fn.nargs == 0 ) // getter
354
log_unimpl("NetConnection.isConnected get");
359
IF_VERBOSE_ASCODING_ERRORS(
360
log_aserror("Tried to set read-only property NetConnection.isConnected");
367
NetConnection::uri_getset(const fn_call& fn)
369
boost::intrusive_ptr<NetConnection> ptr = ensureType<NetConnection>(fn.this_ptr);
372
if ( fn.nargs == 0 ) // getter
374
log_unimpl("NetConnection.uri get");
379
log_unimpl("NetConnection.uri set");
386
NetConnection::attachNetConnectionInterface(as_object& o)
388
o.init_member("connect", new builtin_function(NetConnection::connect_method));
389
o.init_member("addHeader", new builtin_function(NetConnection::addHeader_method));
390
o.init_member("call", new builtin_function(NetConnection::call_method));
391
o.init_member("close", new builtin_function(NetConnection::close_method));
396
NetConnection::attachProperties()
398
boost::intrusive_ptr<builtin_function> gettersetter;
400
gettersetter = new builtin_function(NetConnection::isConnected_getset, NULL);
401
init_property("isConnected", *gettersetter, *gettersetter);
403
gettersetter = new builtin_function(NetConnection::uri_getset, NULL);
404
init_property("uri", *gettersetter, *gettersetter);
409
NetConnection::getNetConnectionInterface()
412
static boost::intrusive_ptr<as_object> o;
415
o = new as_object(getObjectInterface());
416
NetConnection::attachNetConnectionInterface(*o);
423
NetConnection::registerConstructor(as_object& global)
426
// This is going to be the global NetConnection "class"/"function"
427
static boost::intrusive_ptr<builtin_function> cl;
431
cl=new builtin_function(&netconnection_new, getNetConnectionInterface());
432
// replicate all interface to class, to be able to access
433
// all methods as static functions
434
// TODO: this is probably wrong !
435
NetConnection::attachNetConnectionInterface(*cl);
439
// Register _global.String
440
global.init_member("NetConnection", cl.get());
444
// extern (used by Global.cpp)
445
void netconnection_class_init(as_object& global)
447
NetConnection::registerConstructor(global);
451
} // end of gnash namespace