~ubuntu-branches/ubuntu/saucy/gnash/saucy-proposed

« back to all changes in this revision

Viewing changes to server/asobj/NetConnection.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alexander Sack
  • Date: 2008-10-13 14:29:49 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20081013142949-f6qdvnu4mn05ltdc
Tags: 0.8.4~~bzr9980-0ubuntu1
* new upstream release 0.8.4 (LP: #240325)
* ship new lib usr/lib/gnash/libmozsdk.so.* in mozilla-plugin-gnash
  - update debian/mozilla-plugin-gnash.install
* ship new lib usr/lib/gnash/libgnashnet.so.* in gnash-common
  - update debian/gnash-common.install
* add basic debian/build_head script to build latest CVS head packages.
  - add debian/build_head
* new sound architecture requires build depend on libsdl1.2-dev
  - update debian/control
* head build script now has been completely migrated to bzr (upstream +
  ubuntu)
  - update debian/build_head
* disable kde gui until klash/qt4 has been fixed; keep kde packages as empty
  packages for now.
  - update debian/rules
  - debian/klash.install
  - debian/klash.links
  - debian/klash.manpages
  - debian/konqueror-plugin-gnash.install
* drop libkonq5-dev build dependency accordingly
  - update debian/control
* don't install headers manually anymore. gnash doesnt provide a -dev
  package after all
  - update debian/rules
* update libs installed in gnash-common; libgnashserver-*.so is not available
  anymore (removed); in turn we add the new libgnashcore-*.so
  - update debian/gnash-common.install
* use -Os for optimization and properly pass CXXFLAGS=$(CFLAGS) to configure
  - update debian/rules
* touch firefox .autoreg in postinst of mozilla plugin
  - update debian/mozilla-plugin-gnash.postinst
* link gnash in ubufox plugins directory for the plugin alternative switcher
  - add debian/mozilla-plugin-gnash.links
* suggest ubufox accordingly
  - update debian/control
* add new required build-depends on libgif-dev
  - update debian/control
* add Xb-Npp-Description and Xb-Npp-File as new plugin database meta data
  - update debian/control

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// NetConnection.cpp:  Open local connections for FLV files or URLs.
2
 
// 
3
 
//   Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
4
 
// 
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.
9
 
// 
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.
14
 
//
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
18
 
//
19
 
 
20
 
/* $Id: NetConnection.cpp,v 1.57.2.1 2008/02/22 14:16:39 strk Exp $ */
21
 
 
22
 
#ifdef HAVE_CONFIG_H
23
 
#include "gnashconfig.h"
24
 
#endif
25
 
 
26
 
#include <iostream>
27
 
#include <string>
28
 
#include <new>
29
 
#include "NetConnection.h"
30
 
#include "log.h"
31
 
#include "GnashException.h"
32
 
#include "builtin_function.h"
33
 
#include "movie_root.h"
34
 
#include "Object.h" // for getObjectInterface
35
 
 
36
 
#include "StreamProvider.h"
37
 
#include "URLAccessManager.h"
38
 
#include "URL.h"
39
 
 
40
 
namespace gnash {
41
 
 
42
 
static as_value netconnection_new(const fn_call& fn);
43
 
//static as_object* getNetConnectionInterface();
44
 
 
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.
49
 
 
50
 
 
51
 
NetConnection::NetConnection()
52
 
        :
53
 
        as_object(getNetConnectionInterface()),
54
 
        _loader()
55
 
{
56
 
        attachProperties();
57
 
}
58
 
 
59
 
 
60
 
NetConnection::~NetConnection()
61
 
{
62
 
}
63
 
 
64
 
 
65
 
/*public*/
66
 
bool NetConnection::openConnection(const std::string& url)
67
 
{
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.");
71
 
    std::string newurl;
72
 
    if (_prefixUrl.size() > 0) {
73
 
      newurl += _prefixUrl + "/" + url;
74
 
    } else {
75
 
      newurl += url;
76
 
    }
77
 
    if (newurl.compare(_completeUrl) == 0) {
78
 
      return true;
79
 
    } else { 
80
 
      return false;
81
 
    }
82
 
  }
83
 
 
84
 
  if ( _prefixUrl.size() > 0 ) {
85
 
    _completeUrl += _prefixUrl + "/" + url;
86
 
  } else {
87
 
    _completeUrl += url;
88
 
  }
89
 
 
90
 
  URL uri( _completeUrl, get_base_url() );
91
 
 
92
 
  std::string uriStr( uri.str() );
93
 
  assert( uriStr.find( "://" ) != std::string::npos );
94
 
 
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() );
98
 
    return false;
99
 
  }
100
 
 
101
 
  log_security( _("Connecting to movie: %s"), uriStr.c_str() );
102
 
 
103
 
  _loader.reset( new LoadThread() );
104
 
 
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() );
107
 
    _loader.reset();
108
 
 
109
 
    return false;
110
 
  }
111
 
 
112
 
  log_debug( _("Connection established to movie: %s"), uriStr.c_str() );
113
 
 
114
 
  return true;
115
 
}
116
 
 
117
 
 
118
 
/*public*/
119
 
bool
120
 
NetConnection::eof()
121
 
{
122
 
        if (!_loader.get()) return true; // @@ correct ?
123
 
        return _loader->eof();
124
 
}
125
 
 
126
 
 
127
 
/*public*/
128
 
std::string NetConnection::validateURL(const std::string& url)
129
 
{
130
 
        std::string completeUrl;
131
 
        if (_prefixUrl.size() > 0) {
132
 
                completeUrl += _prefixUrl + "/" + url;
133
 
        } else {
134
 
                completeUrl += url;
135
 
        }
136
 
 
137
 
        URL uri(completeUrl, get_base_url());
138
 
 
139
 
        std::string uriStr(uri.str());
140
 
        assert(uriStr.find("://") != std::string::npos);
141
 
 
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());
145
 
                return "";
146
 
        }
147
 
 
148
 
        log_debug(_("Connection to movie: %s"), uriStr.c_str());
149
 
 
150
 
        return uriStr;
151
 
}
152
 
 
153
 
/*private*/
154
 
void
155
 
NetConnection::addToURL(const std::string& url)
156
 
{
157
 
        // What is this ? It is NOT documented in the header !!
158
 
        //if (url == "null" || url == "NULL") return;
159
 
 
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;
163
 
 
164
 
        _prefixUrl += url;
165
 
}
166
 
 
167
 
 
168
 
/*public*/
169
 
size_t
170
 
NetConnection::read( void *dst, size_t bytes )
171
 
{
172
 
  if ( ! _loader.get() ) {
173
 
    return 0;
174
 
  }
175
 
 
176
 
  return _loader->read( dst, bytes );
177
 
}
178
 
 
179
 
 
180
 
/*public*/
181
 
bool
182
 
NetConnection::seek( size_t pos )
183
 
{
184
 
  if ( ! _loader.get() ) {
185
 
    return false;
186
 
  }
187
 
 
188
 
  return _loader->seek( pos );
189
 
}
190
 
 
191
 
 
192
 
/*public*/
193
 
size_t
194
 
NetConnection::tell()
195
 
{
196
 
        if (!_loader.get()) return 0; // @@ correct ?
197
 
        return _loader->tell();
198
 
}
199
 
 
200
 
 
201
 
/*public*/
202
 
long
203
 
NetConnection::getBytesLoaded()
204
 
{
205
 
        if (!_loader.get()) return 0; // @@ correct ?
206
 
        return _loader->getBytesLoaded();
207
 
}
208
 
 
209
 
 
210
 
/*public*/
211
 
long
212
 
NetConnection::getBytesTotal()
213
 
{
214
 
        if (!_loader.get()) return 0; // @@ correct ?
215
 
        return _loader->getBytesTotal();
216
 
}
217
 
 
218
 
 
219
 
/*public*/
220
 
bool
221
 
NetConnection::loadCompleted()
222
 
{
223
 
  if ( ! _loader.get() ) {
224
 
    return false;
225
 
  }
226
 
 
227
 
  return _loader->completed();
228
 
}
229
 
 
230
 
 
231
 
std::auto_ptr<FLVParser>
232
 
NetConnection::getConnectedParser() const
233
 
{
234
 
  std::auto_ptr<FLVParser> ret;
235
 
 
236
 
  if ( _loader.get() ) {
237
 
    ret.reset( new FLVParser(*_loader) );
238
 
  }
239
 
 
240
 
  return ret;
241
 
}
242
 
 
243
 
 
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.
248
 
static as_value
249
 
netconnection_new(const fn_call& /* fn */)
250
 
{
251
 
        GNASH_REPORT_FUNCTION;
252
 
 
253
 
        NetConnection *netconnection_obj = new NetConnection;
254
 
 
255
 
        return as_value(netconnection_obj);
256
 
}
257
 
 
258
 
as_value
259
 
NetConnection::connect_method(const fn_call& fn)
260
 
{
261
 
        // NOTE:
262
 
        //
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.
267
 
 
268
 
        GNASH_REPORT_FUNCTION;
269
 
 
270
 
        boost::intrusive_ptr<NetConnection> ptr = ensureType<NetConnection>(fn.this_ptr); 
271
 
    
272
 
        if (fn.nargs < 1)
273
 
        {
274
 
                IF_VERBOSE_ASCODING_ERRORS(
275
 
                log_aserror(_("NetConnection.connect(): needs at least one argument"));
276
 
                );
277
 
                return as_value(false);
278
 
        }
279
 
 
280
 
        as_value& url_val = fn.arg(0);
281
 
 
282
 
        // Check first arg for validity 
283
 
        if ( url_val.is_null())
284
 
        {
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.
288
 
                
289
 
                return as_value(true);
290
 
        }
291
 
 
292
 
        // The remainder of this function is undocumented.
293
 
        
294
 
        if (url_val.is_undefined()) {
295
 
                IF_VERBOSE_ASCODING_ERRORS(
296
 
                log_aserror(_("NetConnection.connect(): first argument shouldn't be undefined"));
297
 
                );
298
 
                return as_value(false);
299
 
        }
300
 
 
301
 
 
302
 
        /// .. TODO: checkme ... addToURL ?? shoudnl't we attempt a connection ??
303
 
        ptr->addToURL(url_val.to_string());
304
 
 
305
 
        if ( fn.nargs > 1 )
306
 
        {
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());
309
 
        }
310
 
 
311
 
 
312
 
        // TODO: FIXME: should return true *or false* for RTMP connections
313
 
        return as_value(true);
314
 
}
315
 
 
316
 
as_value
317
 
NetConnection::addHeader_method(const fn_call& fn)
318
 
{
319
 
        boost::intrusive_ptr<NetConnection> ptr = ensureType<NetConnection>(fn.this_ptr); 
320
 
        UNUSED(ptr);
321
 
 
322
 
        log_unimpl("NetConnection.addHeader()");
323
 
        return as_value();
324
 
}
325
 
 
326
 
as_value
327
 
NetConnection::call_method(const fn_call& fn)
328
 
{
329
 
        boost::intrusive_ptr<NetConnection> ptr = ensureType<NetConnection>(fn.this_ptr); 
330
 
        UNUSED(ptr);
331
 
 
332
 
        log_unimpl("NetConnection.call()");
333
 
        return as_value();
334
 
}
335
 
 
336
 
as_value
337
 
NetConnection::close_method(const fn_call& fn)
338
 
{
339
 
        boost::intrusive_ptr<NetConnection> ptr = ensureType<NetConnection>(fn.this_ptr); 
340
 
        UNUSED(ptr);
341
 
 
342
 
        log_unimpl("NetConnection.close()");
343
 
        return as_value();
344
 
}
345
 
 
346
 
as_value
347
 
NetConnection::isConnected_getset(const fn_call& fn)
348
 
{
349
 
        boost::intrusive_ptr<NetConnection> ptr = ensureType<NetConnection>(fn.this_ptr); 
350
 
        UNUSED(ptr);
351
 
 
352
 
        if ( fn.nargs == 0 ) // getter
353
 
        {
354
 
                log_unimpl("NetConnection.isConnected get");
355
 
          return as_value();
356
 
        }
357
 
        else // setter
358
 
        {
359
 
                IF_VERBOSE_ASCODING_ERRORS(
360
 
                log_aserror("Tried to set read-only property NetConnection.isConnected");
361
 
                );
362
 
                return as_value();
363
 
        }
364
 
}
365
 
 
366
 
as_value
367
 
NetConnection::uri_getset(const fn_call& fn)
368
 
{
369
 
        boost::intrusive_ptr<NetConnection> ptr = ensureType<NetConnection>(fn.this_ptr); 
370
 
        UNUSED(ptr);
371
 
 
372
 
        if ( fn.nargs == 0 ) // getter
373
 
        {
374
 
                log_unimpl("NetConnection.uri get");
375
 
                return as_value();
376
 
        }
377
 
        else // setter
378
 
        {
379
 
                log_unimpl("NetConnection.uri set");
380
 
                return as_value();
381
 
        }
382
 
 
383
 
}
384
 
 
385
 
void
386
 
NetConnection::attachNetConnectionInterface(as_object& o)
387
 
{
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));
392
 
 
393
 
}
394
 
 
395
 
void
396
 
NetConnection::attachProperties()
397
 
{
398
 
        boost::intrusive_ptr<builtin_function> gettersetter;
399
 
 
400
 
        gettersetter = new builtin_function(NetConnection::isConnected_getset, NULL);
401
 
        init_property("isConnected", *gettersetter, *gettersetter);
402
 
 
403
 
        gettersetter = new builtin_function(NetConnection::uri_getset, NULL);
404
 
        init_property("uri", *gettersetter, *gettersetter);
405
 
 
406
 
}
407
 
 
408
 
as_object*
409
 
NetConnection::getNetConnectionInterface()
410
 
{
411
 
 
412
 
        static boost::intrusive_ptr<as_object> o;
413
 
        if ( o == NULL )
414
 
        {
415
 
                o = new as_object(getObjectInterface());
416
 
                NetConnection::attachNetConnectionInterface(*o);
417
 
        }
418
 
 
419
 
        return o.get();
420
 
}
421
 
 
422
 
void
423
 
NetConnection::registerConstructor(as_object& global)
424
 
{
425
 
 
426
 
        // This is going to be the global NetConnection "class"/"function"
427
 
        static boost::intrusive_ptr<builtin_function> cl;
428
 
 
429
 
        if ( cl == NULL )
430
 
        {
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);
436
 
                     
437
 
        }
438
 
 
439
 
        // Register _global.String
440
 
        global.init_member("NetConnection", cl.get());
441
 
 
442
 
}
443
 
 
444
 
// extern (used by Global.cpp)
445
 
void netconnection_class_init(as_object& global)
446
 
{
447
 
        NetConnection::registerConstructor(global);
448
 
}
449
 
 
450
 
 
451
 
} // end of gnash namespace
452