gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] /srv/bzr/gnash/trunk r11025: merge from rtmp branch, im


From: rob
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r11025: merge from rtmp branch, improvements to libamf & libnet, plus test cases.
Date: Sun, 07 Jun 2009 15:14:22 -0600
User-agent: Bazaar (1.13.1)

------------------------------------------------------------
revno: 11025
committer: address@hidden
branch nick: trunk
timestamp: Sun 2009-06-07 15:14:22 -0600
message:
  merge from rtmp branch, improvements to libamf & libnet, plus test cases.
added:
  cygnal/cgi-bin/
  cygnal/cgi-bin/Makefile.am
  cygnal/cgi-bin/echo/
  cygnal/cgi-bin/echo/Makefile.am
  cygnal/cgi-bin/echo/echo.cpp
  cygnal/cgi-bin/echo/echo.h
  cygnal/cgi-bin/echo/gateway.cpp
  cygnal/cgi-bin/echo/gateway.h
  cygnal/http_server.cpp
  cygnal/http_server.h
  cygnal/proc.cpp
  cygnal/proc.h
  testsuite/network.all/
  testsuite/network.all/Dejagnu.c
  testsuite/network.all/Makefile.am
  testsuite/network.all/http.as
  testsuite/network.all/netstream.as
  testsuite/network.all/network.exp
  testsuite/network.all/remoting.README
  testsuite/network.all/rtmp.as
renamed:
  testsuite/libbase/ => testsuite/libbase.all/
modified:
  configure.ac
  cygnal/Makefile.am
  cygnal/acinclude.m4
  cygnal/crc.cpp
  cygnal/crc.h
  cygnal/cygnal.cpp
  cygnal/cygnal.h
  cygnal/rtmp_server.cpp
  cygnal/rtmp_server.h
  cygnal/testsuite/cygnal.all/Makefile.am
  cygnal/testsuite/cygnal.exp
  libamf/amf.cpp
  libamf/amf_msg.cpp
  libamf/buffer.cpp
  libamf/element.cpp
  libbase/GC.h
  libcore/as_value.cpp
  libcore/as_value.h
  libcore/namedStrings.cpp
  libnet/cache.h
  libnet/cque.cpp
  libnet/cque.h
  libnet/diskstream.h
  libnet/http.cpp
  libnet/http.h
  libnet/network.cpp
  libnet/network.h
  libnet/rtmp.cpp
  libnet/rtmp.h
  libnet/rtmp_client.cpp
  libnet/rtmp_client.h
  libnet/rtmp_msg.cpp
  libnet/rtmp_msg.h
  testsuite/Makefile.am
  testsuite/libamf.all/test_amfmsg.cpp
  testsuite/libcore.all/AsValueTest.cpp
  testsuite/libnet.all/test_http.cpp
  testsuite/libnet.all/test_rtmp.cpp
  testsuite/misc-ming.all/Makefile.am
  testsuite/misc-ming.all/red5test.as
    ------------------------------------------------------------
    revno: 9483.4.333
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-02-21 08:37:21 -0700
    message:
      big merge from trunk. Add cygnal/cgi-bin directory.
    removed:
      po/sv.po
    added:
      cygnal/cgi-bin/
      cygnal/cgi-bin/Makefile.am
      cygnal/cgi-bin/echo/
      cygnal/cgi-bin/echo/Makefile.am
      cygnal/cgi-bin/echo/echo.cpp
      cygnal/cgi-bin/echo/echo.h
      cygnal/cgi-bin/echo/gateway.cpp
      cygnal/cgi-bin/echo/gateway.h
      libbase/NamingPolicy.cpp
      libbase/NamingPolicy.h
      packaging/redhat/klash.spec
    modified:
      Makefile.am
      configure.ac
      cygnal/Makefile.am
      cygnal/cvm.cpp
      cygnal/testsuite/cygnal.exp
      gui/Kde4Gui.cpp
      gui/Kde4Gui.h
      gui/Player.cpp
      gui/Player.h
      gui/fltk.cpp
      gui/fltksup.h
      gui/gnash.cpp
      gui/gtk.cpp
      gui/gtk_glue.h
      gui/gtk_glue_agg.cpp
      gui/gtk_glue_agg.h
      gui/gtksup.h
      gui/gui.cpp
      gui/gui.h
      gui/kde.cpp
      gui/kdesup.h
      gui/klash3.moc.in
      gui/klash4.moc.in
      libamf/amf.cpp
      libamf/buffer.cpp
      libamf/element.cpp
      libbase/GnashImage.h
      libbase/IOChannel.cpp
      libbase/IOChannel.h
      libbase/Makefile.am
      libbase/curl_adapter.cpp
      libbase/log.h
      libbase/noseek_fd_adapter.cpp
      libbase/rc.cpp
      libbase/rc.h
      libbase/tu_file.cpp
      libbase/tu_file.h
      libbase/zlib_adapter.cpp
      libcore/CharacterProxy.h
      libcore/DisplayList.cpp
      libcore/Font.cpp
      libcore/Font.h
      libcore/LoadVariablesThread.cpp
      libcore/LoadVariablesThread.h
      libcore/MovieClip.cpp
      libcore/Property.cpp
      libcore/PropertyList.cpp
      libcore/PropertyList.h
      libcore/RunInfo.h
      libcore/SWFStream.cpp
      libcore/StreamProvider.cpp
      libcore/StreamProvider.h
      libcore/TextField.cpp
      libcore/as_function.cpp
      libcore/as_object.cpp
      libcore/as_object.h
      libcore/as_value.h
      libcore/asobj/ClassHierarchy.cpp
      libcore/asobj/Global.cpp
      libcore/asobj/LoadVars_as.cpp
      libcore/asobj/LoadableObject.cpp
      libcore/asobj/Math_as.cpp
      libcore/asobj/NetConnection_as.cpp
      libcore/asobj/NetStream_as.cpp
      libcore/asobj/Object.cpp
      libcore/asobj/SharedObject_as.cpp
      libcore/asobj/Sound_as.cpp
      libcore/asobj/XMLSocket_as.cpp
      libcore/impl.cpp
      libcore/movie_root.cpp
      libcore/movie_root.h
      libcore/parser/SWFMovieDefinition.cpp
      libcore/parser/SWFMovieDefinition.h
      libcore/parser/character_def.cpp
      libcore/parser/character_def.h
      libcore/swf/TextRecord.cpp
      libcore/swf/tag_loaders.cpp
      libcore/swf_function.cpp
      libcore/vm/ASHandlers.cpp
      libcore/vm/ExecutableCode.h
      libcore/vm/Machine.cpp
      libcore/vm/action.cpp
      libcore/vm/fn_call.h
      libmedia/FLVParser.cpp
      libmedia/ffmpeg/AudioDecoderFfmpeg.cpp
      libmedia/ffmpeg/MediaParserFfmpeg.cpp
      libmedia/gst/AudioDecoderGst.cpp
      libmedia/gst/MediaParserGst.cpp
      libmedia/gst/VideoDecoderGst.cpp
      libnet/diskstream.cpp
      libnet/http.cpp
      libnet/http.h
      libnet/network.cpp
      libnet/rtmp.cpp
      libnet/rtmp.h
      libsound/EmbedSoundInst.cpp
      macros/kde3.m4
      macros/kde4.m4
      packaging/deb.am
      packaging/debian/changelog
      packaging/debian/control
      packaging/debian/gnash-klash.install
      packaging/debian/klash.install
      packaging/debian/klash.links
      packaging/debian/konqueror-plugin-gnash.install
      packaging/debian/mozilla-plugin-gnash.install
      packaging/debian/mozilla-plugin-gnash.postinst
      packaging/debian/mozilla-plugin-gnash.prerm
      packaging/debian/rules
      packaging/redhat/gnash.spec
      packaging/rpm.am
      packaging/snapshot.am
      packaging/xpi.am
      packaging/xpi/install.rdf
      packaging/xpi/update.rdf
      plugin/Makefile.am
      plugin/plugin.cpp
      po/Makefile.am
      po/cs.po
      po/de.po
      po/es.po
      po/fi.po
      po/fr.po
      po/gnash.pot
      po/it.po
      po/ja.po
      testsuite/MovieTester.cpp
      testsuite/MovieTester.h
      testsuite/libamf.all/test_amf.cpp
      testsuite/libbase/CurlStreamTest.cpp
      testsuite/libcore.all/PropertyListTest.cpp
      testsuite/libcore.all/StreamTest.cpp
      testsuite/libnet.all/Makefile.am
      testsuite/libnet.all/test_diskstream.cpp
      testsuite/libnet.all/test_rtmp.cpp
      utilities/flvdumper.cpp
      utilities/processor.cpp
    ------------------------------------------------------------
    revno: 9483.4.334
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-02-21 08:38:43 -0700
    message:
      new class for starting cgi-bins.
    added:
      cygnal/proc.cpp
      cygnal/proc.h
    ------------------------------------------------------------
    revno: 9483.4.335
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-02-21 10:34:03 -0700
    message:
      read echo request from a file or the network, and send a correct response.
    modified:
      cygnal/cgi-bin/echo/gateway.cpp
    ------------------------------------------------------------
    revno: 9483.4.336
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-02-21 11:53:46 -0700
    message:
      cleanup code, add CGI to all method names to be clearer what it is.
    modified:
      cygnal/proc.cpp
      cygnal/proc.h
    ------------------------------------------------------------
    revno: 9483.4.337
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-02-21 11:55:04 -0700
    message:
      split the server side of HTTP support into it's own class in Cygnal, so 
we can support CGI bins easier.
    added:
      cygnal/http_server.cpp
      cygnal/http_server.h
    ------------------------------------------------------------
    revno: 9483.4.338
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-02-21 11:55:44 -0700
    message:
      make less verbose.
    modified:
      cygnal/cgi-bin/echo/gateway.cpp
    ------------------------------------------------------------
    revno: 9483.4.339
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-02-21 11:56:32 -0700
    message:
      add http_server.* to libcygnal.
    modified:
      cygnal/Makefile.am
    ------------------------------------------------------------
    revno: 9483.4.340
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-02-21 11:57:24 -0700
    message:
      http.h now needs to be http_server.h.
    modified:
      cygnal/cygnal.cpp
    ------------------------------------------------------------
    revno: 9483.4.341
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-02-21 12:15:45 -0700
    message:
      get rid of extraneous newline in text field.
    modified:
      cygnal/rtmp_server.cpp
    ------------------------------------------------------------
    revno: 9483.4.342
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-02-21 12:16:22 -0700
    message:
      seperate out the server side HTTP support into it's own class in Cygnal.
    modified:
      libnet/http.cpp
      libnet/http.h
    ------------------------------------------------------------
    revno: 9483.4.343
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-02-21 12:17:04 -0700
    message:
      don't try to build the cgi bins before libcygnal is built.
    modified:
      cygnal/Makefile.am
    ------------------------------------------------------------
    revno: 9483.4.344
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-02-21 16:06:16 -0700
    message:
      use an external program over a network connect to process the data in the 
POST.
    modified:
      cygnal/http_server.cpp
    ------------------------------------------------------------
    revno: 9483.4.345
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-02-21 16:07:18 -0700
    message:
      always start the cgi application in verbose mode.
    modified:
      cygnal/proc.cpp
    ------------------------------------------------------------
    revno: 9483.4.346
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-02-21 16:08:01 -0700
    message:
      don't try to remove a pollfd from a bogus hit.
    modified:
      cygnal/cygnal.cpp
    ------------------------------------------------------------
    revno: 9483.4.347
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-02-21 16:08:40 -0700
    message:
      properly handle closing the network connection.
    modified:
      cygnal/cgi-bin/echo/gateway.cpp
    ------------------------------------------------------------
    revno: 9483.4.348
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-02-21 16:09:10 -0700
    message:
      build proc.cpp as part of libcygnal, not cygnal itself.
    modified:
      cygnal/Makefile.am
    ------------------------------------------------------------
    revno: 9483.4.349
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-02-21 17:38:59 -0700
    message:
      move enable-cgibins to cygnal specific configure file..
    modified:
      configure.ac
      cygnal/acinclude.m4
    ------------------------------------------------------------
    revno: 9483.4.350
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-02-21 17:39:23 -0700
    message:
      don'
    modified:
      libnet/network.cpp
    ------------------------------------------------------------
    revno: 9483.4.351
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-02-21 17:40:02 -0700
    message:
      get the docroot from private data.
    modified:
      libnet/http.h
    ------------------------------------------------------------
    revno: 9483.4.352
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-02-21 17:41:45 -0700
    message:
      use the docoot to find cgi files.
    modified:
      cygnal/proc.cpp
      cygnal/proc.h
    ------------------------------------------------------------
    revno: 9483.4.353
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-02-21 17:42:32 -0700
    message:
      exit if there are errors creating a server connection.
    modified:
      cygnal/cgi-bin/echo/gateway.cpp
    ------------------------------------------------------------
    revno: 9483.4.354
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-02-21 17:43:24 -0700
    message:
      execute an external progam when specified.
    modified:
      cygnal/http_server.cpp
    ------------------------------------------------------------
    revno: 9483.4.355
    committer: address@hidden
    branch nick: rtmp
    timestamp: Mon 2009-03-16 16:14:53 -0600
    message:
      merge from trunk
    modified:
      cygnal/acinclude.m4
      cygnal/crc.h
      cygnal/cygnal.cpp
      cygnal/cygnal.h
      cygnal/http_server.cpp
      cygnal/http_server.h
      cygnal/rtmp_server.h
      libnet/cache.h
      libnet/cque.h
      libnet/diskstream.h
      libnet/http.h
      libnet/rtmp.h
      libnet/rtmp_client.h
      libnet/rtmp_msg.h
        ------------------------------------------------------------
        revno: 9483.10.1
        committer: Markus Gothe <address@hidden>
        branch nick: rtmp
        timestamp: Sun 2009-02-22 02:41:59 +0100
        message:
          fix visibility attribute for RTMP branch / Cygnal
        modified:
          cygnal/cygnal.h
          cygnal/http_server.cpp
          cygnal/http_server.h
          cygnal/rtmp_server.h
          libnet/cache.h
          libnet/cque.h
          libnet/diskstream.h
          libnet/http.h
        ------------------------------------------------------------
        revno: 9483.10.2
        committer: Markus Gothe <address@hidden>
        branch nick: rtmp
        timestamp: Mon 2009-02-23 02:25:09 +0100
        message:
          Cleaned up DSOEXPORTS
        modified:
          libnet/diskstream.h
          libnet/http.h
          libnet/rtmp.h
          libnet/rtmp_client.h
          libnet/rtmp_msg.h
        ------------------------------------------------------------
        revno: 9483.10.3
        committer: Markus Gothe <address@hidden>
        branch nick: rtmp
        timestamp: Mon 2009-02-23 02:30:57 +0100
        message:
          Cleaned up DSOEXPORTS
        modified:
          cygnal/crc.h
          cygnal/http_server.h
          cygnal/rtmp_server.h
        ------------------------------------------------------------
        revno: 9483.10.4
        committer: Markus Gothe <address@hidden>
        branch nick: rtmp
        timestamp: Mon 2009-02-23 02:33:06 +0100
        message:
          Cleaned up DSOEXPORTS
        modified:
          cygnal/cygnal.h
        ------------------------------------------------------------
        revno: 9483.10.5
        committer: Markus Gothe <address@hidden>
        branch nick: rtmp
        timestamp: Mon 2009-02-23 02:36:17 +0100
        message:
          Cleaned up DSOEXPORTS
        modified:
          libnet/http.h
        ------------------------------------------------------------
        revno: 9483.10.6
        committer: Benjamin Wolsey <address@hidden>
        branch nick: rtmp
        timestamp: Wed 2009-02-25 10:17:19 +0100
        message:
          Wrap all macros in AC_DEFUN, or autogen.sh fails (at least on 
Mandriva 2009).
        modified:
          cygnal/acinclude.m4
        ------------------------------------------------------------
        revno: 9483.10.7
        committer: Markus Gothe <address@hidden>
        branch nick: rtmp
        timestamp: Wed 2009-03-04 00:47:47 +0100
        message:
          Updated copyright info
        modified:
          cygnal/acinclude.m4
          cygnal/cygnal.cpp
    ------------------------------------------------------------
    revno: 9483.4.356
    committer: address@hidden
    branch nick: rtmp
    timestamp: Mon 2009-03-16 16:40:24 -0600
    message:
      add setting for the root directory for cgis.
    modified:
      cygnal/crc.cpp
      cygnal/crc.h
    ------------------------------------------------------------
    revno: 9483.4.357
    committer: address@hidden
    branch nick: rtmp
    timestamp: Mon 2009-03-16 16:43:53 -0600
    message:
      moved to Cygnal directory
    removed:
      testsuite/libnet.all/amf0-boolean.bin
      testsuite/libnet.all/amf0-null-object.bin
      testsuite/libnet.all/amf0-null-string.bin
      testsuite/libnet.all/amf0-number.bin
      testsuite/libnet.all/amf0-string.bin
      testsuite/libnet.all/amf0-undefined-object.bin
      testsuite/libnet.all/amf0-unsupported-object.bin
      testsuite/libnet.all/ecma-array.bin
      testsuite/libnet.all/object1.bin
      testsuite/libnet.all/strict-array.bin
    ------------------------------------------------------------
    revno: 9483.4.358
    committer: address@hidden
    branch nick: rtmp
    timestamp: Mon 2009-03-16 16:44:59 -0600
    message:
      get the root directory for cgi-bins.
    modified:
      cygnal/proc.cpp
    ------------------------------------------------------------
    revno: 9483.4.359
    committer: address@hidden
    branch nick: rtmp
    timestamp: Mon 2009-03-16 16:46:54 -0600
    message:
      return a Buffer instead of a bool when processing requests.
    modified:
      cygnal/http_server.cpp
      cygnal/http_server.h
    ------------------------------------------------------------
    revno: 9483.4.360
    committer: address@hidden
    branch nick: rtmp
    timestamp: Mon 2009-03-16 16:48:07 -0600
    message:
      better comments.
    modified:
      cygnal/cygnal.cpp
    ------------------------------------------------------------
    revno: 9483.4.361
    committer: address@hidden
    branch nick: rtmp
    timestamp: Mon 2009-03-16 16:49:57 -0600
    message:
      add option to enable building cgi bins.
    modified:
      configure.ac
    ------------------------------------------------------------
    revno: 9483.4.362
    committer: address@hidden
    branch nick: rtmp
    timestamp: Mon 2009-03-16 17:34:13 -0600
    message:
      big merge from trunk, copyright changes, release stuff, etc...
    removed:
      libcore/generic_character.cpp
      libcore/generic_character.h
      libcore/shape.h
    added:
      gui/gtk_glue_agg_xv.cpp
      gui/gtk_glue_agg_xv.h
      libamf/amf_msg.cpp
      libamf/amf_msg.h
      libbase/GnashAlgorithm.h
      libcore/DisplayObject.cpp
      libcore/DisplayObject.h
      libcore/Geometry.h
      libcore/Shape.cpp
      libcore/Shape.h
      libcore/StaticText.cpp
      libcore/StaticText.h
      libmedia/VideoConverter.h
      libmedia/ffmpeg/VideoConverterFfmpeg.cpp
      libmedia/ffmpeg/VideoConverterFfmpeg.h
      libmedia/gst/VideoConverterGst.cpp
      libmedia/gst/VideoConverterGst.h
      testsuite/libamf.all/test_amfmsg.cpp
      testsuite/misc-ming.all/TextSnapshotTest.c
    modified:
      INSTALL
      Makefile.am
      autogen.sh
      backend/PathParser.cpp
      backend/PathParser.h
      backend/render_handler.h
      backend/render_handler_agg.cpp
      backend/render_handler_agg.h
      backend/render_handler_agg_bitmap.h
      backend/render_handler_cairo.cpp
      backend/render_handler_cairo.h
      backend/render_handler_ogl.cpp
      configure.ac
      cygnal/Makefile.am
      cygnal/acinclude.m4
      cygnal/alloc.cpp
      cygnal/cgi-bin/echo/Makefile.am
      cygnal/cgi-bin/echo/echo.cpp
      cygnal/cgi-bin/echo/echo.h
      cygnal/cgi-bin/echo/gateway.cpp
      cygnal/cgi-bin/echo/gateway.h
      cygnal/crc.cpp
      cygnal/crc.h
      cygnal/cvm.cpp
      cygnal/http_server.cpp
      cygnal/http_server.h
      cygnal/rtmp_server.cpp
      cygnal/testsuite/Makefile.am
      cygnal/testsuite/cygnal.all/Makefile.am
      cygnal/testsuite/cygnal.all/test_crc.cpp
      cygnal/testsuite/cygnal.exp
      depcomp
      devtools/lib/Gnash/Distribution.pm
      devtools/lib/Gnash/Utils.pm
      devtools/testsuite/c_casts.t
      devtools/testsuite/copyright_notices.t
      devtools/testsuite/tabs.t
      devtools/testsuite/uncuddled_else.t
      doc/C/COPYING-DOC
      doc/C/Makefile.am
      doc/C/gen-doc.sh
      doc/C/preformatted/gnash_user.info.in
      doc/C/preformatted/gnashref.html.in
      doc/C/usermanual/gnashrc.xml
      doc/Makefile.am
      extensions/Makefile.am
      extensions/dbus/Makefile.am
      extensions/dbus/dbus_ext.cpp
      extensions/dejagnu/Makefile.am
      extensions/dejagnu/dejagnu.cpp
      extensions/dejagnu/dejagnu.h
      extensions/dejagnu/test.as
      extensions/fileio/Makefile.am
      extensions/fileio/fileio.cpp
      extensions/fileio/fileio.h
      extensions/fileio/test.as
      extensions/gtk2/Makefile.am
      extensions/gtk2/gtkext.cpp
      extensions/gtk2/gtkext.h
      extensions/gtk2/hello.as
      extensions/launcher/Makefile.am
      extensions/launcher/launcher.cpp
      extensions/launcher/launcher_ext.cpp
      extensions/launcher/launcher_ext.h
      extensions/launcher/md5.cpp
      extensions/launcher/md5.h
      extensions/launcher/test.as
      extensions/lirc/Makefile.am
      extensions/lirc/lirc_ext.cpp
      extensions/lirc/lirc_ext.h
      extensions/lirc/test.as
      extensions/metome/Makefile.am
      extensions/metome/metome_ext.cpp
      extensions/metome/metome_ext.h
      extensions/mysql/Makefile.am
      extensions/mysql/mysql_db.cpp
      extensions/mysql/mysql_db.h
      extensions/mysql/mysql_table.cpp
      extensions/mysql/test.as
      gui/GuiKde4.cpp
      gui/Kde4Glue.h
      gui/Kde4GlueAgg.cpp
      gui/Kde4GlueAgg.h
      gui/Kde4Gui.cpp
      gui/Makefile.am
      gui/NullGui.cpp
      gui/NullGui.h
      gui/Player.h
      gui/am-frag/alp.am
      gui/am-frag/aqua.am
      gui/am-frag/dump.am
      gui/am-frag/fb.am
      gui/am-frag/fltk.am
      gui/am-frag/gtk.am
      gui/am-frag/hildon.am
      gui/am-frag/kde3.am
      gui/am-frag/kde4.am
      gui/am-frag/qtopia3.am
      gui/am-frag/riscos.am
      gui/am-frag/sdl.am
      gui/aqua.cpp
      gui/aqua_glue.h
      gui/aqua_ogl_glue.cpp
      gui/aqua_ogl_glue.h
      gui/aquasup.h
      gui/dump.cpp
      gui/dump.h
      gui/fb.cpp
      gui/fbsup.h
      gui/fltk.cpp
      gui/fltk_glue_agg.cpp
      gui/fltk_glue_agg.h
      gui/fltk_glue_cairo.cpp
      gui/fltk_glue_cairo.h
      gui/fltksup.h
      gui/gnash.cpp
      gui/gnash.in
      gui/gtk.cpp
      gui/gtk_glue.h
      gui/gtk_glue_agg.cpp
      gui/gtk_glue_agg.h
      gui/gtk_glue_cairo.cpp
      gui/gtk_glue_cairo.h
      gui/gtk_glue_gtkglext.cpp
      gui/gtk_glue_gtkglext.h
      gui/gui.cpp
      gui/gui.h
      gui/gui_aqua.cpp
      gui/gui_dump.cpp
      gui/gui_fb.cpp
      gui/gui_fltk.cpp
      gui/gui_gtk.cpp
      gui/gui_kde.cpp
      gui/gui_riscos.cpp
      gui/gui_sdl.cpp
      gui/kde.cpp
      gui/kde_glue.h
      gui/kde_glue_agg.cpp
      gui/kde_glue_agg.h
      gui/kde_glue_opengl.cpp
      gui/kde_glue_opengl.h
      gui/kdesup.h
      gui/riscos.cpp
      gui/riscos_glue.h
      gui/riscos_glue_agg.cpp
      gui/riscos_glue_agg.h
      gui/riscossup.h
      gui/sdl.cpp
      gui/sdl_agg_glue.cpp
      gui/sdl_agg_glue.h
      gui/sdl_cairo_glue.cpp
      gui/sdl_cairo_glue.h
      gui/sdl_glue.h
      gui/sdl_ogl_glue.cpp
      gui/sdl_ogl_glue.h
      gui/sdlsup.h
      libamf/Makefile.am
      libamf/amf.cpp
      libamf/amf.h
      libamf/amftest.cpp
      libamf/amfutf8.h
      libamf/buffer.cpp
      libamf/buffer.h
      libamf/element.cpp
      libamf/element.h
      libamf/flv.cpp
      libamf/flv.h
      libamf/lcshm.cpp
      libamf/lcshm.h
      libamf/protocol.h
      libamf/sol.cpp
      libamf/sol.h
      libbase/BitsReader.cpp
      libbase/BitsReader.h
      libbase/ClockTime.cpp
      libbase/ClockTime.h
      libbase/GC.cpp
      libbase/GC.h
      libbase/GnashException.h
      libbase/GnashImage.cpp
      libbase/GnashImage.h
      libbase/GnashImageGif.cpp
      libbase/GnashImageGif.h
      libbase/GnashImageJpeg.cpp
      libbase/GnashImageJpeg.h
      libbase/GnashImagePng.cpp
      libbase/GnashImagePng.h
      libbase/GnashSleep.h
      libbase/IOChannel.cpp
      libbase/IOChannel.h
      libbase/LoadThread.cpp
      libbase/LoadThread.h
      libbase/Makefile.am
      libbase/NetworkAdapter.h
      libbase/Point2d.h
      libbase/Range2d.h
      libbase/SimpleBuffer.h
      libbase/URL.cpp
      libbase/URL.h
      libbase/WallClockTimer.cpp
      libbase/WallClockTimer.h
      libbase/arg_parser.cpp
      libbase/arg_parser.h
      libbase/curl_adapter.cpp
      libbase/dsodefs.h
      libbase/extension.cpp
      libbase/extension.h
      libbase/getclocktime.hpp
      libbase/gettext.h
      libbase/gmemory.h
      libbase/gnashrc.in
      libbase/lirc.h
      libbase/log.cpp
      libbase/log.h
      libbase/memory.cpp
      libbase/noseek_fd_adapter.cpp
      libbase/noseek_fd_adapter.h
      libbase/rc.cpp
      libbase/rc.h
      libbase/ref_counted.h
      libbase/sharedlib.cpp
      libbase/sharedlib.h
      libbase/shm.cpp
      libbase/shm.h
      libbase/smart_ptr.h
      libbase/snappingrange.h
      libbase/string_table.cpp
      libbase/string_table.h
      libbase/utf8.cpp
      libbase/utf8.h
      libbase/utility.h
      libcore/BevelFilter.cpp
      libcore/BevelFilter.h
      libcore/Bitmap.cpp
      libcore/Bitmap.h
      libcore/BitmapFilter.h
      libcore/BitmapInfo.h
      libcore/BitmapMovieInstance.cpp
      libcore/BitmapMovieInstance.h
      libcore/BlurFilter.cpp
      libcore/BlurFilter.h
      libcore/Button.cpp
      libcore/Button.h
      libcore/CharacterProxy.cpp
      libcore/CharacterProxy.h
      libcore/ColorMatrixFilter.cpp
      libcore/ColorMatrixFilter.h
      libcore/ConvolutionFilter.cpp
      libcore/ConvolutionFilter.h
      libcore/DisplayList.cpp
      libcore/DisplayList.h
      libcore/DropShadowFilter.cpp
      libcore/DropShadowFilter.h
      libcore/DynamicShape.cpp
      libcore/DynamicShape.h
      libcore/ExportableResource.h
      libcore/Font.cpp
      libcore/Font.h
      libcore/FreetypeGlyphsProvider.cpp
      libcore/FreetypeGlyphsProvider.h
      libcore/GlowFilter.cpp
      libcore/GlowFilter.h
      libcore/GnashKey.h
      libcore/GradientBevelFilter.cpp
      libcore/GradientBevelFilter.h
      libcore/GradientGlowFilter.cpp
      libcore/GradientGlowFilter.h
      libcore/LoadVariablesThread.cpp
      libcore/LoadVariablesThread.h
      libcore/Makefile.am
      libcore/ManualClock.h
      libcore/MovieClip.cpp
      libcore/MovieClip.h
      libcore/Property.cpp
      libcore/Property.h
      libcore/PropertyList.cpp
      libcore/RGBA.h
      libcore/RunInfo.h
      libcore/SWFMatrix.cpp
      libcore/SWFMatrix.h
      libcore/Sprite.h
      libcore/StreamProvider.cpp
      libcore/StreamProvider.h
      libcore/StringPredicates.h
      libcore/SystemClock.cpp
      libcore/SystemClock.h
      libcore/TextField.cpp
      libcore/TextField.h
      libcore/URLAccessManager.cpp
      libcore/URLAccessManager.h
      libcore/VirtualClock.h
      libcore/asClass.cpp
      libcore/asClass.h
      libcore/as_environment.cpp
      libcore/as_environment.h
      libcore/as_function.cpp
      libcore/as_function.h
      libcore/as_prop_flags.h
      libcore/asobj/Accessibility_as.cpp
      libcore/asobj/Accessibility_as.h
      libcore/asobj/Array_as.h
      libcore/asobj/AsBroadcaster.cpp
      libcore/asobj/Boolean_as.cpp
      libcore/asobj/Boolean_as.h
      libcore/asobj/Camera.cpp
      libcore/asobj/Camera.h
      libcore/asobj/ClassHierarchy.cpp
      libcore/asobj/ClassHierarchy.h
      libcore/asobj/Color_as.cpp
      libcore/asobj/Color_as.h
      libcore/asobj/ContextMenu.cpp
      libcore/asobj/ContextMenu.h
      libcore/asobj/CustomActions.cpp
      libcore/asobj/CustomActions.h
      libcore/asobj/Error_as.cpp
      libcore/asobj/Error_as.h
      libcore/asobj/Global.h
      libcore/asobj/Key_as.cpp
      libcore/asobj/Key_as.h
      libcore/asobj/LoadableObject.cpp
      libcore/asobj/LoadableObject.h
      libcore/asobj/LocalConnection_as.h
      libcore/asobj/Makefile.am
      libcore/asobj/Math_as.h
      libcore/asobj/Microphone.cpp
      libcore/asobj/Microphone.h
      libcore/asobj/Mouse_as.h
      libcore/asobj/MovieClipLoader.cpp
      libcore/asobj/MovieClipLoader.h
      libcore/asobj/NetConnection_as.cpp
      libcore/asobj/NetConnection_as.h
      libcore/asobj/NetStream_as.cpp
      libcore/asobj/NetStream_as.h
      libcore/asobj/Number_as.h
      libcore/asobj/Object.h
      libcore/asobj/PlayHead.cpp
      libcore/asobj/PlayHead.h
      libcore/asobj/Selection_as.cpp
      libcore/asobj/Selection_as.h
      libcore/asobj/Sound_as.cpp
      libcore/asobj/Sound_as.h
      libcore/asobj/Stage_as.cpp
      libcore/asobj/Stage_as.h
      libcore/asobj/String_as.h
      libcore/asobj/System_as.cpp
      libcore/asobj/System_as.h
      libcore/asobj/TextFormat_as.h
      libcore/asobj/TextSnapshot_as.cpp
      libcore/asobj/TextSnapshot_as.h
      libcore/asobj/XMLSocket_as.cpp
      libcore/asobj/XMLSocket_as.h
      libcore/asobj/flash/display/BitmapData_as.cpp
      libcore/asobj/flash/display/BitmapData_as.h
      libcore/asobj/flash/display_pkg.cpp
      libcore/asobj/flash/display_pkg.h
      libcore/asobj/flash/external/ExternalInterface_as.cpp
      libcore/asobj/flash/external/ExternalInterface_as.h
      libcore/asobj/flash/external_pkg.cpp
      libcore/asobj/flash/external_pkg.h
      libcore/asobj/flash/filters/BevelFilter_as.cpp
      libcore/asobj/flash/filters/BevelFilter_as.h
      libcore/asobj/flash/filters/BitmapFilter_as.cpp
      libcore/asobj/flash/filters/BitmapFilter_as.h
      libcore/asobj/flash/filters/BlurFilter_as.cpp
      libcore/asobj/flash/filters/BlurFilter_as.h
      libcore/asobj/flash/filters/ColorMatrixFilter_as.cpp
      libcore/asobj/flash/filters/ColorMatrixFilter_as.h
      libcore/asobj/flash/filters/ConvolutionFilter_as.cpp
      libcore/asobj/flash/filters/ConvolutionFilter_as.h
      libcore/asobj/flash/filters/DisplacementMapFilter_as.cpp
      libcore/asobj/flash/filters/DisplacementMapFilter_as.h
      libcore/asobj/flash/filters/DropShadowFilter_as.cpp
      libcore/asobj/flash/filters/DropShadowFilter_as.h
      libcore/asobj/flash/filters/GlowFilter_as.cpp
      libcore/asobj/flash/filters/GlowFilter_as.h
      libcore/asobj/flash/filters/GradientBevelFilter_as.cpp
      libcore/asobj/flash/filters/GradientBevelFilter_as.h
      libcore/asobj/flash/filters/GradientGlowFilter_as.cpp
      libcore/asobj/flash/filters/GradientGlowFilter_as.h
      libcore/asobj/flash/filters_pkg.cpp
      libcore/asobj/flash/filters_pkg.h
      libcore/asobj/flash/geom/ColorTransform_as.cpp
      libcore/asobj/flash/geom/ColorTransform_as.h
      libcore/asobj/flash/geom/Matrix_as.cpp
      libcore/asobj/flash/geom/Matrix_as.h
      libcore/asobj/flash/geom/Point_as.cpp
      libcore/asobj/flash/geom/Point_as.h
      libcore/asobj/flash/geom/Rectangle_as.cpp
      libcore/asobj/flash/geom/Rectangle_as.h
      libcore/asobj/flash/geom/Transform_as.cpp
      libcore/asobj/flash/geom/Transform_as.h
      libcore/asobj/flash/geom_pkg.cpp
      libcore/asobj/flash/geom_pkg.h
      libcore/asobj/flash/net/FileReferenceList_as.cpp
      libcore/asobj/flash/net/FileReferenceList_as.h
      libcore/asobj/flash/net/FileReference_as.cpp
      libcore/asobj/flash/net/FileReference_as.h
      libcore/asobj/flash/net_pkg.cpp
      libcore/asobj/flash/net_pkg.h
      libcore/asobj/flash/text/TextRenderer_as.cpp
      libcore/asobj/flash/text/TextRenderer_as.h
      libcore/asobj/flash/text_pkg.cpp
      libcore/asobj/flash/text_pkg.h
      libcore/asobj/flash_pkg.cpp
      libcore/asobj/flash_pkg.h
      libcore/asobj/gen-asclass.pl
      libcore/asobj/prophelper.h
      libcore/builtin_function.h
      libcore/character.cpp
      libcore/character.h
      libcore/cxform.h
      libcore/debugger.cpp
      libcore/debugger.h
      libcore/drag_state.h
      libcore/event_id.h
      libcore/fill_style.cpp
      libcore/fill_style.h
      libcore/fontlib.h
      libcore/movie_instance.cpp
      libcore/movie_instance.h
      libcore/movie_root.cpp
      libcore/movie_root.h
      libcore/namedStrings.cpp
      libcore/namedStrings.h
      libcore/parser/BitmapMovieDefinition.cpp
      libcore/parser/BitmapMovieDefinition.h
      libcore/parser/Makefile.am
      libcore/parser/Namespace.h
      libcore/parser/SWFMovieDefinition.cpp
      libcore/parser/SWFMovieDefinition.h
      libcore/parser/abc_block.cpp
      libcore/parser/abc_block.h
      libcore/parser/action_buffer.cpp
      libcore/parser/character_def.cpp
      libcore/parser/character_def.h
      libcore/parser/filter_factory.cpp
      libcore/parser/filter_factory.h
      libcore/parser/morph2_character_def.cpp
      libcore/parser/morph2_character_def.h
      libcore/parser/movie_definition.h
      libcore/parser/shape_character_def.cpp
      libcore/parser/shape_character_def.h
      libcore/parser/sound_definition.h
      libcore/parser/sprite_definition.cpp
      libcore/parser/sprite_definition.h
      libcore/rect.cpp
      libcore/rect.h
      libcore/swf.cpp
      libcore/swf/ControlTag.h
      libcore/swf/DefineButtonTag.cpp
      libcore/swf/DefineButtonTag.h
      libcore/swf/DefineEditTextTag.cpp
      libcore/swf/DefineEditTextTag.h
      libcore/swf/DefineFontAlignZonesTag.cpp
      libcore/swf/DefineFontTag.cpp
      libcore/swf/DefineTextTag.cpp
      libcore/swf/DefineTextTag.h
      libcore/swf/DefineVideoStreamTag.cpp
      libcore/swf/DefineVideoStreamTag.h
      libcore/swf/PlaceObject2Tag.cpp
      libcore/swf/SoundInfoRecord.cpp
      libcore/swf/SoundInfoRecord.h
      libcore/swf/TextRecord.cpp
      libcore/swf/TextRecord.h
      libcore/swf/tag_loaders.cpp
      libcore/swf_event.h
      libcore/swf_function.cpp
      libcore/swf_function.h
      libcore/timers.cpp
      libcore/timers.h
      libcore/vm/ASHandlers.cpp
      libcore/vm/ASHandlers.h
      libcore/vm/CallStack.h
      libcore/vm/CodeStream.h
      libcore/vm/ExecutableCode.h
      libcore/vm/Machine.cpp
      libcore/vm/Machine.h
      libcore/vm/Makefile.am
      libcore/vm/SafeStack.h
      libcore/vm/VM.cpp
      libcore/vm/action.cpp
      libcore/vm/action.h
      libcore/vm/asName.h
      libcore/vm/fn_call.h
      libcore/vm/with_stack_entry.h
      libmedia/AudioDecoder.h
      libmedia/AudioDecoderNellymoser.h
      libmedia/AudioDecoderSimple.cpp
      libmedia/AudioDecoderSimple.h
      libmedia/AudioDecoderSpeex.cpp
      libmedia/AudioDecoderSpeex.h
      libmedia/AudioResampler.cpp
      libmedia/AudioResampler.h
      libmedia/FLVParser.cpp
      libmedia/FLVParser.h
      libmedia/Makefile.am
      libmedia/MediaHandler.h
      libmedia/MediaParser.cpp
      libmedia/SoundInfo.h
      libmedia/VideoDecoder.h
      libmedia/ffmpeg/AudioDecoderFfmpeg.cpp
      libmedia/ffmpeg/AudioDecoderFfmpeg.h
      libmedia/ffmpeg/AudioResamplerFfmpeg.cpp
      libmedia/ffmpeg/AudioResamplerFfmpeg.h
      libmedia/ffmpeg/MediaHandlerFfmpeg.cpp
      libmedia/ffmpeg/MediaHandlerFfmpeg.h
      libmedia/ffmpeg/MediaParserFfmpeg.cpp
      libmedia/ffmpeg/MediaParserFfmpeg.h
      libmedia/ffmpeg/VideoDecoderFfmpeg.cpp
      libmedia/ffmpeg/VideoDecoderFfmpeg.h
      libmedia/ffmpeg/ffmpegHeaders.h
      libmedia/gst/AudioDecoderGst.cpp
      libmedia/gst/AudioDecoderGst.h
      libmedia/gst/GstUtil.cpp
      libmedia/gst/GstUtil.h
      libmedia/gst/MediaHandlerGst.cpp
      libmedia/gst/MediaHandlerGst.h
      libmedia/gst/MediaParserGst.cpp
      libmedia/gst/MediaParserGst.h
      libmedia/gst/VideoDecoderGst.cpp
      libmedia/gst/VideoDecoderGst.h
      libmedia/gst/swfdec_codec_gst.c
      libmedia/gst/swfdec_codec_gst.h
      libnet/Makefile.am
      libnet/cache.cpp
      libnet/cache.h
      libnet/cque.cpp
      libnet/cqueue.cpp
      libnet/cqueue.h
      libnet/diskstream.cpp
      libnet/diskstream.h
      libnet/handler.cpp
      libnet/handler.h
      libnet/http.cpp
      libnet/http.h
      libnet/lirc.cpp
      libnet/lirc.h
      libnet/netstats.cpp
      libnet/netstats.h
      libnet/network.cpp
      libnet/network.h
      libnet/rtmp.cpp
      libnet/rtmp_client.cpp
      libnet/rtmp_msg.cpp
      libnet/statistics.cpp
      libnet/statistics.h
      libsound/AuxStream.h
      libsound/EmbedSound.cpp
      libsound/EmbedSound.h
      libsound/EmbedSoundInst.cpp
      libsound/EmbedSoundInst.h
      libsound/InputStream.h
      libsound/Makefile.am
      libsound/NullSoundHandler.h
      libsound/SoundEnvelope.h
      libsound/sdl/sound_handler_sdl.cpp
      libsound/sdl/sound_handler_sdl.h
      libsound/sound_handler.cpp
      libsound/sound_handler.h
      macros/agg.m4
      macros/alp.m4
      macros/archflag.m4
      macros/boost.m4
      macros/codeset.m4
      macros/curl.m4
      macros/dbus.m4
      macros/docbook.m4
      macros/ffmpeg.m4
      macros/firefox.m4
      macros/freetype.m4
      macros/gettext.m4
      macros/glib.m4
      macros/glibc2.m4
      macros/glibc21.m4
      macros/gnashpkgtool.m4
      macros/gtk2.m4
      macros/gtkglext.m4
      macros/haxe.m4
      macros/hildon.m4
      macros/iconv.m4
      macros/intdiv0.m4
      macros/intmax.m4
      macros/inttypes-pri.m4
      macros/inttypes.m4
      macros/inttypes_h.m4
      macros/isc-posix.m4
      macros/kde3.m4
      macros/kde4.m4
      macros/lcmessage.m4
      macros/lib-link.m4
      macros/lib-prefix.m4
      macros/libexe.m4
      macros/libltdl.m4
      macros/lirc.m4
      macros/longdouble.m4
      macros/longlong.m4
      macros/ming.m4
      macros/mtasc.m4
      macros/mysql.m4
      macros/nls.m4
      macros/nspr.m4
      macros/opengl.m4
      macros/pango.m4
      macros/po.m4
      macros/printf-posix.m4
      macros/progtest.m4
      macros/pthreads.m4
      macros/qt3.m4
      macros/qt4.m4
      macros/qtopia.m4
      macros/sdl.m4
      macros/signed.m4
      macros/size_max.m4
      macros/stdint_h.m4
      macros/uintmax_t.m4
      macros/ulonglong.m4
      macros/wchar_t.m4
      macros/wint_t.m4
      macros/x11.m4
      macros/xpcom.m4
      macros/xsize.m4
      missing
      packaging/Makefile.am
      packaging/alp.am
      packaging/bsd.am
      packaging/deb.am
      packaging/debian/Makefile.am
      packaging/debian/copyright
      packaging/doc/Makefile.am
      packaging/install-gnash.sh
      packaging/ipkg.am
      packaging/ipkg/Makefile.am
      packaging/redhat/Makefile.am
      packaging/rpm.am
      packaging/snapshot.am
      packaging/xpi.am
      plugin/Makefile.am
      plugin/klash/Makefile.am
      plugin/klash/klash_part.cpp
      plugin/klash/klash_part.h
      plugin/klash4/Makefile.am
      plugin/klash4/klash_part.cpp
      plugin/klash4/klash_part.h
      plugin/mozilla-sdk/Makefile.am
      plugin/mozilla-sdk/include/jni.h
      plugin/mozilla-sdk/include/jni_md.h
      plugin/mozilla-sdk/include/jri.h
      plugin/mozilla-sdk/include/jri_md.h
      plugin/mozilla-sdk/include/jritypes.h
      plugin/mozilla-sdk/include/npapi.h
      plugin/mozilla-sdk/include/nptypes.h
      plugin/mozilla-sdk/include/npupp.h
      plugin/mozilla-sdk/include/prcpucfg-glibc.h
      plugin/mozilla-sdk/include/prcpucfg-win32.h
      plugin/mozilla-sdk/include/prcpucfg.h
      plugin/mozilla-sdk/include/prcvar.h
      plugin/mozilla-sdk/include/prerr.h
      plugin/mozilla-sdk/include/prerror.h
      plugin/mozilla-sdk/include/prinit.h
      plugin/mozilla-sdk/include/prinrval.h
      plugin/mozilla-sdk/include/prlock.h
      plugin/mozilla-sdk/include/prthread.h
      plugin/mozilla-sdk/include/prtypes.h
      plugin/mozilla-sdk/include/prwin16.h
      plugin/plugin.cpp
      plugin/plugin.h
      plugin/win32/Makefile.am
      plugin/win32/npgnash.c
      plugin/win32/plugin.cpp
      plugin/win32/plugin.h
      plugin/xpcom/GnashComponent.cpp
      plugin/xpcom/GnashComponent.h
      plugin/xpcom/GnashComponentModule.cpp
      plugin/xpcom/Makefile.am
      plugin/xpcom/iGnashComponent.idl
      po/Makefile.am
      po/cs.po
      po/de.po
      pythonmodule/Makefile.am
      pythonmodule/gnashPythonExample.py
      pythonmodule/gnashpython.cpp
      pythonmodule/gnashpython.h
      pythonmodule/pyGnash.cpp
      testsuite/DummyCharacter.h
      testsuite/DummyMovieDefinition.h
      testsuite/FuzzyPixel.cpp
      testsuite/FuzzyPixel.h
      testsuite/Makefile.am
      testsuite/MovieTester.cpp
      testsuite/MovieTester.h
      testsuite/actionscript.all/Accessibility.as
      testsuite/actionscript.all/AsBroadcaster.as
      testsuite/actionscript.all/BitmapData.as
      testsuite/actionscript.all/Boolean.as
      testsuite/actionscript.all/Camera.as
      testsuite/actionscript.all/Color.as
      testsuite/actionscript.all/ColorTransform.as
      testsuite/actionscript.all/ContextMenu.as
      testsuite/actionscript.all/CustomActions.as
      testsuite/actionscript.all/Date.as
      testsuite/actionscript.all/Error.as
      testsuite/actionscript.all/ExternalInterface.as
      testsuite/actionscript.all/Function.as
      testsuite/actionscript.all/Inheritance.as
      testsuite/actionscript.all/Instance.as
      testsuite/actionscript.all/Key.as
      testsuite/actionscript.all/LoadVars.as
      testsuite/actionscript.all/LocalConnection.as
      testsuite/actionscript.all/Makefile.am
      testsuite/actionscript.all/Math.as
      testsuite/actionscript.all/Matrix.as
      testsuite/actionscript.all/Microphone.as
      testsuite/actionscript.all/Mouse.as
      testsuite/actionscript.all/MovieClip.as
      testsuite/actionscript.all/MovieClipLoader.as
      testsuite/actionscript.all/NetConnection.as
      testsuite/actionscript.all/NetStream.as
      testsuite/actionscript.all/Number.as
      testsuite/actionscript.all/Object.as
      testsuite/actionscript.all/Point.as
      testsuite/actionscript.all/Random.as
      testsuite/actionscript.all/Rectangle.as
      testsuite/actionscript.all/Selection.as
      testsuite/actionscript.all/SharedObject.as
      testsuite/actionscript.all/Sound.as
      testsuite/actionscript.all/Stage.as
      testsuite/actionscript.all/System.as
      testsuite/actionscript.all/TextField.as
      testsuite/actionscript.all/TextFormat.as
      testsuite/actionscript.all/TextSnapshot.as
      testsuite/actionscript.all/Transform.as
      testsuite/actionscript.all/Try.as
      testsuite/actionscript.all/Video.as
      testsuite/actionscript.all/XML.as
      testsuite/actionscript.all/XMLNode.as
      testsuite/actionscript.all/XMLSocket.as
      testsuite/actionscript.all/array.as
      testsuite/actionscript.all/case.as
      testsuite/actionscript.all/check.as
      testsuite/actionscript.all/dejagnu.as
      testsuite/actionscript.all/enumerate.as
      testsuite/actionscript.all/gen-test.sh
      testsuite/actionscript.all/getvariable.as
      testsuite/actionscript.all/ops.as
      testsuite/actionscript.all/rtmp.as
      testsuite/actionscript.all/rtrace.as
      testsuite/actionscript.all/setProperty.as
      testsuite/actionscript.all/swap.as
      testsuite/actionscript.all/targetPath.as
      testsuite/actionscript.all/toString_valueOf.as
      testsuite/actionscript.all/utils.as
      testsuite/actionscript.all/with.as
      testsuite/actionscript.all/xtrace.as
      testsuite/generic-testrunner.sh
      testsuite/libamf.all/Makefile.am
      testsuite/libamf.all/test_amf.cpp
      testsuite/libamf.all/test_buffer.cpp
      testsuite/libamf.all/test_el.cpp
      testsuite/libamf.all/test_flv.cpp
      testsuite/libamf.all/test_lc.cpp
      testsuite/libamf.all/test_number.cpp
      testsuite/libamf.all/test_object.cpp
      testsuite/libamf.all/test_sol.cpp
      testsuite/libamf.all/test_string.cpp
      testsuite/libamf.all/test_variable.cpp
      testsuite/libbase/CurlStreamTest.cpp
      testsuite/libbase/IntTypesTest.cpp
      testsuite/libbase/Makefile.am
      testsuite/libbase/NoSeekFileTest.cpp
      testsuite/libbase/Point2dTest.cpp
      testsuite/libbase/Range2dTest.cpp
      testsuite/libbase/TCXXRc.cpp
      testsuite/libbase/URLTest.cpp
      testsuite/libbase/gnashrc-local.in
      testsuite/libbase/gnashrc.in
      testsuite/libbase/memtest.cpp
      testsuite/libbase/snappingrangetest.cpp
      testsuite/libbase/string_tableTest.cpp
      testsuite/libcore.all/AsValueTest.cpp
      testsuite/libcore.all/BitsReaderTest.cpp
      testsuite/libcore.all/ClassSizes.cpp
      testsuite/libcore.all/DisplayListTest.cpp
      testsuite/libcore.all/EdgeTest.cpp
      testsuite/libcore.all/MatrixTest.cpp
      testsuite/libcore.all/PropertyListTest.cpp
      testsuite/libcore.all/SafeStackTest.cpp
      testsuite/libcore.all/StreamTest.cpp
      testsuite/libcore.all/as_prop_flagsTest.cpp
      testsuite/libnet.all/Makefile.am
      testsuite/libnet.all/generate_amfbins.cpp
      testsuite/libnet.all/test_cache.cpp
      testsuite/libnet.all/test_cque.cpp
      testsuite/libnet.all/test_crc.cpp
      testsuite/libnet.all/test_diskstream.cpp
      testsuite/libnet.all/test_handler.cpp
      testsuite/libnet.all/test_http.cpp
      testsuite/libnet.all/test_rtmp.cpp
      testsuite/media/Makefile.am
      testsuite/misc-haxe.all/Dejagnu.hx
      testsuite/misc-haxe.all/Makefile.am
      testsuite/misc-haxe.all/check.as
      testsuite/misc-ming.all/BitmapDataTest.c
      testsuite/misc-ming.all/ButtonEventsTest-Runner.cpp
      testsuite/misc-ming.all/ButtonEventsTest.c
      testsuite/misc-ming.all/DefineEditTextTest-Runner.cpp
      testsuite/misc-ming.all/DefineEditTextTest.c
      testsuite/misc-ming.all/DefineEditTextVariableNameTest-Runner.cpp
      testsuite/misc-ming.all/DefineEditTextVariableNameTest.c
      testsuite/misc-ming.all/DefineEditTextVariableNameTest2.c
      testsuite/misc-ming.all/DefineTextTest-Runner.cpp
      testsuite/misc-ming.all/DefineTextTest.c
      testsuite/misc-ming.all/Dejagnu.c
      testsuite/misc-ming.all/DepthLimitsTest.c
      testsuite/misc-ming.all/DragDropTestRunner.cpp
      testsuite/misc-ming.all/EmbeddedSoundTest-Runner.cpp
      testsuite/misc-ming.all/EmbeddedSoundTest.c
      testsuite/misc-ming.all/FlashVarsTest.as
      testsuite/misc-ming.all/KeyIsDownTest.c
      testsuite/misc-ming.all/LoadVarsTest.c
      testsuite/misc-ming.all/Makefile.am
      testsuite/misc-ming.all/NetStream-SquareTestRunner.cpp
      testsuite/misc-ming.all/PlaceObject2Test.c
      testsuite/misc-ming.all/PrototypeEventListenersTestRunner.cpp
      testsuite/misc-ming.all/RemoveObject2Test.c
      testsuite/misc-ming.all/RollOverOutTest-Runner.cpp
      testsuite/misc-ming.all/RollOverOutTest.c
      testsuite/misc-ming.all/SpriteButtonEventsTest-Runner.cpp
      testsuite/misc-ming.all/SpriteButtonEventsTest.c
      testsuite/misc-ming.all/Video-EmbedSquareTest.c
      testsuite/misc-ming.all/Video-EmbedSquareTestRunner.cpp
      testsuite/misc-ming.all/XMLSocketTest.c
      testsuite/misc-ming.all/action_execution_order_extend_test.c
      testsuite/misc-ming.all/action_execution_order_test.c
      testsuite/misc-ming.all/action_execution_order_test1.c
      testsuite/misc-ming.all/action_execution_order_test11.c
      testsuite/misc-ming.all/action_execution_order_test2.c
      testsuite/misc-ming.all/action_execution_order_test3.c
      testsuite/misc-ming.all/action_execution_order_test4.c
      testsuite/misc-ming.all/action_execution_order_test5.c
      testsuite/misc-ming.all/action_execution_order_test6.c
      testsuite/misc-ming.all/action_execution_order_test7.c
      testsuite/misc-ming.all/action_execution_order_test8.c
      testsuite/misc-ming.all/action_execution_order_test9.c
      testsuite/misc-ming.all/attachMovieLoopingTest.c
      testsuite/misc-ming.all/attachMovieLoopingTestRunner.cpp
      testsuite/misc-ming.all/attachMovieTest.c
      testsuite/misc-ming.all/attachMovieTestRunner.cpp
      testsuite/misc-ming.all/callFunction_test.c
      testsuite/misc-ming.all/consecutive_goto_frame_test.c
      testsuite/misc-ming.all/definebitsjpeg2.c
      testsuite/misc-ming.all/displaylist_depths_test.c
      testsuite/misc-ming.all/displaylist_depths_test10.c
      testsuite/misc-ming.all/displaylist_depths_test11.c
      testsuite/misc-ming.all/displaylist_depths_test2.c
      testsuite/misc-ming.all/displaylist_depths_test3.c
      testsuite/misc-ming.all/displaylist_depths_test4.c
      testsuite/misc-ming.all/displaylist_depths_test5.c
      testsuite/misc-ming.all/displaylist_depths_test6.c
      testsuite/misc-ming.all/displaylist_depths_test7.c
      testsuite/misc-ming.all/displaylist_depths_test8.c
      testsuite/misc-ming.all/displaylist_depths_test9.c
      testsuite/misc-ming.all/duplicate_movie_clip_test.c
      testsuite/misc-ming.all/duplicate_movie_clip_test2.c
      testsuite/misc-ming.all/easysound.as
      testsuite/misc-ming.all/eventSoundTest1-Runner.cpp
      testsuite/misc-ming.all/eventSoundTest1.c
      testsuite/misc-ming.all/event_handler_scope_test.c
      testsuite/misc-ming.all/frame_label_test.c
      testsuite/misc-ming.all/getTimer_test.c
      testsuite/misc-ming.all/get_frame_number_test.c
      testsuite/misc-ming.all/goto_frame_test.c
      testsuite/misc-ming.all/init_action_test.c
      testsuite/misc-ming.all/instanceNameTest.c
      testsuite/misc-ming.all/intervalTest.as
      testsuite/misc-ming.all/intervalTestRunner.cpp
      testsuite/misc-ming.all/key_event_test.c
      testsuite/misc-ming.all/key_event_testrunner.cpp
      testsuite/misc-ming.all/loadImageTest.c
      testsuite/misc-ming.all/loadMovieTest.c
      testsuite/misc-ming.all/loadMovieTestRunner.cpp
      testsuite/misc-ming.all/loop_test-Runner.cpp
      testsuite/misc-ming.all/loop_test.c
      testsuite/misc-ming.all/loop_test10.c
      testsuite/misc-ming.all/loop_test2.c
      testsuite/misc-ming.all/loop_test2runner.cpp
      testsuite/misc-ming.all/loop_test3.c
      testsuite/misc-ming.all/loop_test4.c
      testsuite/misc-ming.all/loop_test5.c
      testsuite/misc-ming.all/loop_test6.c
      testsuite/misc-ming.all/loop_test7.c
      testsuite/misc-ming.all/loop_test8.c
      testsuite/misc-ming.all/loop_test9.c
      testsuite/misc-ming.all/masks_test.c
      testsuite/misc-ming.all/masks_test2.c
      testsuite/misc-ming.all/masks_test2runner.cpp
      testsuite/misc-ming.all/masks_testrunner.cpp
      testsuite/misc-ming.all/matrix_test.c
      testsuite/misc-ming.all/ming_utils.c
      testsuite/misc-ming.all/ming_utils.h
      testsuite/misc-ming.all/morph_test1.c
      testsuite/misc-ming.all/morph_test1runner.cpp
      testsuite/misc-ming.all/move_object_test.c
      testsuite/misc-ming.all/moviecliploader_test.c
      testsuite/misc-ming.all/multi_doactions_and_goto_frame_test.c
      testsuite/misc-ming.all/new_child_in_unload_test.c
      testsuite/misc-ming.all/opcode_guard_test.c
      testsuite/misc-ming.all/path_format_test.c
      testsuite/misc-ming.all/place_and_remove_object_insane_test.c
      testsuite/misc-ming.all/place_and_remove_object_test.c
      testsuite/misc-ming.all/place_object_test.c
      testsuite/misc-ming.all/place_object_test2.c
      testsuite/misc-ming.all/registerClassTest.c
      testsuite/misc-ming.all/registerClassTest2.c
      testsuite/misc-ming.all/registerClassTestRunner.cpp
      testsuite/misc-ming.all/replace_buttons1test.c
      testsuite/misc-ming.all/replace_buttons1test_runner.cpp
      testsuite/misc-ming.all/replace_shapes1test.c
      testsuite/misc-ming.all/replace_shapes1test_runner.cpp
      testsuite/misc-ming.all/replace_sprites1test.c
      testsuite/misc-ming.all/replace_sprites1test_runner.cpp
      testsuite/misc-ming.all/reverse_execute_PlaceObject2_test1.c
      testsuite/misc-ming.all/reverse_execute_PlaceObject2_test2.c
      testsuite/misc-ming.all/root_stop_test.c
      testsuite/misc-ming.all/root_stop_testrunner.cpp
      testsuite/misc-ming.all/runtime_vm_stack_test.c
      testsuite/misc-ming.all/shape_test.c
      testsuite/misc-ming.all/simple_loop_test.c
      testsuite/misc-ming.all/simple_loop_testrunner.cpp
      testsuite/misc-ming.all/spritehier.c
      testsuite/misc-ming.all/static_vs_dynamic1.c
      testsuite/misc-ming.all/static_vs_dynamic2.c
      testsuite/misc-ming.all/streamingSoundTest1-Runner.cpp
      testsuite/misc-ming.all/streamingSoundTest1.c
      testsuite/misc-ming.all/timeline_var_test.c
      testsuite/misc-ming.all/unload_movieclip_test1.c
      testsuite/misc-ming.all/widgets.as
      testsuite/misc-mtasc.all/Base1.as
      testsuite/misc-mtasc.all/Dejagnu.as
      testsuite/misc-mtasc.all/Derived1.as
      testsuite/misc-mtasc.all/Makefile.am
      testsuite/misc-mtasc.all/TextFieldTest.as
      testsuite/misc-mtasc.all/check.as
      testsuite/misc-mtasc.all/exception.as
      testsuite/misc-mtasc.all/implementsOp/BExtendingImplementation.as
      testsuite/misc-mtasc.all/implementsOp/ImplementationA.as
      testsuite/misc-mtasc.all/implementsOp/ImplementationB.as
      testsuite/misc-mtasc.all/implementsOp/SimpleInterface.as
      testsuite/misc-mtasc.all/implementsOpTest.as
      testsuite/misc-mtasc.all/level5.as
      testsuite/misc-mtasc.all/level87.as
      testsuite/misc-mtasc.all/level99.as
      testsuite/misc-mtasc.all/levels.as
      testsuite/misc-mtasc.all/super_test1.as
      testsuite/misc-swfc.all/Dejagnu.sc
      testsuite/misc-swfc.all/Makefile.am
      testsuite/misc-swfc.all/action_execution_order_test10.sc
      testsuite/misc-swfc.all/action_execution_order_test12.sc
      testsuite/misc-swfc.all/button_test1.sc
      testsuite/misc-swfc.all/button_test1runner.cpp
      testsuite/misc-swfc.all/button_test2.sc
      testsuite/misc-swfc.all/check.sc
      testsuite/misc-swfc.all/edittext_test1.sc
      testsuite/misc-swfc.all/matrix_accuracy_test1.sc
      testsuite/misc-swfc.all/mouse_drag_test.sc
      testsuite/misc-swfc.all/movieclip_destruction_test1.sc
      testsuite/misc-swfc.all/movieclip_destruction_test2.sc
      testsuite/misc-swfc.all/movieclip_destruction_test3.sc
      testsuite/misc-swfc.all/movieclip_destruction_test4.sc
      testsuite/misc-swfc.all/opcode_guard_test2.sc
      testsuite/misc-swfc.all/opcode_guard_test3.sc
      testsuite/misc-swfc.all/registerclass_test3.sc
      testsuite/misc-swfc.all/soft_reference_test1.sc
      testsuite/misc-swfc.all/stackscope.sc
      testsuite/misc-swfc.all/swf4opcode.sc
      testsuite/misc-swfmill.all/Makefile.am
      testsuite/misc-swfmill.all/backgroundTestRunner.cpp
      testsuite/movies.all/Makefile.am
      testsuite/movies.all/gravity_embedded-TestRunner.cpp
      testsuite/samples/Makefile.am
      testsuite/samples/clip_as_button2-TestRunner.cpp
      testsuite/samples/gotoFrameOnKeyEvent-TestRunner.cpp
      testsuite/samples/subshapes-TestRunner.cpp
      testsuite/simple.exp
      testsuite/swfdec/Makefile.am
      testsuite/swfdec/PASSING
      testsuite/swfdec/gen_run_swfdec_testsuite.sh
      utilities/dumpshm.cpp
      utilities/flvdumper.cpp
      utilities/processor.cpp
      utilities/rtmpget.cpp
      utilities/soldumper.cpp
    ------------------------------------------------------------
    revno: 9483.4.363
    committer: address@hidden
    branch nick: rtmp
    timestamp: Thu 2009-03-19 18:00:54 -0600
    message:
      big merge from experimental branch, rewritten RTMT support for Gnash, with
      RTMP coming next. Cygnal handles Red5 'echo' tests for RTMPT and RTMP as
      well. Also new and greatly improved test case for 'echo' types of tests,
      ie... bouncing packets off a server and decoding the result.
      
      your mileage may vary...
    modified:
      cygnal/http_server.cpp
      cygnal/http_server.h
      libamf/amf.cpp
      libamf/amf_msg.cpp
      libbase/GC.h
      libcore/as_value.cpp
      libcore/as_value.h
      libcore/asobj/NetConnection_as.cpp
      libcore/asobj/NetConnection_as.h
      libcore/asobj/NetStream_as.cpp
      libnet/http.cpp
      libnet/http.h
      libnet/network.cpp
      libnet/network.h
      libnet/rtmp.cpp
      libnet/rtmp.h
      libnet/rtmp_client.cpp
      libnet/rtmp_client.h
      testsuite/libnet.all/test_http.cpp
      testsuite/misc-ming.all/red5test.as
      utilities/processor.cpp
        ------------------------------------------------------------
        revno: 10688.1.1
        committer: address@hidden
        branch nick: remoting
        timestamp: Wed 2009-03-11 21:46:26 -0600
        message:
          stripped out remoting stuff, sreaming video still works.
        modified:
          libcore/asobj/NetConnection_as.cpp
          libcore/asobj/NetConnection_as.h
        ------------------------------------------------------------
        revno: 10688.1.2
        committer: address@hidden
        branch nick: remoting
        timestamp: Wed 2009-03-11 21:49:13 -0600
        message:
          stripped out remoting stuff, sreaming video still works.
        modified:
          libbase/GC.h
          libcore/as_value.cpp
          libcore/as_value.h
          libcore/asobj/NetStream_as.cpp
          libnet/http.cpp
          libnet/http.h
          libnet/network.h
          utilities/processor.cpp
        ------------------------------------------------------------
        revno: 10688.1.3
        committer: address@hidden
        branch nick: remoting
        timestamp: Thu 2009-03-12 18:44:41 -0600
        message:
          merge in from branch, partial RTMP support, using libnet HTTP support 
for remoting.
        modified:
          libcore/asobj/NetConnection_as.cpp
          libcore/asobj/NetConnection_as.h
        ------------------------------------------------------------
        revno: 10688.1.4
        committer: address@hidden
        branch nick: remoting
        timestamp: Thu 2009-03-12 18:45:21 -0600
        message:
          store the path from the URL as well.
        modified:
          libnet/rtmp_client.h
        ------------------------------------------------------------
        revno: 10688.1.5
        committer: address@hidden
        branch nick: remoting
        timestamp: Thu 2009-03-12 19:44:38 -0600
        message:
          toggle a flag when connected.
        modified:
          libnet/rtmp_client.cpp
        ------------------------------------------------------------
        revno: 10688.1.6
        committer: address@hidden
        branch nick: remoting
        timestamp: Thu 2009-03-12 20:06:31 -0600
        message:
          pass the right Network connection to the thread handler.
        modified:
          libcore/asobj/NetConnection_as.cpp
          libcore/asobj/NetConnection_as.h
        ------------------------------------------------------------
        revno: 10688.1.7
        committer: address@hidden
        branch nick: remoting
        timestamp: Fri 2009-03-13 18:32:20 -0600
        message:
          don't encode strict arrays as sparse arrays.
        modified:
          libamf/amf.cpp
        ------------------------------------------------------------
        revno: 10688.1.8
        committer: address@hidden
        branch nick: remoting
        timestamp: Fri 2009-03-13 18:33:42 -0600
        message:
          add versions of sendMsg that use the priate setting for the file 
descriptor.
        modified:
          libnet/rtmp.cpp
          libnet/rtmp.h
        ------------------------------------------------------------
        revno: 10688.1.9
        committer: address@hidden
        branch nick: remoting
        timestamp: Fri 2009-03-13 18:35:23 -0600
        message:
          greatly expanded version of the test case.
        modified:
          testsuite/misc-ming.all/red5test.as
        ------------------------------------------------------------
        revno: 10688.1.10
        committer: address@hidden
        branch nick: remoting
        timestamp: Fri 2009-03-13 18:36:09 -0600
        message:
          also run single threaded, since the VM isn't thread safe.
        modified:
          libcore/asobj/NetConnection_as.cpp
          libcore/asobj/NetConnection_as.h
    ------------------------------------------------------------
    revno: 9483.4.364
    committer: address@hidden
    branch nick: rtmp
    timestamp: Tue 2009-03-24 10:33:25 -0600
    message:
      don't disallow ports under 1024.
    modified:
      libnet/network.cpp
    ------------------------------------------------------------
    revno: 9483.4.365
    committer: address@hidden
    branch nick: rtmp
    timestamp: Tue 2009-03-24 10:35:22 -0600
    message:
      get the baseURL when constructing the URL for ::call()
    modified:
      libcore/asobj/NetConnection_as.cpp
    ------------------------------------------------------------
    revno: 9483.4.366
    committer: address@hidden
    branch nick: rtmp
    timestamp: Tue 2009-03-24 11:43:35 -0600
    message:
      the content-length field is always only one data item.
    modified:
      libnet/http.cpp
    ------------------------------------------------------------
    revno: 9483.4.367
    committer: address@hidden
    branch nick: rtmp
    timestamp: Tue 2009-03-24 11:45:01 -0600
    message:
      the content-type field may have more than one item,so scan for what we 
want, not an exact match. Handle chunked transfer encoding header.
    modified:
      libcore/asobj/NetConnection_as.cpp
    ------------------------------------------------------------
    revno: 9483.4.368
    committer: address@hidden
    branch nick: rtmp
    timestamp: Tue 2009-03-24 20:00:52 -0600
    message:
      add some accessors for the queue
    modified:
      libnet/http.h
    ------------------------------------------------------------
    revno: 9483.4.369
    committer: address@hidden
    branch nick: rtmp
    timestamp: Tue 2009-03-24 20:01:34 -0600
    message:
      add recvChunked(), for the client side of reading chunked HTTP data.
    modified:
      libnet/http.cpp
    ------------------------------------------------------------
    revno: 9483.4.370
    committer: address@hidden
    branch nick: rtmp
    timestamp: Tue 2009-03-24 20:02:08 -0600
    message:
      don't resize to 0.
    modified:
      libamf/buffer.cpp
    ------------------------------------------------------------
    revno: 9483.4.371
    committer: address@hidden
    branch nick: rtmp
    timestamp: Tue 2009-03-24 20:04:00 -0600
    message:
      use recvChunked().
    modified:
      libcore/asobj/NetConnection_as.cpp
    ------------------------------------------------------------
    revno: 9483.4.372
    committer: address@hidden
    branch nick: rtmp
    timestamp: Tue 2009-03-24 20:04:26 -0600
    message:
      minor reformatting
    modified:
      libcore/asobj/NetConnection_as.h
    ------------------------------------------------------------
    revno: 9483.4.373
    committer: address@hidden
    branch nick: rtmp
    timestamp: Wed 2009-03-25 16:30:54 -0600
    message:
      tweak logic of ending buffer so merging works for bigger Buffers.
    modified:
      libnet/cque.cpp
      libnet/cque.h
    ------------------------------------------------------------
    revno: 9483.4.374
    committer: address@hidden
    branch nick: rtmp
    timestamp: Wed 2009-03-25 16:31:57 -0600
    message:
      add mergeChunks() to forcea merge of all the buffers in the queue. Don't 
copy the chunked transfer header to the data.
    modified:
      libnet/http.cpp
      libnet/http.h
    ------------------------------------------------------------
    revno: 9483.4.375
    committer: address@hidden
    branch nick: rtmp
    timestamp: Wed 2009-03-25 16:32:38 -0600
    message:
      don't dump the element when converting.
    modified:
      libcore/as_value.cpp
    ------------------------------------------------------------
    revno: 9483.4.376
    committer: address@hidden
    branch nick: rtmp
    timestamp: Wed 2009-03-25 16:33:14 -0600
    message:
      don't limit dumping to smaller buffers.
    modified:
      libamf/buffer.cpp
    ------------------------------------------------------------
    revno: 9483.4.377
    committer: address@hidden
    branch nick: rtmp
    timestamp: Wed 2009-03-25 16:33:46 -0600
    message:
      fix path to libcygnal.la.
    modified:
      cygnal/testsuite/cygnal.all/Makefile.am
    ------------------------------------------------------------
    revno: 9483.4.378
    committer: address@hidden
    branch nick: rtmp
    timestamp: Wed 2009-03-25 16:34:36 -0600
    message:
      don't include the server side onlyecho tests, they've been moved to the 
cygnal testsuite.
    modified:
      testsuite/libnet.all/test_http.cpp
    ------------------------------------------------------------
    revno: 9483.4.379
    committer: address@hidden
    branch nick: rtmp
    timestamp: Wed 2009-03-25 16:35:16 -0600
    message:
      minor reformatting.
    modified:
      testsuite/libamf.all/test_amfmsg.cpp
    ------------------------------------------------------------
    revno: 9483.4.380
    committer: address@hidden
    branch nick: rtmp
    timestamp: Wed 2009-03-25 16:36:02 -0600
    message:
      handle reading chunked messages.
    modified:
      libcore/asobj/NetConnection_as.cpp
    ------------------------------------------------------------
    revno: 9483.4.381
    committer: address@hidden
    branch nick: rtmp
    timestamp: Wed 2009-03-25 17:02:43 -0600
    message:
      add supported for the unsupported data type
    modified:
      libcore/as_value.cpp
      libcore/as_value.h
    ------------------------------------------------------------
    revno: 9483.4.382
    committer: address@hidden
    branch nick: rtmp
    timestamp: Wed 2009-03-25 17:44:14 -0600
    message:
      add support for converting Data Elements, and trapping bad data types.
    modified:
      libcore/as_value.cpp
    ------------------------------------------------------------
    revno: 9483.4.383
    committer: address@hidden
    branch nick: rtmp
    timestamp: Thu 2009-03-26 10:40:48 -0600
    message:
      remove the trailing \r\n that terminates the HTTP chunk, as it shouldn't 
be in the binary blob.
    modified:
      libnet/http.cpp
    ------------------------------------------------------------
    revno: 9483.4.384
    committer: address@hidden
    branch nick: rtmp
    timestamp: Thu 2009-03-26 10:46:43 -0600
    message:
      make less verbose, it works now.
    modified:
      libamf/amf_msg.cpp
      libcore/asobj/NetConnection_as.cpp
      libnet/cque.cpp
    ------------------------------------------------------------
    revno: 9483.4.385
    committer: address@hidden
    branch nick: rtmp
    timestamp: Thu 2009-03-26 10:46:55 -0600
    message:
      make less verbose, it works now.
    modified:
      libcore/as_value.cpp
    ------------------------------------------------------------
    revno: 9483.4.386
    committer: address@hidden
    branch nick: rtmp
    timestamp: Thu 2009-03-26 10:47:43 -0600
    message:
      make less verbose, fix old formatting errors.
    modified:
      libamf/amf.cpp
    ------------------------------------------------------------
    revno: 9483.4.387
    committer: address@hidden
    branch nick: rtmp
    timestamp: Thu 2009-03-26 11:08:22 -0600
    message:
      don't check property names to be ascii, they could be unicode instead.
    modified:
      libamf/element.cpp
    ------------------------------------------------------------
    revno: 9483.4.388
    committer: address@hidden
    branch nick: rtmp
    timestamp: Thu 2009-03-26 13:18:28 -0600
    message:
      don't try to convert an empty property to an as_value.
    modified:
      libcore/as_value.cpp
    ------------------------------------------------------------
    revno: 9483.4.389
    committer: address@hidden
    branch nick: rtmp
    timestamp: Thu 2009-03-26 13:23:30 -0600
    message:
      only drop the last two bytes on the last chunked packet.
    modified:
      libnet/http.cpp
    ------------------------------------------------------------
    revno: 9483.4.390
    committer: address@hidden
    branch nick: rtmp
    timestamp: Thu 2009-03-26 13:24:16 -0600
    message:
      less verbose
    modified:
      libcore/asobj/NetConnection_as.cpp
      libnet/cque.cpp
    ------------------------------------------------------------
    revno: 9483.4.391
    committer: address@hidden
    branch nick: rtmp
    timestamp: Thu 2009-03-26 18:38:10 -0600
    message:
      add a few RTMP tests
    modified:
      testsuite/misc-ming.all/red5test.as
    ------------------------------------------------------------
    revno: 9483.4.392
    committer: address@hidden
    branch nick: rtmp
    timestamp: Thu 2009-03-26 18:38:36 -0600
    message:
      reverse the order for client and server source fields.
    modified:
      libnet/rtmp_msg.h
    ------------------------------------------------------------
    revno: 9483.4.393
    committer: address@hidden
    branch nick: rtmp
    timestamp: Thu 2009-03-26 18:39:34 -0600
    message:
      red5 eants the connect packet as part of the final handshake, or it 
refuses to connect.
    modified:
      libnet/rtmp_client.cpp
      libnet/rtmp_client.h
    ------------------------------------------------------------
    revno: 9483.4.394
    committer: address@hidden
    branch nick: rtmp
    timestamp: Thu 2009-03-26 18:40:29 -0600
    message:
      do a successful NetConnection::connect() remoting call.
    modified:
      libcore/asobj/NetConnection_as.cpp
    ------------------------------------------------------------
    revno: 9483.4.395
    committer: address@hidden
    branch nick: rtmp
    timestamp: Thu 2009-03-26 21:49:20 -0600
    message:
      add method for creating the Red5 echo Requests.
    modified:
      libnet/rtmp_client.cpp
      libnet/rtmp_client.h
    ------------------------------------------------------------
    revno: 9483.4.396
    committer: address@hidden
    branch nick: rtmp
    timestamp: Thu 2009-03-26 21:49:51 -0600
    message:
      be more clear which response we got.
    modified:
      testsuite/misc-ming.all/red5test.as
    ------------------------------------------------------------
    revno: 9483.4.397
    committer: address@hidden
    branch nick: rtmp
    timestamp: Thu 2009-03-26 21:50:23 -0600
    message:
      hum, we need to sleep after connecting before trying to read a packet.
    modified:
      libnet/rtmp.cpp
    ------------------------------------------------------------
    revno: 9483.4.398
    committer: address@hidden
    branch nick: rtmp
    timestamp: Thu 2009-03-26 21:51:09 -0600
    message:
      process the response from a Red5 eecho request.
    modified:
      libcore/asobj/NetConnection_as.cpp
    ------------------------------------------------------------
    revno: 9483.4.399
    committer: address@hidden
    branch nick: rtmp
    timestamp: Thu 2009-03-26 22:05:59 -0600
    message:
      add the other data type tests to the RTMP tests.
    modified:
      testsuite/misc-ming.all/red5test.as
    ------------------------------------------------------------
    revno: 9483.4.400
    committer: address@hidden
    branch nick: rtmp
    timestamp: Fri 2009-03-27 09:23:24 -0600
    message:
      handle reading of RTMP messages bigger than the default chunksize of 128 
bytes.
    modified:
      libcore/asobj/NetConnection_as.cpp
    ------------------------------------------------------------
    revno: 9483.4.401
    committer: address@hidden
    branch nick: rtmp
    timestamp: Fri 2009-03-27 11:51:02 -0600
    message:
      minor reformatting
    modified:
      libcore/namedStrings.cpp
      libnet/network.h
    ------------------------------------------------------------
    revno: 9483.4.402
    committer: address@hidden
    branch nick: rtmp
    timestamp: Fri 2009-03-27 11:54:57 -0600
    message:
      check the connect() status for RTMP too.
    modified:
      testsuite/misc-ming.all/red5test.as
    ------------------------------------------------------------
    revno: 9483.4.403
    committer: address@hidden
    branch nick: rtmp
    timestamp: Fri 2009-03-27 11:55:57 -0600
    message:
      add a pointer to the current object to the thread_params.
    modified:
      libcore/asobj/NetConnection_as.h
    ------------------------------------------------------------
    revno: 9483.4.404
    committer: address@hidden
    branch nick: rtmp
    timestamp: Fri 2009-03-27 11:56:15 -0600
    message:
      Read multiple RTMP messages. Move the processing to net_handler() from 
call().
    modified:
      libcore/asobj/NetConnection_as.cpp
    ------------------------------------------------------------
    revno: 9483.4.405
    committer: address@hidden
    branch nick: rtmp
    timestamp: Fri 2009-03-27 13:57:58 -0600
    message:
      use methodName instead of the app name for creating an echo request.
    modified:
      libcore/asobj/NetConnection_as.cpp
    ------------------------------------------------------------
    revno: 9483.4.406
    committer: address@hidden
    branch nick: rtmp
    timestamp: Fri 2009-03-27 17:28:09 -0600
    message:
      make rtmpget build again, support of the new client side API partially 
done.
    modified:
      utilities/rtmpget.cpp
    ------------------------------------------------------------
    revno: 9483.4.407
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-03-28 09:09:27 -0600
    message:
      always reset the element before returning an error.
    modified:
      libamf/amf.cpp
    ------------------------------------------------------------
    revno: 9483.4.408
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-03-28 12:33:52 -0600
    message:
      add rtmpget back in.
    modified:
      utilities/Makefile.am
    ------------------------------------------------------------
    revno: 9483.4.409
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-03-28 12:34:29 -0600
    message:
      refactored heavily. Added error checking of responses since we can now 
easily decode them.
    modified:
      utilities/rtmpget.cpp
    ------------------------------------------------------------
    revno: 9483.4.410
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-03-28 12:35:12 -0600
    message:
      be clear which server the responses are from.
    modified:
      testsuite/misc-ming.all/red5test.as
    ------------------------------------------------------------
    revno: 9483.4.411
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-03-28 12:36:39 -0600
    message:
      add check for invalid argument, which somehow got left out.
    modified:
      libnet/rtmp_msg.cpp
    ------------------------------------------------------------
    revno: 9483.4.412
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-03-28 16:44:11 -0600
    message:
      write the FLV file to disk while we read it in.
    modified:
      utilities/rtmpget.cpp
    ------------------------------------------------------------
    revno: 9483.4.413
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-03-28 16:45:03 -0600
    message:
      make decodeHeader less verbose.
    modified:
      libnet/rtmp.cpp
    ------------------------------------------------------------
    revno: 9483.4.414
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-03-28 16:45:43 -0600
    message:
      remove if'd out code.
    modified:
      libcore/asobj/NetConnection_as.cpp
    ------------------------------------------------------------
    revno: 9483.4.415
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-03-28 17:00:37 -0600
    message:
      add more comments.
    modified:
      utilities/rtmpget.cpp
    ------------------------------------------------------------
    revno: 9483.4.416
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sat 2009-03-28 18:26:51 -0600
    message:
      write the FLV magic number.
    modified:
      utilities/rtmpget.cpp
    ------------------------------------------------------------
    revno: 9483.4.417
    committer: address@hidden
    branch nick: rtmp
    timestamp: Tue 2009-03-31 11:36:51 -0600
    message:
      merge from savannah
    modified:
      cygnal/http_server.h
      cygnal/proc.h
      libamf/amf_msg.cpp
      libnet/rtmp_client.h
      testsuite/misc-ming.all/Makefile.am
      utilities/rtmpget.cpp
        ------------------------------------------------------------
        revno: 9483.11.1
        committer: Markus Gothe <address@hidden>
        branch nick: rtmp
        timestamp: Tue 2009-03-31 02:31:07 +0200
        message:
          Added DSOEXPORT-attribute
        modified:
          libnet/rtmp_client.h
        ------------------------------------------------------------
        revno: 9483.11.2
        committer: Markus Gothe <address@hidden>
        branch nick: rtmp
        timestamp: Tue 2009-03-31 02:53:35 +0200
        message:
          Added DSOEXPORT-attribute
        modified:
          cygnal/http_server.h
          cygnal/proc.h
          libnet/rtmp_client.h
    ------------------------------------------------------------
    revno: 9483.4.418
    committer: address@hidden
    branch nick: rtmp
    timestamp: Tue 2009-03-31 14:54:13 -0600
    message:
      use the standard arg_parser way of handling command line options. Add -P 
option.
    modified:
      utilities/processor.cpp
    ------------------------------------------------------------
    revno: 9483.4.419
    committer: address@hidden
    branch nick: rtmp
    timestamp: Tue 2009-03-31 15:16:53 -0600
    message:
      Finish adding -P option support.
    modified:
      utilities/processor.cpp
    ------------------------------------------------------------
    revno: 9483.4.420
    committer: address@hidden
    branch nick: rtmp
    timestamp: Tue 2009-03-31 15:36:56 -0600
    message:
      support using flashVars to set hostname and ports.
    modified:
      testsuite/misc-ming.all/red5test.as
    ------------------------------------------------------------
    revno: 9483.4.421
    committer: address@hidden
    branch nick: rtmp
    timestamp: Tue 2009-03-31 17:53:47 -0600
    message:
      handle reading the handshake, which arrives in any series of packetsof 
any size based on network latency.
    modified:
      libnet/rtmp_client.cpp
    ------------------------------------------------------------
    revno: 9483.4.422
    committer: address@hidden
    branch nick: rtmp
    timestamp: Tue 2009-03-31 17:58:53 -0600
    message:
      make less verbose. Drop silly debug statement that valgrind doesn't like.
    modified:
      utilities/rtmpget.cpp
    ------------------------------------------------------------
    revno: 9483.4.423
    committer: address@hidden
    branch nick: rtmp
    timestamp: Tue 2009-03-31 18:11:33 -0600
    message:
      don't leak any memory.
    modified:
      utilities/rtmpget.cpp
    ------------------------------------------------------------
    revno: 9483.4.424
    committer: address@hidden
    branch nick: rtmp
    timestamp: Tue 2009-03-31 20:49:29 -0600
    message:
      add new directory for real networking tests.
    added:
      testsuite/network.all/
      testsuite/network.all/Dejagnu.c
      testsuite/network.all/Makefile.am
      testsuite/network.all/http.as
      testsuite/network.all/netstream.as
      testsuite/network.all/network.exp
      testsuite/network.all/remoting.README
      testsuite/network.all/rtmp.as
    modified:
      configure.ac
      testsuite/Makefile.am
    ------------------------------------------------------------
    revno: 9483.4.425
    committer: address@hidden
    branch nick: rtmp
    timestamp: Tue 2009-03-31 20:54:18 -0600
    message:
      convering as_values toElements is a boost::shared_ptr now, not auto_ptr.
    modified:
      testsuite/libcore.all/AsValueTest.cpp
    ------------------------------------------------------------
    revno: 9483.4.426
    committer: address@hidden
    branch nick: rtmp
    timestamp: Wed 2009-04-01 10:23:23 -0600
    message:
      probe a list of target machines to see what is available for testing. Use 
-P to specify the parameters for the test case.
    modified:
      testsuite/network.all/network.exp
    ------------------------------------------------------------
    revno: 9483.4.427
    committer: address@hidden
    branch nick: rtmp
    timestamp: Wed 2009-04-01 11:37:11 -0600
    message:
      Add tests for netat and wget, which are used in testing. Display the
      results of the tests.
    modified:
      configure.ac
    ------------------------------------------------------------
    revno: 9483.4.428
    committer: address@hidden
    branch nick: rtmp
    timestamp: Wed 2009-04-01 11:38:08 -0600
    message:
      make network.all optional based on whether netcat is installed.
    modified:
      testsuite/Makefile.am
    ------------------------------------------------------------
    revno: 9483.4.429
    committer: address@hidden
    branch nick: rtmp
    timestamp: Wed 2009-04-01 12:16:33 -0600
    message:
      rename to be consistant
    renamed:
      testsuite/libbase/ => testsuite/libbase.all/
    ------------------------------------------------------------
    revno: 9483.4.430
    committer: address@hidden
    branch nick: rtmp
    timestamp: Wed 2009-04-01 12:33:44 -0600
    message:
      make sure we have a valid server for testing before continuing.
    modified:
      testsuite/network.all/network.exp
    ------------------------------------------------------------
    revno: 9483.4.431
    committer: address@hidden
    branch nick: rtmp
    timestamp: Wed 2009-04-01 13:51:47 -0600
    message:
      remove red5test, it's now in network.all
    modified:
      testsuite/misc-ming.all/Makefile.am
    ------------------------------------------------------------
    revno: 9483.4.432
    committer: address@hidden
    branch nick: rtmp
    timestamp: Wed 2009-04-01 13:53:49 -0600
    message:
      improve status messages.
    modified:
      testsuite/network.all/http.as
    ------------------------------------------------------------
    revno: 9483.4.433
    committer: address@hidden
    branch nick: rtmp
    timestamp: Wed 2009-04-01 14:53:29 -0600
    message:
      improve isConnected tests.
    modified:
      testsuite/network.all/http.as
    ------------------------------------------------------------
    revno: 9483.4.434
    committer: address@hidden
    branch nick: rtmp
    timestamp: Wed 2009-04-01 16:52:04 -0600
    message:
      add recvResponse() to handle all the wpork of reading a message, 
splitting it, and processing all the queues.
    modified:
      libnet/rtmp_client.cpp
      libnet/rtmp_client.h
    ------------------------------------------------------------
    revno: 9483.4.435
    committer: address@hidden
    branch nick: rtmp
    timestamp: Wed 2009-04-01 16:53:00 -0600
    message:
      decodeMsgBody() now returns a boost:shared_ptr instead of a real pointer.
    modified:
      cygnal/rtmp_server.cpp
      libcore/asobj/NetConnection_as.cpp
      libnet/rtmp.cpp
      libnet/rtmp.h
      utilities/rtmpget.cpp
    ------------------------------------------------------------
    revno: 9483.4.436
    committer: address@hidden
    branch nick: rtmp
    timestamp: Wed 2009-04-01 16:54:07 -0600
    message:
      cleanup to get closer to working 100%.
    modified:
      testsuite/network.all/rtmp.as
    ------------------------------------------------------------
    revno: 9483.4.437
    committer: address@hidden
    branch nick: rtmp
    timestamp: Wed 2009-04-01 18:20:21 -0600
    message:
      use recvResponse() instead of doing it our own way.
    modified:
      utilities/rtmpget.cpp
    ------------------------------------------------------------
    revno: 9483.4.438
    committer: address@hidden
    branch nick: rtmp
    timestamp: Thu 2009-04-02 08:55:15 -0600
    message:
      set the bodysize to the last known bodysize for a channel if the header 
size is 1. Also if a single byte header is the first part of the buffer to be 
split(), don't forget to put the header byte in the buffer. For regular 
continuation packets the single header byte is left out.
    modified:
      libnet/rtmp.cpp
    ------------------------------------------------------------
    revno: 9483.4.439
    committer: address@hidden
    branch nick: rtmp
    timestamp: Thu 2009-04-02 09:04:09 -0600
    message:
      return a dequeue of Messages from recvResponse if there is data.
    modified:
      libnet/rtmp_client.cpp
      libnet/rtmp_client.h
    ------------------------------------------------------------
    revno: 9483.4.440
    committer: address@hidden
    branch nick: rtmp
    timestamp: Thu 2009-04-02 09:05:01 -0600
    message:
      handle processing data from Invoke messages recieved from the RTMP server.
    modified:
      libcore/asobj/NetConnection_as.cpp
    ------------------------------------------------------------
    revno: 9483.4.441
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sun 2009-04-05 15:04:55 -0600
    message:
      use -v with netcat, so it works on ubuntu too.
    modified:
      testsuite/network.all/network.exp
    ------------------------------------------------------------
    revno: 9483.4.442
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sun 2009-04-05 15:08:16 -0600
    message:
      decodeMsgBody() returns a boost::shared_ptr<RTMPMsg> now instead of a 
real pointer.
    modified:
      testsuite/libnet.all/test_rtmp.cpp
    ------------------------------------------------------------
    revno: 9483.4.443
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sun 2009-04-05 15:09:00 -0600
    message:
      minor reformatting.
    modified:
      cygnal/testsuite/cygnal.exp
      utilities/processor.cpp
    ------------------------------------------------------------
    revno: 9483.4.444
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sun 2009-04-05 15:19:54 -0600
    message:
      there is no type field for single byte headers, so we can't print it.
    modified:
      libnet/rtmp.cpp
    ------------------------------------------------------------
    revno: 9483.4.445
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sun 2009-04-05 15:20:30 -0600
    message:
      make less verbose.
    modified:
      libcore/asobj/NetConnection_as.cpp
    ------------------------------------------------------------
    revno: 9483.4.446
    committer: address@hidden
    branch nick: rtmp
    timestamp: Sun 2009-04-05 16:01:27 -0600
    message:
      merge from trunk.
    removed:
      libcore/character.cpp
      libcore/character.h
    added:
      libbase/GnashNumeric.h
      libcore/InteractiveObject.cpp
      libcore/InteractiveObject.h
      testsuite/as3/
      testsuite/as3/Makefile.am
      testsuite/as3/basic.as
      testsuite/as3/check.as
      testsuite/as3/dejagnu.as
      testsuite/media/vstroke.png
      testsuite/misc-ming.all/BitmapSmoothingTest.c
    renamed:
      libcore/timers.cpp => libcore/Timers.cpp
      libcore/timers.h => libcore/Timers.h
    modified:
      README
      backend/render_handler.h
      backend/render_handler_agg.cpp
      backend/render_handler_cairo.cpp
      backend/render_handler_ogl.cpp
      configure.ac
      cygnal/Makefile.am
      cygnal/crc.cpp
      cygnal/cygnal.cpp
      doc/C/gnashref.xml
      doc/C/gnashuser.xml
      doc/C/preformatted/gnash.1.in
      doc/C/preformatted/gnash_ref.info.in
      doc/C/preformatted/gnash_user.info.in
      doc/C/preformatted/gnashref.html.in
      doc/C/preformatted/gnashuser.html.in
      doc/C/usermanual/gnashrc.xml
      gui/Kde4Gui.cpp
      gui/Player.cpp
      gui/gnash.cpp
      gui/gtk.cpp
      gui/gtk_glue_agg_xv.cpp
      gui/gui.cpp
      gui/gui.h
      gui/kde.cpp
      libamf/amf_msg.cpp
      libbase/GnashException.h
      libbase/LoadThread.cpp
      libbase/LoadThread.h
      libbase/Makefile.am
      libbase/URL.cpp
      libbase/curl_adapter.cpp
      libbase/gnashrc.in
      libbase/jemalloc.c
      libbase/log.cpp
      libbase/log.h
      libbase/snappingrange.h
      libbase/utility.h
      libcore/Bitmap.cpp
      libcore/Bitmap.h
      libcore/BitmapMovieInstance.cpp
      libcore/BitmapMovieInstance.h
      libcore/Button.cpp
      libcore/Button.h
      libcore/CharacterProxy.cpp
      libcore/CharacterProxy.h
      libcore/DisplayList.cpp
      libcore/DisplayList.h
      libcore/DisplayObject.cpp
      libcore/DisplayObject.h
      libcore/Font.cpp
      libcore/Font.h
      libcore/FreetypeGlyphsProvider.cpp
      libcore/FreetypeGlyphsProvider.h
      libcore/GnashKey.h
      libcore/Makefile.am
      libcore/MouseButtonState.h
      libcore/MovieClip.cpp
      libcore/MovieClip.h
      libcore/RGBA.cpp
      libcore/SWFMatrix.cpp
      libcore/Shape.cpp
      libcore/Shape.h
      libcore/Sprite.h
      libcore/StaticText.cpp
      libcore/StaticText.h
      libcore/TextField.cpp
      libcore/TextField.h
      libcore/Video.cpp
      libcore/Video.h
      libcore/VirtualClock.h
      libcore/as_environment.cpp
      libcore/as_environment.h
      libcore/as_function.cpp
      libcore/as_function.h
      libcore/as_object.cpp
      libcore/as_object.h
      libcore/as_value.cpp
      libcore/as_value.h
      libcore/asobj/Array_as.cpp
      libcore/asobj/Array_as.h
      libcore/asobj/AsBroadcaster.cpp
      libcore/asobj/ClassHierarchy.cpp
      libcore/asobj/Color_as.cpp
      libcore/asobj/Date_as.cpp
      libcore/asobj/Global.cpp
      libcore/asobj/Key_as.cpp
      libcore/asobj/Key_as.h
      libcore/asobj/LoadVars_as.cpp
      libcore/asobj/LoadableObject.cpp
      libcore/asobj/LoadableObject.h
      libcore/asobj/Math_as.cpp
      libcore/asobj/Mouse_as.cpp
      libcore/asobj/MovieClipLoader.cpp
      libcore/asobj/NetConnection_as.cpp
      libcore/asobj/NetConnection_as.h
      libcore/asobj/NetStream_as.cpp
      libcore/asobj/NetStream_as.h
      libcore/asobj/Object.cpp
      libcore/asobj/Selection_as.cpp
      libcore/asobj/SharedObject_as.cpp
      libcore/asobj/Sound_as.cpp
      libcore/asobj/Sound_as.h
      libcore/asobj/String_as.cpp
      libcore/asobj/System_as.cpp
      libcore/asobj/TextFormat_as.cpp
      libcore/asobj/TextFormat_as.h
      libcore/asobj/TextSnapshot_as.cpp
      libcore/asobj/TextSnapshot_as.h
      libcore/asobj/XMLNode_as.cpp
      libcore/asobj/XMLNode_as.h
      libcore/asobj/XMLSocket_as.cpp
      libcore/asobj/XML_as.cpp
      libcore/asobj/flash/display/BitmapData_as.cpp
      libcore/asobj/flash/geom/Point_as.cpp
      libcore/asobj/flash/geom/Rectangle_as.cpp
      libcore/asobj/flash/geom/Transform_as.cpp
      libcore/cxform.cpp
      libcore/cxform.h
      libcore/debugger.cpp
      libcore/drag_state.h
      libcore/event_id.h
      libcore/fill_style.cpp
      libcore/fill_style.h
      libcore/movie_instance.cpp
      libcore/movie_instance.h
      libcore/movie_root.cpp
      libcore/movie_root.h
      libcore/parser/BitmapMovieDefinition.cpp
      libcore/parser/BitmapMovieDefinition.h
      libcore/parser/Namespace.h
      libcore/parser/SWFMovieDefinition.cpp
      libcore/parser/SWFMovieDefinition.h
      libcore/parser/character_def.h
      libcore/parser/morph2_character_def.cpp
      libcore/parser/morph2_character_def.h
      libcore/parser/movie_definition.h
      libcore/parser/shape_character_def.cpp
      libcore/parser/shape_character_def.h
      libcore/parser/sprite_definition.cpp
      libcore/parser/sprite_definition.h
      libcore/rect.cpp
      libcore/render.cpp
      libcore/render.h
      libcore/styles.cpp
      libcore/swf.h
      libcore/swf/DefineButtonCxformTag.cpp
      libcore/swf/DefineButtonSoundTag.cpp
      libcore/swf/DefineButtonSoundTag.h
      libcore/swf/DefineButtonTag.cpp
      libcore/swf/DefineButtonTag.h
      libcore/swf/DefineEditTextTag.cpp
      libcore/swf/DefineEditTextTag.h
      libcore/swf/DefineFontTag.cpp
      libcore/swf/DefineFontTag.h
      libcore/swf/DefineTextTag.cpp
      libcore/swf/DefineTextTag.h
      libcore/swf/DefineVideoStreamTag.cpp
      libcore/swf/DefineVideoStreamTag.h
      libcore/swf/DisplayListTag.h
      libcore/swf/DoInitActionTag.h
      libcore/swf/PlaceObject2Tag.cpp
      libcore/swf/PlaceObject2Tag.h
      libcore/swf/RemoveObjectTag.cpp
      libcore/swf/RemoveObjectTag.h
      libcore/swf/SetBackgroundColorTag.h
      libcore/swf/StartSoundTag.h
      libcore/swf/TextRecord.cpp
      libcore/swf/TextRecord.h
      libcore/swf/VideoFrameTag.cpp
      libcore/swf/VideoFrameTag.h
      libcore/swf/tag_loaders.cpp
      libcore/swf_function.cpp
      libcore/vm/ASHandlers.cpp
      libcore/vm/ASHandlers.h
      libcore/vm/ActionExec.cpp
      libcore/vm/ActionExec.h
      libcore/vm/CodeStream.h
      libcore/vm/ExecutableCode.h
      libcore/vm/Machine.h
      libcore/vm/VM.h
      libcore/vm/action.cpp
      libcore/vm/action.h
      libcore/vm/fn_call.h
      libmedia/AudioDecoderSimple.cpp
      libmedia/MediaParser.h
      libmedia/gst/swfdec_codec_gst.c
      libnet/network.cpp
      macros/gnashpkgtool.m4
      macros/pthreads.m4
      plugin/klash4/klash_part.moc.in
      pythonmodule/gnashpython.cpp
      pythonmodule/gnashpython.h
      pythonmodule/pyGnash.cpp
      testsuite/DummyCharacter.h
      testsuite/DummyMovieDefinition.h
      testsuite/Makefile.am
      testsuite/MovieTester.cpp
      testsuite/MovieTester.h
      testsuite/libbase.all/TCXXRc.cpp
      testsuite/libbase.all/gnashrc.in
      testsuite/libcore.all/AsValueTest.cpp
      testsuite/libcore.all/ClassSizes.cpp
      testsuite/libcore.all/DisplayListTest.cpp
      testsuite/libcore.all/Makefile.am
      testsuite/libnet.all/test_http.cpp
      testsuite/misc-ming.all/BitmapDataTest.c
      testsuite/misc-ming.all/ButtonEventsTest-Runner.cpp
      testsuite/misc-ming.all/ButtonEventsTest.c
      testsuite/misc-ming.all/DefineEditTextTest-Runner.cpp
      testsuite/misc-ming.all/DefineEditTextVariableNameTest-Runner.cpp
      testsuite/misc-ming.all/DefineEditTextVariableNameTest.c
      testsuite/misc-ming.all/DefineTextTest-Runner.cpp
      testsuite/misc-ming.all/DragDropTestRunner.cpp
      testsuite/misc-ming.all/DrawingApiTestRunner.cpp
      testsuite/misc-ming.all/EmbeddedSoundTest-Runner.cpp
      testsuite/misc-ming.all/KeyIsDownTest.c
      testsuite/misc-ming.all/LoadVarsTest.c
      testsuite/misc-ming.all/Makefile.am
      testsuite/misc-ming.all/NetStream-SquareTest.c
      testsuite/misc-ming.all/NetStream-SquareTestRunner.cpp
      testsuite/misc-ming.all/PlaceObject2Test.c
      testsuite/misc-ming.all/PrototypeEventListenersTestRunner.cpp
      testsuite/misc-ming.all/RollOverOutTest-Runner.cpp
      testsuite/misc-ming.all/SpriteButtonEventsTest-Runner.cpp
      testsuite/misc-ming.all/VarAndCharClashTest.as
      testsuite/misc-ming.all/Video-EmbedSquareTestRunner.cpp
      testsuite/misc-ming.all/attachMovieLoopingTest.c
      testsuite/misc-ming.all/attachMovieLoopingTestRunner.cpp
      testsuite/misc-ming.all/attachMovieTestRunner.cpp
      testsuite/misc-ming.all/displaylist_depths_test.c
      testsuite/misc-ming.all/displaylist_depths_test10.c
      testsuite/misc-ming.all/displaylist_depths_test11.c
      testsuite/misc-ming.all/displaylist_depths_test2.c
      testsuite/misc-ming.all/displaylist_depths_test3.c
      testsuite/misc-ming.all/displaylist_depths_test4.c
      testsuite/misc-ming.all/displaylist_depths_test5.c
      testsuite/misc-ming.all/displaylist_depths_test6.c
      testsuite/misc-ming.all/displaylist_depths_test7.c
      testsuite/misc-ming.all/displaylist_depths_test8.c
      testsuite/misc-ming.all/displaylist_depths_test9.c
      testsuite/misc-ming.all/eventSoundTest1-Runner.cpp
      testsuite/misc-ming.all/goto_frame_test.c
      testsuite/misc-ming.all/instanceNameTest.c
      testsuite/misc-ming.all/intervalTestRunner.cpp
      testsuite/misc-ming.all/key_event_test.c
      testsuite/misc-ming.all/key_event_testrunner.cpp
      testsuite/misc-ming.all/loadMovieTestRunner.cpp
      testsuite/misc-ming.all/loop_test-Runner.cpp
      testsuite/misc-ming.all/loop_test.c
      testsuite/misc-ming.all/loop_test2.c
      testsuite/misc-ming.all/loop_test2runner.cpp
      testsuite/misc-ming.all/loop_test3.c
      testsuite/misc-ming.all/loop_test4.c
      testsuite/misc-ming.all/loop_test5.c
      testsuite/misc-ming.all/loop_test6.c
      testsuite/misc-ming.all/loop_test7.c
      testsuite/misc-ming.all/loop_test8.c
      testsuite/misc-ming.all/loop_test9.c
      testsuite/misc-ming.all/masks_test.c
      testsuite/misc-ming.all/masks_test2runner.cpp
      testsuite/misc-ming.all/masks_testrunner.cpp
      testsuite/misc-ming.all/morph_test1runner.cpp
      testsuite/misc-ming.all/place_object_test.c
      testsuite/misc-ming.all/place_object_test2.c
      testsuite/misc-ming.all/registerClassTestRunner.cpp
      testsuite/misc-ming.all/replace_buttons1test.c
      testsuite/misc-ming.all/replace_buttons1test_runner.cpp
      testsuite/misc-ming.all/replace_shapes1test.c
      testsuite/misc-ming.all/replace_shapes1test_runner.cpp
      testsuite/misc-ming.all/replace_sprites1test.c
      testsuite/misc-ming.all/replace_sprites1test_runner.cpp
      testsuite/misc-ming.all/root_stop_testrunner.cpp
      testsuite/misc-ming.all/shape_test.c
      testsuite/misc-ming.all/simple_loop_test.c
      testsuite/misc-ming.all/simple_loop_testrunner.cpp
      testsuite/misc-ming.all/static_vs_dynamic2.c
      testsuite/misc-ming.all/streamingSoundTest1-Runner.cpp
      testsuite/misc-swfc.all/button_test1runner.cpp
      testsuite/misc-swfc.all/movieclip_destruction_test1.sc
      testsuite/misc-swfc.all/opcode_guard_test3.sc
      testsuite/misc-swfc.all/soft_reference_test1.sc
      testsuite/misc-swfmill.all/backgroundTestRunner.cpp
      testsuite/misc-swfmill.all/initaction_in_definesprite.xml
      testsuite/movies.all/gravity_embedded-TestRunner.cpp
      testsuite/samples/clip_as_button2-TestRunner.cpp
      testsuite/samples/gotoFrameOnKeyEvent-TestRunner.cpp
      testsuite/samples/subshapes-TestRunner.cpp
      utilities/processor.cpp
      libcore/Timers.cpp
      libcore/Timers.h
=== modified file 'configure.ac'
--- a/configure.ac      2009-06-06 22:55:39 +0000
+++ b/configure.ac      2009-06-07 21:14:22 +0000
@@ -461,6 +461,16 @@
 esac],cygnal=no)
 AM_CONDITIONAL(CYGNAL, test x$cygnal = xyes)
 
+dnl Build the cgibins server if specified.
+AC_ARG_ENABLE(cgibins,
+  AC_HELP_STRING([--enable-cgibin], [Enable building of the CGIs for Cygnal]),
+[case "${enableval}" in
+  yes) cgibin=yes ;;
+  no)  cgibin=no ;;
+  *)   AC_MSG_ERROR([bad value ${enableval} for enable-cgibin option]) ;;
+esac],cgibin=yes)
+AM_CONDITIONAL(USE_CGI, test x$cgibin = xyes)
+
 dnl Fix the Intel 810 LOD bias problem
 AC_ARG_ENABLE(i810-lod-bias,
   AC_HELP_STRING([--enable-i810-lod-bias], [Enable fix for Intel 810 LOD bias 
problem]),
@@ -1239,7 +1249,6 @@
 AM_CONDITIONAL(HAVE_DMALLOC, [ test x$has_dmalloc = xyes ])
 
 AC_PATH_TOOL([AUTOTRACE], [autotrace])
-AC_PATH_TOOL([NETCAT], [netcat])
 AC_HEADER_DIRENT
 
 dnl -----------------------------------------------------------------
@@ -1671,6 +1680,11 @@
 fi
 AM_CONDITIONAL(ENABLE_RED5_TESTING, [ test x"$RED5_HOST" != x ])
 
+AC_PATH_PROG(NETCAT, nc)
+AM_CONDITIONAL(HAS_NETCAT, [ test x"$NETCAT" != x ])
+AC_PATH_PROG(WGET, wget)
+AM_CONDITIONAL(HAS_WGET, [ test x"$WGET" != x ])
+
 dnl
 dnl See if we can use the swfmill, mtasc, swfc and haxe based testsuites 
 dnl
@@ -2227,8 +2241,8 @@
 dnl AC_CONFIG_LINKS(doc/C/images)
 dnl AC_CONFIG_LINKS(gnashconfig.h,libltdl/config.h)
 
AC_CONFIG_LINKS(cygnal/testsuite/cygnal.all/cygnalrc:cygnal/testsuite/cygnal.all/cygnalrc.in)
-AC_CONFIG_LINKS(testsuite/libbase/gnashrc:testsuite/libbase/gnashrc.in)
-AC_CONFIG_LINKS(testsuite/libbase/gnashrc-local:testsuite/libbase/gnashrc-local.in)
+AC_CONFIG_LINKS(testsuite/libbase.all/gnashrc:testsuite/libbase.all/gnashrc.in)
+AC_CONFIG_LINKS(testsuite/libbase.all/gnashrc-local:testsuite/libbase.all/gnashrc-local.in)
 
 AC_CONFIG_FILES(gnash.pc:gnash.pc.in)
 
@@ -2250,7 +2264,7 @@
 pythonmodule/Makefile
 testsuite/Makefile
 testsuite/media/Makefile
-testsuite/libbase/Makefile
+testsuite/libbase.all/Makefile
 testsuite/as3/Makefile
 testsuite/as3/classes.all/Makefile
 testsuite/actionscript.all/Makefile
@@ -2261,6 +2275,7 @@
 testsuite/misc-haxe.all/Makefile
 testsuite/misc-swfmill.all/Makefile
 testsuite/misc-swfc.all/Makefile
+testsuite/network.all/Makefile
 testsuite/movies.all/Makefile
 testsuite/libcore.all/Makefile
 testsuite/libamf.all/Makefile
@@ -2283,6 +2298,8 @@
 plugin/mozilla-sdk/Makefile
 plugin/win32/Makefile
 cygnal/Makefile
+cygnal/cgi-bin/Makefile
+cygnal/cgi-bin/echo/Makefile
 cygnal/testsuite/Makefile
 cygnal/testsuite/cygnal.all/Makefile
 )
@@ -3248,6 +3265,17 @@
   echo "     ${classlist}"
 fi
 
+if test x"$NETCAT" != x; then
+    echo "        You have netcat installed, which is only used for testing"
+else
+    echo "        Install netcat for networking test support"
+fi
+if test x"$WGET" != x; then
+    echo "        You have wget installed, which is only used for testing"
+else
+    echo "        Install wget for networking test support"
+fi
+
 if test x$cross_compiling = xyes; then
   AC_MSG_NOTICE([This build is setup for cross compiling])
 fi

=== modified file 'cygnal/Makefile.am'
--- a/cygnal/Makefile.am        2009-04-06 20:29:42 +0000
+++ b/cygnal/Makefile.am        2009-06-07 21:14:22 +0000
@@ -21,7 +21,11 @@
 AUTOMAKE_OPTIONS = dejagnu
 
 if TESTSUITE
-TEST_DIR = testsuite
+TEST_DIR = #testsuite
+endif
+
+if USE_CGI
+CGI_DIR = cgi-bin
 endif
 
 SUBDIRS = \
@@ -67,12 +71,19 @@
 noinst_HEADERS = \
        cygnal.h \
        rtmp_server.h \
+       http_server.h \
+       proc.h \
        crc.h
 
 bin_PROGRAMS = cygnal
-
-cygnal_SOURCES = cygnal.cpp crc.cpp cvm.cpp rtmp_server.cpp
-cygnal_LDADD = $(AM_LDFLAGS)
+lib_LTLIBRARIES = libcygnal.la
+
+cygnal_SOURCES = cygnal.cpp
+cygnal_LDADD = $(AM_LDFLAGS) libcygnal.la
+
+libcygnal_la_SOURCES = crc.cpp cvm.cpp rtmp_server.cpp http_server.cpp  
proc.cpp
+libcygnal_la_LIBADD = 
+
 
 # Rebuild with GCC 4.x Mudflap support
 mudflap:

=== modified file 'cygnal/acinclude.m4'
--- a/cygnal/acinclude.m4       2009-03-05 19:35:09 +0000
+++ b/cygnal/acinclude.m4       2009-03-16 23:34:13 +0000
@@ -37,15 +37,12 @@
 dnl AC_PROG_INSTALL
 dnl AM_COMPILER_LIB
 
+dnl Build the cgibins server if specified.
 AC_DEFUN([CYGNAL_PATHS],
 [
 
-dnl For Asynchronous I/O
-dnl AC_CHECK_HEADERS(aio.h poll.h)
-
 AC_CHECK_HEADERS(poll.h epoll.h)
 
 dnl Look for the various ways of blocking while waiting for I/O
 AC_CHECK_FUNCS(pselect ppoll)
- 
 ])

=== added directory 'cygnal/cgi-bin'
=== added file 'cygnal/cgi-bin/Makefile.am'
--- a/cygnal/cgi-bin/Makefile.am        1970-01-01 00:00:00 +0000
+++ b/cygnal/cgi-bin/Makefile.am        2009-02-21 15:37:21 +0000
@@ -0,0 +1,20 @@
+## Process this file with automake to generate Makefile.in
+# 
+#   Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+AUTOMAKE_OPTIONS = 
+
+SUBDIRS = echo # oflademo

=== added directory 'cygnal/cgi-bin/echo'
=== added file 'cygnal/cgi-bin/echo/Makefile.am'
--- a/cygnal/cgi-bin/echo/Makefile.am   1970-01-01 00:00:00 +0000
+++ b/cygnal/cgi-bin/echo/Makefile.am   2009-03-16 23:34:13 +0000
@@ -0,0 +1,56 @@
+## Process this file with automake to generate Makefile.in
+# 
+#   Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+AUTOMAKE_OPTIONS = 
+
+# this is where Gnash plugins get installed
+cgidir = $(libdir)/gnash/cygnal
+
+bin_PROGRAMS = echo gateway
+
+GNASH_LIBS = \
+       $(top_builddir)/libbase/libgnashbase.la \
+       $(top_builddir)/libamf/libgnashamf.la \
+       $(top_builddir)/libnet/libgnashnet.la \
+       $(PTHREAD_LIBS) \
+       $(BOOST_CFLAGS) \
+       $(NULL)
+
+INCLUDES = \
+            -I$(top_srcdir)/libbase \
+           -I$(top_srcdir)/libamf \
+           -I$(top_srcdir)/libnet \
+           -I$(top_srcdir)/libcore \
+           -I$(top_srcdir)/cygnal \
+           $(BOOST_CFLAGS)
+
+echo_SOURCES = echo.cpp echo.h
+echo_LDFLAGS = # -module -avoid-version -no-undefined
+echo_LDADD =  $(GNASH_LIBS) $(top_builddir)/cygnal/libcygnal.la
+
+gateway_SOURCES = gateway.cpp echo.h 
+gateway_LDFLAGS = # -module -avoid-version -no-undefined
+gateway_LDADD = $(GNASH_LIBS) $(top_builddir)/cygnal/libcygnal.la
+
+
+CLEANFILES = \
+      gnash-dbg.log
+
+# install-cgiLTLIBRARIES: $(cgi_LTLIBRARIES)
+#      test -d "$(DESTDIR)$(cgidir)" || $(mkinstalldirs) "$(DESTDIR)$(cgidir)"
+#      $(LIBTOOL) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) 
$(cgi_LTLIBRARIES) "$(DESTDIR)$(cgidir)/$(cgi_LTLIBRARIES)"
+#      $(RM) $(DESTDIR)$(cgidir)/*.a 

=== added file 'cygnal/cgi-bin/echo/echo.cpp'
--- a/cygnal/cgi-bin/echo/echo.cpp      1970-01-01 00:00:00 +0000
+++ b/cygnal/cgi-bin/echo/echo.cpp      2009-03-16 23:34:13 +0000
@@ -0,0 +1,256 @@
+// Red5 server side support for the echo_test via RTMP
+// 
+//   Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#include <string>
+#include <log.h>
+#include <iostream>
+#include <string>
+#include <boost/shared_ptr.hpp>
+
+// Gnash headers
+#include "amf.h"
+#include "arg_parser.h"
+#include "buffer.h"
+#include "network.h"
+#include "element.h"
+
+// cygnal headers
+#include "echo.h"
+
+using namespace amf;
+using namespace gnash;
+using namespace std;
+using namespace cygnal;
+
+static void usage (void);
+
+LogFile& dbglogfile = LogFile::getDefaultInstance();
+
+// Toggles very verbose debugging info from the network Network class
+static bool netdebug = false;
+
+int
+main(int argc, char *argv[])
+{
+    int port = 1234;
+    bool done = false;
+    
+    dbglogfile.setLogFilename("echo-test.log");
+//    dbglogfile.setWriteDisk(true);
+
+    const Arg_parser::Option opts[] =
+        {
+            { 'h', "help",          Arg_parser::no  },
+            { 'v', "verbose",       Arg_parser::no  },
+            { 'd', "dump",          Arg_parser::no  },
+            { 'n', "netdebug",      Arg_parser::no  },
+            { 'p', "port",          Arg_parser::yes  },
+        };
+    
+    Arg_parser parser(argc, argv, opts);
+    if( ! parser.error().empty() ) {
+        log_error("%s", parser.error());
+        exit(EXIT_FAILURE);
+    }
+
+    string infile;
+    
+    for( int i = 0; i < parser.arguments(); ++i ) {
+        const int code = parser.code(i);
+        try {
+            switch( code ) {
+              case 'h':
+                  usage ();
+                  exit(EXIT_SUCCESS);
+              case 'v':
+                    dbglogfile.setVerbosity();
+                    // This happens once per 'v' flag 
+                    log_debug(_("Verbose output turned on"));
+                    break;
+              case 'n':
+                  netdebug = true;
+                  break;
+              case 'p':
+                  port = parser.argument<int>(i);
+                  break;
+              case 0:
+                  infile = parser.argument(i);
+                  break;
+              default:
+                  break;
+           }
+        }
+        
+        catch (Arg_parser::ArgParserException &e) {
+            log_error(_("Error parsing command line options: %s"), e.what());
+        }
+    }
+
+    EchoTest net;
+    int netfd;
+    
+    if (infile.empty()) {
+        if (netdebug) {
+            net.toggleDebug(true);
+        }
+        int fd = net.createServer(port);
+        // Only wait for a limited time.
+        net.setTimeout(10);
+        netfd = net.newConnection(false, fd);
+    }
+    
+    // This is the main message processing loop for rtmp. All message received 
require
+    // a response.
+    do {
+        boost::shared_ptr<amf::Buffer> bufptr(new amf::Buffer);
+        if (infile.empty()) {
+            net.readNet(netfd, *bufptr);
+        } else {
+            DiskStream filestream(infile);
+            filestream.loadToMem(0);
+            int ret = net.writeNet(netfd, filestream.get(), 
filestream.getPagesize());
+            if (ret <= 0) {
+                break;
+            }
+        }
+        
+        vector<boost::shared_ptr<amf::Element> > request = 
net.parseEchoRequest(
+            bufptr->reference(), bufptr->allocated());
+        if (request[3]) {
+            boost::shared_ptr<amf::Buffer> result = 
net.formatEchoResponse(request[1]->to_number(), *request[3]);
+            if (net.writeNet(netfd, *result)) {
+                log_debug("Sent echo test response response to client.");
+            }
+        } else {
+            log_error("Couldn't send echo test response to client!");
+            done = true;
+        }
+    } while (!done);
+}
+
+EchoTest::EchoTest()
+{
+//    GNASH_REPORT_FUNCTION;
+}
+
+EchoTest::~EchoTest()
+{
+//    GNASH_REPORT_FUNCTION;
+}
+
+// Parse an Echo Request message coming from the Red5 echo_test. This
+// method should only be used for testing purposes.
+vector<boost::shared_ptr<amf::Element > >
+EchoTest::parseEchoRequest(boost::uint8_t *ptr, size_t size)
+{
+//    GNASH_REPORT_FUNCTION;
+
+    AMF amf;
+    vector<boost::shared_ptr<amf::Element > > headers;
+
+    // The first element is the name of the test, 'echo'
+    boost::shared_ptr<amf::Element> el1 = amf.extractAMF(ptr, ptr+size);
+    ptr += amf.totalsize();
+    headers.push_back(el1);
+
+    // The second element is the number of the test,
+    boost::shared_ptr<amf::Element> el2 = amf.extractAMF(ptr, ptr+size);
+    ptr += amf.totalsize();
+    headers.push_back(el2);
+
+    // This one has always been a NULL object from my tests
+    boost::shared_ptr<amf::Element> el3 = amf.extractAMF(ptr, ptr+size);
+    ptr += amf.totalsize();
+    headers.push_back(el3);
+
+    // This one has always been an NULL or Undefined object from my tests
+    boost::shared_ptr<amf::Element> el4 = amf.extractAMF(ptr, ptr+size);
+    if (!el4) {
+       log_error("Couldn't reliably extract the echo data!");
+    }
+    ptr += amf.totalsize();
+    headers.push_back(el4);
+    
+    return headers;
+}
+
+// format a response to the 'echo' test used for testing Gnash. This
+// is only used for testing by developers. The format appears to be
+// a string '_result', followed by the number of the test, and then two
+// NULL objects.
+boost::shared_ptr<amf::Buffer>
+EchoTest::formatEchoResponse(double num, amf::Element &el)
+{
+//    GNASH_REPORT_FUNCTION;
+    boost::shared_ptr<amf::Buffer> data = amf::AMF::encodeElement(el);
+    return formatEchoResponse(num, data->reference(), data->allocated());
+}
+
+boost::shared_ptr<amf::Buffer>
+EchoTest::formatEchoResponse(double num, amf::Buffer &data)
+{
+//    GNASH_REPORT_FUNCTION;
+    return formatEchoResponse(num, data.reference(), data.allocated());
+}
+
+boost::shared_ptr<amf::Buffer>
+EchoTest::formatEchoResponse(double num, boost::uint8_t *data, size_t size)
+{
+//    GNASH_REPORT_FUNCTION;
+
+    string result = "_result";
+    Element echo;
+    echo.makeString(result);
+
+    Element index;
+    index.makeNumber(num);
+
+    Element null;
+    null.makeNull();
+
+    boost::shared_ptr<amf::Buffer> encecho = echo.encode();
+    boost::shared_ptr<amf::Buffer> encidx  = index.encode();   
+    boost::shared_ptr<amf::Buffer> encnull  = null.encode();   
+
+    boost::shared_ptr<amf::Buffer> buf(new amf::Buffer(encecho->size()
+                                                      + encidx->size()
+                                                      + encnull->size() + 
size));
+
+    *buf = encecho;
+    *buf += encidx;
+    *buf += encnull;
+    buf->append(data, size);
+
+    return buf;
+}
+
+static void
+usage (void)
+{
+    cerr << "This program tests AMF support in the AMF library." << endl
+         << endl
+         << _("Usage: test_amf [options...]") << endl
+         << _("  -h,  --help          Print this help and exit") << endl
+         << _("  -v,  --verbose       Output verbose debug info") << endl
+        << _("  -n,  --netdebug      Turn on net debugging messages") << endl
+         << endl;
+}

=== added file 'cygnal/cgi-bin/echo/echo.h'
--- a/cygnal/cgi-bin/echo/echo.h        1970-01-01 00:00:00 +0000
+++ b/cygnal/cgi-bin/echo/echo.h        2009-03-16 23:34:13 +0000
@@ -0,0 +1,67 @@
+// Red5 server side support for the echo_test via RTMP
+// 
+//   Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+#ifndef _ECHO_H_
+#define _ECHO_H_
+
+#include <string>
+#include <map>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+#include <boost/shared_array.hpp>
+#include <boost/scoped_array.hpp>
+#include <sstream>
+
+// gnash headers
+#include "amf.h"
+#include "buffer.h"
+#include "element.h"
+#include "http.h"
+
+// cygnal headers
+#include "rtmp_server.h"
+
+namespace cygnal
+{
+    
+class EchoTest : public cygnal::RTMPServer
+{
+public:
+    EchoTest ();
+    ~EchoTest ();
+  
+    // Parse an Echo Request message coming from the Red5 echo_test.
+    std::vector<boost::shared_ptr<amf::Element > > 
parseEchoRequest(amf::Buffer &buf)
+        { return parseEchoRequest(buf.reference(), buf.size()); };
+    std::vector<boost::shared_ptr<amf::Element > > 
parseEchoRequest(boost::uint8_t *buf, size_t size);
+    
+    // format a response to the 'echo' test used for testing Gnash.
+    boost::shared_ptr<amf::Buffer> formatEchoResponse(double num, amf::Element 
&el);
+    boost::shared_ptr<amf::Buffer> formatEchoResponse(double num, amf::Buffer 
&data);
+    boost::shared_ptr<amf::Buffer> formatEchoResponse(double num, 
boost::uint8_t *data, size_t size);
+private:
+    
+};  
+
+} // end of cygnal namespace
+#endif  // end of __ECHO_H__
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

=== added file 'cygnal/cgi-bin/echo/gateway.cpp'
--- a/cygnal/cgi-bin/echo/gateway.cpp   1970-01-01 00:00:00 +0000
+++ b/cygnal/cgi-bin/echo/gateway.cpp   2009-03-16 23:34:13 +0000
@@ -0,0 +1,382 @@
+// Red5 server side support for the echo_test via HTTP
+// 
+//   Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#include <string>
+#include <log.h>
+#include <iostream>
+#include <string>
+#include <boost/shared_ptr.hpp>
+
+#include "amf.h"
+#include "arg_parser.h"
+#include "buffer.h"
+#include "network.h"
+#include "element.h"
+
+#include "gateway.h"
+#include "diskstream.h"
+
+using namespace amf;
+using namespace gnash;
+using namespace std;
+using namespace cygnal;
+
+static void usage (void);
+
+LogFile& dbglogfile = LogFile::getDefaultInstance();
+
+// Toggles very verbose debugging info from the network Network class
+static bool netdebug = false;
+
+int
+main(int argc, char *argv[])
+{
+    int port = 1234;
+    bool done = false;
+    bool gdb = false;
+    
+    dbglogfile.setLogFilename("gateway-test.log");
+//    dbglogfile.setWriteDisk(true);
+
+    const Arg_parser::Option opts[] =
+        {
+            { 'h', "help",          Arg_parser::no  },
+            { 'v', "verbose",       Arg_parser::no  },
+            { 'n', "netdebug",      Arg_parser::no  },
+            { 'p', "port",          Arg_parser::yes  },
+            { 'g', "gdb",           Arg_parser::no  },
+            { 'd', "dump",          Arg_parser::no  },
+        };
+    
+    Arg_parser parser(argc, argv, opts);
+    if( ! parser.error().empty() ) {
+        log_error("%s", parser.error());
+        exit(EXIT_FAILURE);
+    }
+
+    string infile;
+    
+    for( int i = 0; i < parser.arguments(); ++i ) {
+        const int code = parser.code(i);
+        try {
+            switch( code ) {
+              case 'h':
+                  usage ();
+                  exit(EXIT_SUCCESS);
+              case 'v':
+                    dbglogfile.setVerbosity();
+                    // This happens once per 'v' flag 
+                    log_debug(_("Verbose output turned on"));
+                    break;
+              case 'n':
+                  netdebug = true;
+                  break;
+              case 'g':
+                  gdb = true;
+                  break;
+              case 'p':
+                  port = parser.argument<int>(i);
+                  break;
+              case 0:
+                  infile = parser.argument(i);
+                  break;
+              default:
+                  break;
+           }
+        }
+        
+        catch (Arg_parser::ArgParserException &e) {
+            log_error(_("Error parsing command line options: %s"), e.what());
+        }
+    }
+
+    // if set, wait for us to connectGDB for debugging
+    while (gdb) {
+        cout << "Waiting for GDB " << getpid() << endl;
+        sleep(5);
+    }
+    
+    
+    GatewayTest net;
+
+    if (netdebug) {
+       net.toggleDebug(true);
+    }
+
+    int fd = 0;
+    int netfd = 0;
+    if (infile.empty()) {
+        fd = net.createServer(port);
+        if (fd <= 0) {
+            exit(1);
+        }
+        // Only wait for a limited time.
+        net.setTimeout(10);
+//        netfd = net.newConnection(false, fd);
+    }
+    
+    // Wait for data, and when we get it, process it.
+    boost::shared_ptr<amf::Buffer> content;
+    vector<boost::shared_ptr<amf::Element> > headers;
+    int ret = 0;
+    net.setTimeout(10);
+    do {
+        netfd = net.newConnection(false, fd);
+        if (netfd <= 0) {
+            done = true;
+            break;
+        }
+        // See if we have any messages waiting
+        if (infile.empty()) {
+            boost::shared_ptr<amf::Buffer> content = net.readNet();
+            if (!content) {
+                done = true;
+                break;
+            }
+//            content->dump();
+            headers = net.parseEchoRequest(*content);
+        } else {
+            DiskStream filestream;
+            filestream.open(infile);
+            filestream.loadToMem(0);
+            headers = net.parseEchoRequest(filestream.get(), 
filestream.getPagesize());
+            filestream.close();
+            done = true;
+            break;
+        }
+        
+       //boost::shared_ptr<amf::Element> &el0 = headers[0];
+       
+        if (!done) {
+            if (headers.size() >= 4) {
+                if (headers[3]) {
+                    amf::Buffer reply;
+                    if (headers[1]->getNameSize()) {
+                        reply = net.formatEchoResponse(headers[1]->getName(), 
*headers[3]);
+                    } else {
+                        reply = net.formatEchoResponse("no name", *headers[3]);
+                    }
+                    
+                    if (infile.empty()) {
+                        int ret = net.writeNet(netfd, reply);
+                        if (ret <= 0) {
+//                        reply.dump();
+                            // For now exit after only one packet
+                            done = true;
+                        }
+                    } else {
+                        cerr << hexify(reply.reference(), reply.allocated(), 
true) << endl;
+                    }
+                }
+            }
+        }
+    } while(done != true);
+
+    net.closeNet();
+}
+
+GatewayTest::GatewayTest()
+{
+//    GNASH_REPORT_FUNCTION;
+}
+
+GatewayTest::~GatewayTest()
+{
+//    GNASH_REPORT_FUNCTION;
+}
+
+// Parse an Echo Request message coming from the Red5 echo_test. This
+// method should only be used for testing purposes.
+vector<boost::shared_ptr<amf::Element > >
+GatewayTest::parseEchoRequest(boost::uint8_t *data, size_t size)
+{
+//    GNASH_REPORT_FUNCTION;
+    
+    vector<boost::shared_ptr<amf::Element > > headers;
+       
+    // skip past the header bytes, we don't care about them.
+    boost::uint8_t *tmpptr = data + 6;
+    
+    boost::uint16_t length;
+    length = ntohs((*(boost::uint16_t *)tmpptr) & 0xffff);
+    tmpptr += sizeof(boost::uint16_t);
+
+    // Get the first name, which is a raw string, and not preceded by
+    // a type byte.
+    boost::shared_ptr<amf::Element > el1(new amf::Element);
+    
+    // If the length of the name field is corrupted, then we get out of
+    // range quick, and corrupt memory. This is a bit of a hack, but
+    // reduces memory errors caused by some of the corrupted tes cases.
+    boost::uint8_t *endstr = std::find(tmpptr, tmpptr+length, '\0');
+    if (endstr != tmpptr+length) {
+       log_debug("Caught corrupted string! length was %d, null at %d",
+                 length,  endstr-tmpptr);
+       length = endstr-tmpptr;
+    }
+    el1->setName(tmpptr, length);
+    tmpptr += length;
+    headers.push_back(el1);
+    
+    // Get the second name, which is a raw string, and not preceded by
+    // a type byte.
+    length = ntohs((*(boost::uint16_t *)tmpptr) & 0xffff);
+    tmpptr += sizeof(boost::uint16_t);
+    boost::shared_ptr<amf::Element > el2(new amf::Element);
+
+//     std::string name2(reinterpret_cast<const char *>(tmpptr), length);
+//     el2->setName(name2.c_str(), name2.size());
+    // If the length of the name field is corrupted, then we get out of
+    // range quick, and corrupt memory. This is a bit of a hack, but
+    // reduces memory errors caused by some of the corrupted tes cases.
+    endstr = std::find(tmpptr, tmpptr+length, '\0');
+    if (endstr != tmpptr+length) {
+       log_debug("Caught corrupted string! length was %d, null at %d",
+                 length,  endstr-tmpptr);
+       length = endstr-tmpptr;
+    }
+    el2->setName(tmpptr, length);
+    headers.push_back(el2);
+    tmpptr += length;
+
+    // Get the last two pieces of data, which are both AMF encoded
+    // with a type byte.
+    amf::AMF amf;
+    boost::shared_ptr<amf::Element> el3 = amf.extractAMF(tmpptr, tmpptr + 
size);
+    headers.push_back(el3);
+    tmpptr += amf.totalsize();
+    
+    boost::shared_ptr<amf::Element> el4 = amf.extractAMF(tmpptr, tmpptr + 
size);
+    headers.push_back(el4);
+
+     return headers;
+}
+
+// format a response to the 'echo' test used for testing Gnash. This
+// is only used for testing by developers. The format appears to be
+// two strings, followed by a double, followed by the "onResult".
+amf::Buffer &
+GatewayTest::formatEchoResponse(const std::string &num, amf::Element &el)
+{
+//    GNASH_REPORT_FUNCTION;
+    boost::shared_ptr<amf::Buffer> data;
+
+    amf::Element nel;
+    if (el.getType() == amf::Element::TYPED_OBJECT_AMF0) {
+       nel.makeTypedObject();
+       string name = el.getName();
+       nel.setName(name);
+       if (el.propertySize()) {
+           // FIXME: see about using std::reverse() instead.
+           for (int i=el.propertySize()-1; i>=0; i--) {
+//         for (int i=0 ; i<el.propertySize(); i++) {
+               boost::shared_ptr<amf::Element> child = el.getProperty(i);
+               nel.addProperty(child);
+           }
+           data = nel.encode();
+       } else {
+           data = el.encode();
+       }
+    } else {
+       data = el.encode();
+    }
+
+    return formatEchoResponse(num, data->reference(), data->allocated());
+}
+
+amf::Buffer &
+GatewayTest::formatEchoResponse(const std::string &num, amf::Buffer &data)
+{
+//    GNASH_REPORT_FUNCTION;
+    return formatEchoResponse(num, data.reference(), data.allocated());
+}
+
+amf::Buffer &
+GatewayTest::formatEchoResponse(const std::string &num, boost::uint8_t *data, 
size_t size)
+{
+//    GNASH_REPORT_FUNCTION;
+
+    //boost::uint8_t *tmpptr  = data;
+    
+    // FIXME: temporary hacks while debugging
+    amf::Buffer fixme("00 00 00 00 00 01");
+    amf::Buffer fixme2("ff ff ff ff");
+    
+    _buffer = "HTTP/1.1 200 OK\r\n";
+    formatContentType(DiskStream::FILETYPE_AMF);
+//    formatContentLength(size);
+    // FIXME: this is a hack ! Calculate a real size!
+    formatContentLength(size+29);
+    
+    // Pretend to be Red5 server
+    formatServer("Jetty(6.1.7)");
+    
+    // All HTTP messages are followed by a blank line.
+    terminateHeader();
+
+    // Add the binary blob for the header
+    _buffer += fixme;
+
+    // Make the result response, which is the 2nd data item passed in
+    // the request, a slash followed by a number like "/2".
+    string result = num;
+    result += "/onResult";
+    boost::shared_ptr<amf::Buffer> res = amf::AMF::encodeString(result);
+    _buffer.append(res->begin()+1, res->size()-1);
+
+    // Add the null data item
+    boost::shared_ptr<amf::Buffer> null = amf::AMF::encodeString("null");
+    _buffer.append(null->begin()+1, null->size()-1);
+
+    // Add the other binary blob
+    _buffer += fixme2;
+
+    amf::Element::amf0_type_e type = 
static_cast<amf::Element::amf0_type_e>(*data);
+    if ((type == amf::Element::UNSUPPORTED_AMF0)
+       || (type == amf::Element::NULL_AMF0)) {
+       _buffer += type;
+       // Red5 returns a NULL object when it's recieved an undefined one in 
the echo_test
+    } else if (type == amf::Element::UNDEFINED_AMF0) {
+       _buffer += amf::Element::NULL_AMF0;
+    } else {
+       // Add the AMF data we're echoing back
+       if (size) {
+           _buffer.append(data, size);
+       }
+    }
+    
+    return _buffer;
+}
+
+static void
+usage (void)
+{
+    cerr << "This program tests AMF support in the AMF library." << endl
+         << endl
+         << _("Usage: test_amf [options...]") << endl
+         << _("  -h,  --help          Print this help and exit") << endl
+         << _("  -v,  --verbose       Output verbose debug info") << endl
+        << _("  -n,  --netdebug      Turn on net debugging messages") << endl
+         << endl;
+}
+
+

=== added file 'cygnal/cgi-bin/echo/gateway.h'
--- a/cygnal/cgi-bin/echo/gateway.h     1970-01-01 00:00:00 +0000
+++ b/cygnal/cgi-bin/echo/gateway.h     2009-03-16 23:34:13 +0000
@@ -0,0 +1,64 @@
+// Red5 server side support for the echo_test via HTTP
+// 
+//   Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+#ifndef _GATEWAY_H_
+#define _GATEWAY_H_
+
+#include <string>
+#include <map>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+#include <boost/shared_array.hpp>
+#include <boost/scoped_array.hpp>
+#include <sstream>
+
+#include "amf.h"
+#include "buffer.h"
+#include "element.h"
+#include "rtmp.h"
+
+#include "http.h"
+
+namespace cygnal
+{
+  
+class GatewayTest : public gnash::HTTP
+{
+public:
+    GatewayTest ();
+    ~GatewayTest ();
+
+    // Parse an Echo Request message coming from the Red5 echo_test.
+    std::vector<boost::shared_ptr<amf::Element > > 
parseEchoRequest(amf::Buffer &buf)
+        { return parseEchoRequest(buf.reference(), buf.size()); };
+    std::vector<boost::shared_ptr<amf::Element > > 
parseEchoRequest(boost::uint8_t *buf, size_t size);
+
+    // format a response to the 'echo' test used for testing Gnash.
+    amf::Buffer &formatEchoResponse(const std::string &num, amf::Element &el);
+    amf::Buffer &formatEchoResponse(const std::string &num, amf::Buffer &data);
+    amf::Buffer &formatEchoResponse(const std::string &num, boost::uint8_t 
*data, size_t size);
+private:
+};
+
+} // end of cygnal namespace
+#endif  // end of __GATEWAY_H__
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

=== modified file 'cygnal/crc.cpp'
--- a/cygnal/crc.cpp    2009-03-19 23:14:43 +0000
+++ b/cygnal/crc.cpp    2009-04-05 22:01:27 +0000
@@ -186,6 +186,16 @@
                 continue;
             }
 
+            if (noCaseCompare(variable, "cgiroot") ) {
+                setCgiRoot(value);
+                continue;
+            }
+
+            if (noCaseCompare(variable, "documentroot") ) {
+                _wwwroot = value;
+                continue;
+            }
+            
             bool test;
             bool threads;
            bool netdebug;

=== modified file 'cygnal/crc.h'
--- a/cygnal/crc.h      2009-02-25 22:33:03 +0000
+++ b/cygnal/crc.h      2009-03-16 23:34:13 +0000
@@ -97,15 +97,29 @@
     /// @remarks This should only be used for debugging purposes.
     void dump() const { dump(std::cerr); }
     
+    void setDocumentRoot(const std::string &x) { _wwwroot = x; }
+    std::string getDocumentRoot() { return _wwwroot; }
+    
+    void setCgiRoot(const std::string &x) { _cgiroot = x; }
+    std::string getCgiRoot() { return _cgiroot; }
+    
     /// \overload dump(std::ostream& os) const
     void dump(std::ostream& os) const;
     
-  private:
     /// Construct only by getDefaultInstance()
     CRcInitFile();
     /// Never destroy (TODO: add a destroyDefaultInstance)
     ~CRcInitFile();
     
+  private:
+    /// \var _wwwroot
+    ///                The root path for the streaming server to find al files.
+    std::string _wwwroot;
+    
+    /// \var _cgiroot;
+    ///                This specifies the default directory for all cgi 
(exeutables).
+    std::string _cgiroot;
+
     /// \var _port_offset
     ///                This is an offset applied to all priviledged tcp/ip
     ///                ports. This enables the port number to be shifted into
@@ -140,6 +154,7 @@
     ///                This toggles whether the admin thread is started or
     ///                not, also to reduce complecity when debugging.
     bool _admin;
+
 };
 
 /// \brief Dump to the specified output stream.

=== modified file 'cygnal/cygnal.cpp'
--- a/cygnal/cygnal.cpp 2009-03-19 23:14:43 +0000
+++ b/cygnal/cygnal.cpp 2009-04-05 22:01:27 +0000
@@ -53,9 +53,9 @@
 #include "network.h"
 #include "log.h"
 #include "crc.h"
+#include "proc.h"
 #include "rtmp.h"
-#include "rtmp_server.h"
-#include "http.h"
+#include "buffer.h"
 #include "utility.h"
 #include "limits.h"
 #include "netstats.h"
@@ -68,7 +68,9 @@
 #include "GnashSleep.h" // for usleep comptibility.
 
 // classes internal to Cygnal
-#include "buffer.h"
+#include "rtmp_server.h"
+#include "http_server.h"
+
 #include "handler.h"
 #include "cache.h"
 #include "gettext.h"
@@ -145,13 +147,18 @@
 
 // end of globals
 
+// The debug log used by all the gnash libraries.
 static LogFile& dbglogfile = LogFile::getDefaultInstance();
 
-// The rcfile is loaded and parsed here:
+// The user config for Cygnal is loaded and parsed here:
 static CRcInitFile& crcfile = CRcInitFile::getDefaultInstance();
 
+// Cache support for responses and files.
 static Cache& cache = Cache::getDefaultInstance();
 
+// The list of active cgis beiung executed.
+static std::map<std::string, Proc> procs; // = proc::getDefaultInstance();
+
 // This mutex is used to signify when all the threads are done.
 static boost::condition        alldone;
 static boost::mutex    alldone_mutex;
@@ -670,25 +677,31 @@
                    if ((it->revents & POLLRDHUP) || (it->revents & POLLNVAL))  
{
                        log_debug("Revents has a POLLRDHUP or POLLNVAL set to 
%d for fd #%d",
                                  it->revents, it->fd);
-                       net->erasePollFD(it->fd);
-                       net->closeNet(it->fd);
+                       if (it->fd > 0) {
+                           net->erasePollFD(it->fd);
+                           net->closeNet(it->fd);
+                       }
 //                     continue;
                        break;
                    } else {
                        // We got some data, so process it
                        log_debug("Got something on fd #%d, 0x%x", it->fd, 
it->revents);
+                       if (it->fd > 0) {
+                           // Call the protocol handler for this network 
connection
+                           bool ret = net->getEntry(it->fd)(args);
                        // Call the protocol handler for this network connection
 //                     bool ret = net->getEntry(it->fd)(args);
                        
 //                     log_debug("Handler returned %s", (ret) ? "true" : 
"false");
-                       // FIXME: we currently force a 'close connection' at 
the end
-                       // of sending a file, since apache does too. This 
pretty much
-                       // blows persistance,
+                           // FIXME: we currently force a 'close connection' 
at the end
+                           // of sending a file, since apache does too. This 
pretty much
+                           // blows persistance,
 //                     if (ret) {
                            networks[args->tid] = 0;
                            net->closeNet(it->fd);
                            net->erasePollFD(it->fd);
 //                     }
+                       }
                    }
                }
            } catch (std::exception& e) {

=== modified file 'cygnal/cygnal.h'
--- a/cygnal/cygnal.h   2009-02-25 22:33:03 +0000
+++ b/cygnal/cygnal.h   2009-03-16 23:34:13 +0000
@@ -27,7 +27,7 @@
 /// \class cygnal::ThreadCounter of threads currently
 ///     active. This is primarily so the counter can be wrapped with a
 ///     mutex to be thread safe, as threads delete themseleves.
-class DSOEXPORT ThreadCounter
+class ThreadCounter
 {
   public:
     ThreadCounter() : _tids(0) {};

=== added file 'cygnal/http_server.cpp'
--- a/cygnal/http_server.cpp    1970-01-01 00:00:00 +0000
+++ b/cygnal/http_server.cpp    2009-03-20 00:00:54 +0000
@@ -0,0 +1,1060 @@
+// http.cpp:  HyperText Transport Protocol handler for Cygnal, for Gnash.
+// 
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#include <boost/thread/mutex.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/shared_array.hpp>
+#include <boost/scoped_array.hpp>
+#include <boost/tokenizer.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/date_time/gregorian/gregorian.hpp>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string>
+#include <iostream>
+#include <cstring>
+#include <sstream>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <algorithm>
+#include "GnashSystemIOHeaders.h" // read()
+
+#include "amf.h"
+#include "element.h"
+#include "cque.h"
+#include "log.h"
+#include "crc.h"
+#include "network.h"
+#include "handler.h"
+#include "utility.h"
+#include "buffer.h"
+#include "diskstream.h"
+
+// Cygnal specific headers
+#include "http_server.h"
+#include "proc.h"
+#include "cache.h"
+
+// Not POSIX, so best not rely on it if possible.
+#ifndef PATH_MAX
+# define PATH_MAX 1024
+#endif
+
+using namespace gnash;
+using namespace std;
+
+static boost::mutex stl_mutex;
+
+namespace cygnal
+{
+
+// The rcfile is loaded and parsed here:
+static CRcInitFile& crcfile = CRcInitFile::getDefaultInstance();
+static Cache& cache = Cache::getDefaultInstance();
+// static Proc& cgis = Proc::getDefaultInstance();
+
+HTTPServer::HTTPServer() 
+{
+//    GNASH_REPORT_FUNCTION;
+}
+
+HTTPServer::~HTTPServer()
+{
+//    GNASH_REPORT_FUNCTION;
+}
+
+boost::shared_ptr<amf::Buffer>
+HTTPServer::processClientRequest(int fd)
+{
+//    GNASH_REPORT_FUNCTION;
+    boost::shared_ptr<amf::Buffer> buf(_que.peek());
+    boost::shared_ptr<amf::Buffer> result;
+    
+    if (buf) {
+       _cmd = extractCommand(buf->reference());
+       switch (_cmd) {
+         case HTTP::HTTP_GET:
+             result = processGetRequest(fd);
+             break;
+         case HTTP::HTTP_POST:
+             result = processPostRequest(fd);
+             break;
+         case HTTP::HTTP_HEAD:
+             result = processHeadRequest(fd);
+             break;
+         case HTTP::HTTP_CONNECT:
+             result = processConnectRequest(fd);
+             break;
+         case HTTP::HTTP_TRACE:
+             result = processTraceRequest(fd);
+             break;
+         case HTTP::HTTP_OPTIONS:
+             result = processOptionsRequest(fd);
+             break;
+         case HTTP::HTTP_PUT:
+             result = processPutRequest(fd);
+             break;
+         case HTTP::HTTP_DELETE:
+             result = processDeleteRequest(fd);
+             break;
+         default:
+             break;
+       }
+    }
+
+    return result;
+}
+
+// A GET request asks the server to send a file to the client
+boost::shared_ptr<amf::Buffer> 
+HTTPServer::processGetRequest(int fd)
+{
+    GNASH_REPORT_FUNCTION;
+
+//     boost::uint8_t buffer[readsize+1];
+//     const char *ptr = reinterpret_cast<const char *>(buffer);
+//     memset(buffer, 0, readsize+1);
+    
+//    _handler->wait();
+//    _handler->dump();
+
+    cerr << "QUE = " << _que.size() << endl;
+    boost::shared_ptr<amf::Buffer> buf;
+    
+    if (_que.size() == 0) {
+       return buf;
+    }
+    
+    buf = _que.pop();
+//    cerr << "YYYYYYY: " << (char *)buf->reference() << endl;
+//    cerr << hexify(buf->reference(), buf->allocated(), false) << endl;
+    
+    if (buf == 0) {
+     //        log_debug("Que empty, net connection dropped for fd #%d", 
getFileFd());
+       log_debug("Que empty, net connection dropped for fd #%d", fd);
+       return buf;
+    }
+    
+    clearHeader();
+    processHeaderFields(*buf);
+
+    string url = _docroot + _filespec;
+    // See if the file is in the cache and already opened.
+    boost::shared_ptr<DiskStream> filestream(cache.findFile(url));
+    if (filestream) {
+       cerr << "FIXME: found file in cache!" << endl;
+    } else {
+       filestream.reset(new DiskStream);
+//         cerr << "New Filestream at 0x" << hex << filestream.get() << endl;
+       
+//         cache.addFile(url, filestream);     FIXME: always reload from disk 
for now.
+       
+       // Oopen the file and read the first chunk into memory
+       if (filestream->open(url)) {
+           formatErrorResponse(HTTPServer::NOT_FOUND);
+       } else {
+           // Get the file size for the HTTPServer header
+           if (filestream->getFileType() == DiskStream::FILETYPE_NONE) {
+               formatErrorResponse(HTTPServer::NOT_FOUND);
+           } else {
+               cache.addPath(_filespec, filestream->getFilespec());
+           }
+       }
+    }
+    
+    // Send the reply
+    amf::Buffer &reply = formatHeader(filestream->getFileType(),
+                                         filestream->getFileSize(),
+                                         HTTPServer::OK);
+    writeNet(fd, reply);
+
+    size_t filesize = filestream->getFileSize();
+    size_t bytes_read = 0;
+    int ret;
+    size_t page = 0;
+    if (filesize) {
+#ifdef USE_STATS_CACHE
+       struct timespec start;
+       clock_gettime (CLOCK_REALTIME, &start);
+#endif
+       size_t getbytes = 0;
+       if (filesize <= filestream->getPagesize()) {
+           getbytes = filesize;
+       } else {
+           getbytes = filestream->getPagesize();
+       }
+       if (filesize >= CACHE_LIMIT) {
+           do {
+               filestream->loadToMem(page);
+               ret = writeNet(fd, filestream->get(), getbytes);
+               if (ret <= 0) {
+                   break;
+               }
+               bytes_read += ret;
+               page += filestream->getPagesize();
+           } while (bytes_read <= filesize);
+       } else {
+           filestream->loadToMem(filesize, 0);
+           ret = writeNet(fd, filestream->get(), filesize);
+       }
+       filestream->close();
+#ifdef USE_STATS_CACHE
+       struct timespec end;
+       clock_gettime (CLOCK_REALTIME, &end);
+       double time = (end.tv_sec - start.tv_sec) + ((end.tv_nsec - 
start.tv_nsec)/1e9);
+       cerr << "File " << _filespec
+            << " transferred " << filesize << " bytes in: " << fixed
+            << time << " seconds for net fd #" << fd << endl;
+#endif
+    }
+
+    log_debug("http_handler all done transferring requested file \"%s\".", 
_filespec);
+    
+    return buf;
+}
+
+// A POST request asks sends a data from the client to the server. After 
processing
+// the header like we normally do, we then read the amount of bytes specified 
by
+// the "content-length" field, and then write that data to disk, or decode the 
amf.
+boost::shared_ptr<amf::Buffer>
+HTTPServer::processPostRequest(int fd)
+{
+    GNASH_REPORT_FUNCTION;
+
+//    cerr << "QUE1 = " << _que.size() << endl;
+
+    boost::shared_ptr<amf::Buffer> buf;
+    
+    if (_que.size() == 0) {
+       return buf;
+    }
+    
+    buf = _que.pop();
+    if (buf == 0) {
+       log_debug("Que empty, net connection dropped for fd #%d", getFileFd());
+       return buf;
+    }
+//    cerr << __FUNCTION__ << buf->allocated() << " : " << 
hexify(buf->reference(), buf->allocated(), true) << endl;
+    
+    clearHeader();
+    boost::uint8_t *data = processHeaderFields(*buf);
+    size_t length = strtol(getField("content-length").c_str(), NULL, 0);
+    boost::shared_ptr<amf::Buffer> content(new amf::Buffer(length));
+    int ret = 0;
+    if (buf->allocated() - (data - buf->reference()) ) {
+//     cerr << "Don't need to read more data: have " << buf->allocated() << " 
bytes" << endl;
+       content->copy(data, length);
+       ret = length;
+    } else {   
+//     cerr << "Need to read more data, only have "  << buf->allocated() << " 
bytes" << endl;
+       ret = readNet(fd, *content, 2);
+       data = content->reference();
+    }    
+    
+    if (getField("content-type") == "application/x-www-form-urlencoded") {
+       log_debug("Got file data in POST");
+       string url = _docroot + _filespec;
+       DiskStream ds(url, *content);
+       ds.writeToDisk();
+//    ds.close();
+       // oh boy, we got ourselves some encoded AMF objects instead of a 
boring file.
+    } else if (getField("content-type") == "application/x-amf") {
+       log_debug("Got AMF data in POST");
+#if 0
+       amf::AMF amf;
+       boost::shared_ptr<amf::Element> el = 
amf.extractAMF(content.reference(), content.end());
+       el->dump();             // FIXME: do something intelligent
+                               // with this Element
+#endif
+    }
+    
+    // Send the reply
+
+    // NOTE: this is a "special" path we trap until we have real CGI support
+    if ((getField("content-type") == "application/x-amf")
+       && (getField("content-type") == "application/x-amf")) {
+#if 1
+       if (_filespec == "/echo/gateway") {
+       }
+       
+       Proc cgis;
+       string path = _docroot;
+//     string path = 
"/home/rob/projects/gnu/i686-pc-linux-gnu/gnash/rtmp/cygnal/cgi-bin";
+       path += _filespec;
+       
+       cgis.startCGI(_filespec, true, 1234);
+       cgis.createClient("localhost", 1234);
+       cgis.writeNet(*content);
+       boost::shared_ptr<amf::Buffer> reply = cgis.readNet();
+       writeNet(fd, *reply);
+//     cgis.stopCGI(_filespec);
+#else
+       vector<boost::shared_ptr<amf::Element> > headers = 
parseEchoRequest(*content);
+       //boost::shared_ptr<amf::Element> &el0 = headers[0];
+
+       if (headers.size() >= 4) {
+           if (headers[3]) {
+               amf::Buffer &reply = formatEchoResponse(headers[1]->getName(), 
*headers[3]);
+//         cerr << "FIXME 3: " << hexify(reply.reference(), reply.allocated(), 
true) << endl;
+//         cerr << "FIXME 3: " << hexify(reply.reference(), reply.allocated(), 
false) << endl;
+               writeNet(fd, reply);
+           }
+       }
+#endif
+    } else {
+       amf::Buffer &reply = formatHeader(_filetype, _filesize, HTTPServer::OK);
+       writeNet(fd, reply);
+    }
+
+    return buf;
+}
+
+boost::shared_ptr<amf::Buffer>
+HTTPServer::processPutRequest(int /* fd */)
+{
+    boost::shared_ptr<amf::Buffer> buf;
+//    GNASH_REPORT_FUNCTION;
+    log_unimpl("PUT request");
+
+    return buf;
+}
+
+boost::shared_ptr<amf::Buffer> 
+HTTPServer::processDeleteRequest(int /* fd */)
+{
+//    GNASH_REPORT_FUNCTION;
+    boost::shared_ptr<amf::Buffer> buf;
+    log_unimpl("DELETE request");
+    
+    return buf;
+}
+
+boost::shared_ptr<amf::Buffer> 
+HTTPServer::processConnectRequest(int /* fd */)
+{
+//    GNASH_REPORT_FUNCTION;
+    boost::shared_ptr<amf::Buffer> buf;
+    log_unimpl("CONNECT request");
+
+    return buf;
+}
+
+boost::shared_ptr<amf::Buffer>
+HTTPServer::processOptionsRequest(int /* fd */)
+{
+//    GNASH_REPORT_FUNCTION;
+    boost::shared_ptr<amf::Buffer> buf;
+    log_unimpl("OPTIONS request");
+
+    return buf;
+}
+
+boost::shared_ptr<amf::Buffer>
+HTTPServer::processHeadRequest(int /* fd */)
+{
+//    GNASH_REPORT_FUNCTION;
+    boost::shared_ptr<amf::Buffer> buf;
+    log_unimpl("HEAD request");
+    
+    return buf;
+}
+
+boost::shared_ptr<amf::Buffer>
+HTTPServer::processTraceRequest(int /* fd */)
+{
+//    GNASH_REPORT_FUNCTION;
+    boost::shared_ptr<amf::Buffer> buf;
+    log_unimpl("TRACE request");
+    
+    return buf;
+}
+
+amf::Buffer &
+HTTPServer::formatErrorResponse(http_status_e code)
+{
+//    GNASH_REPORT_FUNCTION;
+
+    char num[12];
+    // First build the message body, so we know how to set Content-Length
+    _buffer += "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n";
+    _buffer += "<html><head>\r\n";
+    _buffer += "<title>";
+    sprintf(num, "%d", code);
+    _buffer += num;
+    _buffer += " Not Found</title>\r\n";
+    _buffer += "</head><body>\r\n";
+    _buffer += "<h1>Not Found</h1>\r\n";
+    _buffer += "<p>The requested URL ";
+    _buffer += _filespec;
+    _buffer += " was not found on this server.</p>\r\n";
+    _buffer += "<hr>\r\n";
+    _buffer += "<address>Cygnal (GNU/Linux) Server at ";
+    _buffer += getField("host");
+    _buffer += " </address>\r\n";
+    _buffer += "</body></html>\r\n";
+
+    // First build the header
+    formatDate();
+    formatServer();
+    formatContentLength(_filesize);
+    formatConnection("close");
+    formatContentType(_filetype);
+
+    // All HTTPServer messages are followed by a blank line.
+    terminateHeader();
+
+    return _buffer;
+}
+
+amf::Buffer &
+HTTPServer::formatGetReply(http_status_e code)
+{
+
+//    GNASH_REPORT_FUNCTION;
+    
+    return formatHeader(_filesize, code);
+}
+
+amf::Buffer &
+HTTPServer::formatGetReply(size_t size, http_status_e code)
+{
+//    GNASH_REPORT_FUNCTION;
+    
+    formatHeader(size, code);
+    
+//    int ret = Network::writeNet(_header.str());    
+//    boost::uint8_t *ptr = (boost::uint8_t *)_body.str().c_str();
+//     buf->copy(ptr, _body.str().size());
+//    _handler->dump();
+
+#if 0
+    if (_header.str().size()) {
+        log_debug (_("Sent GET Reply"));
+       return _buffer;
+    } else {
+       clearHeader();
+       log_debug (_("Couldn't send GET Reply, no header data"));
+    }    
+#endif
+    
+    return _buffer;
+}
+
+amf::Buffer &
+HTTPServer::formatPostReply(rtmpt_cmd_e /* code */)
+{
+    GNASH_REPORT_FUNCTION;
+
+    formatDate();
+    formatServer();
+    formatContentType(DiskStream::FILETYPE_AMF);
+    // All HTTPServer messages are followed by a blank line.
+    terminateHeader();
+    return _buffer;
+
+#if 0
+    formatHeader(_filesize, code);
+    boost::shared_ptr<amf::Buffer> buf = new amf::Buffer;
+    if (_header.str().size()) {
+       buf->resize(_header.str().size());
+       string str = _header.str();
+       buf->copy(str);
+       _handler->pushout(buf);
+       _handler->notifyout();
+        log_debug (_("Sent GET Reply"));
+       return true; // Default to true
+    } else {
+       clearHeader();
+       log_debug (_("Couldn't send POST Reply, no header data"));
+    }
+#endif
+
+    return _buffer;
+}
+
+#if 0
+// Parse an Echo Request message coming from the Red5 echo_test. This
+// method should only be used for testing purposes.
+vector<boost::shared_ptr<amf::Element > >
+HTTPServer::parseEchoRequest(boost::uint8_t *data, size_t size)
+{
+//    GNASH_REPORT_FUNCTION;
+    
+    vector<boost::shared_ptr<amf::Element > > headers;
+       
+    // skip past the header bytes, we don't care about them.
+    boost::uint8_t *tmpptr = data + 6;
+    
+    boost::uint16_t length;
+    length = ntohs((*(boost::uint16_t *)tmpptr) & 0xffff);
+    tmpptr += sizeof(boost::uint16_t);
+
+    // Get the first name, which is a raw string, and not preceded by
+    // a type byte.
+    boost::shared_ptr<amf::Element > el1(new amf::Element);
+    
+    // If the length of the name field is corrupted, then we get out of
+    // range quick, and corrupt memory. This is a bit of a hack, but
+    // reduces memory errors caused by some of the corrupted tes cases.
+    boost::uint8_t *endstr = std::find(tmpptr, tmpptr+length, '\0');
+    if (endstr != tmpptr+length) {
+       log_debug("Caught corrupted string! length was %d, null at %d",
+                 length,  endstr-tmpptr);
+       length = endstr-tmpptr;
+    }
+    el1->setName(tmpptr, length);
+    tmpptr += length;
+    headers.push_back(el1);
+    
+    // Get the second name, which is a raw string, and not preceded by
+    // a type byte.
+    length = ntohs((*(boost::uint16_t *)tmpptr) & 0xffff);
+    tmpptr += sizeof(boost::uint16_t);
+    boost::shared_ptr<amf::Element > el2(new amf::Element);
+
+//     std::string name2(reinterpret_cast<const char *>(tmpptr), length);
+//     el2->setName(name2.c_str(), name2.size());
+    // If the length of the name field is corrupted, then we get out of
+    // range quick, and corrupt memory. This is a bit of a hack, but
+    // reduces memory errors caused by some of the corrupted tes cases.
+    endstr = std::find(tmpptr, tmpptr+length, '\0');
+    if (endstr != tmpptr+length) {
+       log_debug("Caught corrupted string! length was %d, null at %d",
+                 length,  endstr-tmpptr);
+       length = endstr-tmpptr;
+    }
+    el2->setName(tmpptr, length);
+    headers.push_back(el2);
+    tmpptr += length;
+
+    // Get the last two pieces of data, which are both AMF encoded
+    // with a type byte.
+    amf::AMF amf;
+    boost::shared_ptr<amf::Element> el3 = amf.extractAMF(tmpptr, tmpptr + 
size);
+    headers.push_back(el3);
+    tmpptr += amf.totalsize();
+    
+    boost::shared_ptr<amf::Element> el4 = amf.extractAMF(tmpptr, tmpptr + 
size);
+    headers.push_back(el4);
+
+     return headers;
+}
+
+// format a response to the 'echo' test used for testing Gnash. This
+// is only used for testing by developers. The format appears to be
+// two strings, followed by a double, followed by the "onResult".
+amf::Buffer &
+HTTPServer::formatEchoResponse(const std::string &num, amf::Element &el)
+{
+//    GNASH_REPORT_FUNCTION;
+    boost::shared_ptr<amf::Buffer> data;
+
+    amf::Element nel;
+    if (el.getType() == amf::Element::TYPED_OBJECT_AMF0) {
+       nel.makeTypedObject();
+       string name = el.getName();
+       nel.setName(name);
+       if (el.propertySize()) {
+           // FIXME: see about using std::reverse() instead.
+           for (int i=el.propertySize()-1; i>=0; i--) {
+//         for (int i=0 ; i<el.propertySize(); i++) {
+               boost::shared_ptr<amf::Element> child = el.getProperty(i);
+               nel.addProperty(child);
+           }
+           data = nel.encode();
+       } else {
+           data = el.encode();
+       }
+    } else {
+       data = el.encode();
+    }
+
+    return formatEchoResponse(num, data->reference(), data->allocated());
+}
+
+amf::Buffer &
+HTTPServer::formatEchoResponse(const std::string &num, amf::Buffer &data)
+{
+//    GNASH_REPORT_FUNCTION;
+    return formatEchoResponse(num, data.reference(), data.allocated());
+}
+
+amf::Buffer &
+HTTPServer::formatEchoResponse(const std::string &num, boost::uint8_t *data, 
size_t size)
+{
+//    GNASH_REPORT_FUNCTION;
+
+    //boost::uint8_t *tmpptr  = data;
+    
+    // FIXME: temporary hacks while debugging
+    amf::Buffer fixme("00 00 00 00 00 01");
+    amf::Buffer fixme2("ff ff ff ff");
+    
+    _buffer = "HTTPServer/1.1 200 OK\r\n";
+    formatContentType(DiskStream::FILETYPE_AMF);
+//    formatContentLength(size);
+    // FIXME: this is a hack ! Calculate a real size!
+    formatContentLength(size+29);
+    
+    // Pretend to be Red5 server
+    formatServer("Jetty(6.1.7)");
+    
+    // All HTTPServer messages are followed by a blank line.
+    terminateHeader();
+
+    // Add the binary blob for the header
+    _buffer += fixme;
+
+    // Make the result response, which is the 2nd data item passed in
+    // the request, a slash followed by a number like "/2".
+    string result = num;
+    result += "/onResult";
+    boost::shared_ptr<amf::Buffer> res = amf::AMF::encodeString(result);
+    _buffer.append(res->begin()+1, res->size()-1);
+
+    // Add the null data item
+    boost::shared_ptr<amf::Buffer> null = amf::AMF::encodeString("null");
+    _buffer.append(null->begin()+1, null->size()-1);
+
+    // Add the other binary blob
+    _buffer += fixme2;
+
+    amf::Element::amf0_type_e type = 
static_cast<amf::Element::amf0_type_e>(*data);
+    if ((type == amf::Element::UNSUPPORTED_AMF0)
+       || (type == amf::Element::NULL_AMF0)) {
+       _buffer += type;
+       // Red5 returns a NULL object when it's recieved an undefined one in 
the echo_test
+    } else if (type == amf::Element::UNDEFINED_AMF0) {
+       _buffer += amf::Element::NULL_AMF0;
+    } else {
+       // Add the AMF data we're echoing back
+       if (size) {
+           _buffer.append(data, size);
+       }
+    }
+    
+    return _buffer;
+}
+#endif
+
+#if 0
+/// These methods extract data from an RTMPT message. RTMP is an
+/// extension to HTTP that adds commands to manipulate the
+/// connection's persistance.
+//
+/// The URL to be opened has the following form:
+/// http://server/<comand>/[<client>/]<index>
+/// <command>
+///    denotes the RTMPT request type, "OPEN", "SEND", "IDLE", "CLOSE")
+/// <client>
+///    specifies the id of the client that performs the requests
+///    (only sent for established sessions)
+/// <index>
+///    is a consecutive number that seems to be used to detect missing packages
+HTTP::rtmpt_cmd_e
+HTTP::extractRTMPT(boost::uint8_t *data)
+{
+    GNASH_REPORT_FUNCTION;
+
+    string body = reinterpret_cast<const char *>(data);
+    string tmp, cid, indx;
+    HTTP::rtmpt_cmd_e cmd;
+
+    // force the case to make comparisons easier
+    std::transform(body.begin(), body.end(), body.begin(), 
+               (int(*)(int)) toupper);
+    string::size_type start, end;
+
+    // Extract the command first
+    start = body.find("OPEN", 0);
+    if (start != string::npos) {
+        cmd = HTTP::OPEN;
+    }
+    start = body.find("SEND", 0);
+    if (start != string::npos) {
+        cmd = HTTP::SEND;
+    }
+    start = body.find("IDLE", 0);
+    if (start != string::npos) {
+        cmd = HTTP::IDLE;
+    }
+    start = body.find("CLOSE", 0);
+    if (start != string::npos) {
+        cmd = HTTP::CLOSE;
+    }
+
+    // Extract the optional client id
+    start = body.find("/", start+1);
+    if (start != string::npos) {
+       end = body.find("/", start+1);
+       if (end != string::npos) {
+           indx = body.substr(end, body.size());
+           cid = body.substr(start, (end-start));
+       } else {
+           cid = body.substr(start, body.size());
+       }
+    }
+
+    _index = strtol(indx.c_str(), NULL, 0);
+    _clientid = strtol(cid.c_str(), NULL, 0);
+    end =  body.find("\r\n", start);
+//     if (end != string::npos) {
+//         cmd = HTTP::CLOSE;
+//     }
+
+    return cmd;
+}
+
+#endif
+
+/// These methods extract data from an RTMPT message. RTMP is an
+/// extension to HTTPServer that adds commands to manipulate the
+/// connection's persistance.
+//
+/// The URL to be opened has the following form:
+/// http://server/<comand>/[<client>/]<index>
+/// <command>
+///    denotes the RTMPT request type, "OPEN", "SEND", "IDLE", "CLOSE")
+/// <client>
+///    specifies the id of the client that performs the requests
+///    (only sent for established sessions)
+/// <index>
+///    is a consecutive number that seems to be used to detect missing packages
+HTTPServer::rtmpt_cmd_e
+HTTPServer::extractRTMPT(boost::uint8_t *data)
+{
+    GNASH_REPORT_FUNCTION;
+
+    string body = reinterpret_cast<const char *>(data);
+    string tmp, cid, indx;
+    HTTPServer::rtmpt_cmd_e cmd;
+
+    // force the case to make comparisons easier
+    std::transform(body.begin(), body.end(), body.begin(), 
+               (int(*)(int)) toupper);
+    string::size_type start, end;
+
+    // Extract the command first
+    start = body.find("OPEN", 0);
+    if (start != string::npos) {
+        cmd = HTTPServer::OPEN;
+    }
+    start = body.find("SEND", 0);
+    if (start != string::npos) {
+        cmd = HTTPServer::SEND;
+    }
+    start = body.find("IDLE", 0);
+    if (start != string::npos) {
+        cmd = HTTPServer::IDLE;
+    }
+    start = body.find("CLOSE", 0);
+    if (start != string::npos) {
+        cmd = HTTPServer::CLOSE;
+    }
+
+    // Extract the optional client id
+    start = body.find("/", start+1);
+    if (start != string::npos) {
+       end = body.find("/", start+1);
+       if (end != string::npos) {
+           indx = body.substr(end, body.size());
+           cid = body.substr(start, (end-start));
+       } else {
+           cid = body.substr(start, body.size());
+       }
+    }
+
+    _index = strtol(indx.c_str(), NULL, 0);
+    _clientid = strtol(cid.c_str(), NULL, 0);
+    end =  body.find("\r\n", start);
+//     if (end != string::npos) {
+//         cmd = HTTPServer::CLOSE;
+//     }
+
+    return cmd;
+}
+
+#if 0
+HTTPServer::http_method_e
+HTTPServer::extractCommand(boost::uint8_t *data)
+{
+    GNASH_REPORT_FUNCTION;
+
+//    string body = reinterpret_cast<const char *>(data);
+    HTTPServer::http_method_e cmd = HTTP::HTTP_NONE;
+
+    // force the case to make comparisons easier
+//     std::transform(body.begin(), body.end(), body.begin(), 
+//                (int(*)(int)) toupper);
+
+    // Extract the command
+    if (memcmp(data, "GET", 3) == 0) {
+        cmd = HTTP::HTTP_GET;
+    } else if (memcmp(data, "POST", 4) == 0) {
+        cmd = HTTP::HTTP_POST;
+    } else if (memcmp(data, "HEAD", 4) == 0) {
+        cmd = HTTP::HTTP_HEAD;
+    } else if (memcmp(data, "CONNECT", 7) == 0) {
+        cmd = HTTP::HTTP_CONNECT;
+    } else if (memcmp(data, "TRACE", 5) == 0) {
+        cmd = HTTP::HTTP_TRACE;
+    } else if (memcmp(data, "PUT", 3) == 0) {
+        cmd = HTTP::HTTP_PUT;
+    } else if (memcmp(data, "OPTIONS", 4) == 0) {
+        cmd = HTTP::HTTP_OPTIONS;
+    } else if (memcmp(data, "DELETE", 4) == 0) {
+        cmd = HTTP::HTTP_DELETE;
+    }
+
+    // For valid requests, the second argument, delimited by spaces
+    // is the filespec of the file being requested or transmitted.
+    if (cmd != HTTP::HTTP_NONE) {
+       boost::uint8_t *start = std::find(data, data+7, ' ') + 1;
+       boost::uint8_t *end   = std::find(start + 2, data+PATH_MAX, ' ');
+       boost::uint8_t *params = std::find(start, end, '?');
+       if (params != end) {
+           _params = std::string(params+1, end);
+           _filespec = std::string(start, params);
+           log_debug("Parameters for file: \"%s\"", _params);
+       } else {
+           // This is fine as long as end is within the buffer.
+           _filespec = std::string(start, end);
+       }
+       log_debug("Requesting file: \"%s\"", _filespec);
+
+       // The third field is always the HTTP version
+       // The version is the last field and is the protocol name
+       // followed by a slash, and the version number. Note that
+       // the version is not a double, even though it has a dot
+       // in it. It's actually two separate integers.
+       _version.major = *(end+6) - '0';
+       _version.minor = *(end+8) - '0';
+       log_debug (_("Version: %d.%d"), _version.major, _version.minor);
+    }
+
+    return cmd;
+}
+
+boost::uint8_t *
+HTTPServer::processHeaderFields(amf::Buffer &buf)
+{
+  //    GNASH_REPORT_FUNCTION;
+    string head(reinterpret_cast<const char *>(buf.reference()));
+
+    // The end of the header block is always followed by a blank line
+    string::size_type end = head.find("\r\n\r\n", 0);
+//    head.erase(end, buf.size()-end);
+    Tok t(head, Sep("\r\n"));
+    for (Tok::iterator i = t.begin(); i != t.end(); ++i) {
+       string::size_type pos = i->find(":", 0);
+       if (pos != string::npos) {
+           string name = i->substr(0, pos);
+           string value = i->substr(pos+2, i->size());
+           std::transform(name.begin(), name.end(), name.begin(), 
+                          (int(*)(int)) tolower);
+           std::transform(value.begin(), value.end(), value.begin(), 
+                          (int(*)(int)) tolower);
+           _fields[name] = value;
+           if (name == "keep-alive") {
+               _keepalive = true;
+               if ((value != "on") && (value != "off")) {
+                   _max_requests = strtol(value.c_str(), NULL, 0);
+                   log_debug("Setting Max Requests for Keep-Alive to %d", 
_max_requests);
+               }
+           }
+           if (name == "connection") {
+               if (value.find("keep-alive", 0) != string::npos) {
+                   _keepalive = true;
+               }
+           }
+           if (name == "content-length") {
+               _filesize = strtol(value.c_str(), NULL, 0);
+               log_debug("Setting Content Length to %d", _filesize);
+           }
+           if (name == "content-type") {
+               // This is the type used by flash when sending a AMF data via 
POST
+               if (value == "application/x-amf") {
+//                 log_debug("Got AMF data in the POST request!");
+                   _filetype = DiskStream::FILETYPE_AMF;
+               }
+               // This is the type used by wget when sending a file via POST
+               if (value == "application/x-www-form-urlencoded") {
+//                 log_debug("Got file data in the POST request");
+                   _filetype = DiskStream::FILETYPE_ENCODED;
+               }
+               log_debug("Setting Content Type to %d", _filetype);
+           }
+           
+//         cerr << "FIXME: " << (void *)i << " : " << dec <<  end << endl;
+       } else {
+           const boost::uint8_t *cmd = reinterpret_cast<const boost::uint8_t 
*>(i->c_str());
+           if (extractCommand(const_cast<boost::uint8_t *>(cmd)) == 
HTTP::HTTP_NONE) {
+               break;
+#if 1
+           } else {
+               log_debug("Got a request, parsing \"%s\"", *i);
+               string::size_type start = i->find(" ");
+               string::size_type params = i->find("?");
+               string::size_type pos = i->find("HTTP/");
+               if (pos != string::npos) {
+                   // The version is the last field and is the protocol name
+                   // followed by a slash, and the version number. Note that
+                   // the version is not a double, even though it has a dot
+                   // in it. It's actually two separate integers.
+                   _version.major = i->at(pos+5) - '0';
+                   _version.minor = i->at(pos+7) - '0';
+                   log_debug (_("Version: %d.%d"), _version.major, 
_version.minor);
+                   // the filespec in the request is the middle field, 
deliminated
+                   // by a space on each end.
+                   if (params != string::npos) {
+                       _params = i->substr(params+1, end);
+                       _filespec = i->substr(start+1, params);
+                       log_debug("Parameters for file: \"%s\"", _params);
+                   } else {
+                       _filespec = i->substr(start+1, pos-start-2);
+                   }
+                   log_debug("Requesting file: \"%s\"", _filespec);
+
+                   // HTTP 1.1 enables persistant network connections
+                   // by default.
+                   if (_version.minor > 0) {
+                       log_debug("Enabling Keep Alive by default for HTTP > 
1.0");
+                       _keepalive = true;
+                   }
+               }
+           }
+#endif
+       }
+    }
+    
+    return buf.reference() + end + 4;
+}
+#endif
+
+void
+HTTPServer::dump()
+{
+//    GNASH_REPORT_FUNCTION;
+}
+
+extern "C" {
+
+bool
+http_handler(Network::thread_params_t *args)
+{
+//    GNASH_REPORT_FUNCTION;
+//    struct thread_params thread_data;
+    string url, filespec, parameters;
+    HTTPServer *www = new HTTPServer;
+    bool result = false;
+    
+//    Network *net = reinterpret_cast<Network *>(args->handler);
+    bool done = false;
+//    www.setHandler(net);
+
+    log_debug(_("Starting HTTP Handler for fd #%d, tid %ld"),
+             args->netfd, get_thread_id());
+    
+    string docroot = args->filespec;
+
+//     cgis.setDocroot(args->filespec);
+    
+    www->setDocRoot(docroot);
+    log_debug("Starting to wait for data in net for fd #%d", args->netfd);
+
+    // Wait for data, and when we get it, process it.
+    do {
+       
+#ifdef USE_STATISTICS
+       struct timespec start;
+       clock_gettime (CLOCK_REALTIME, &start);
+#endif
+
+       // See if we have any messages waiting
+       if (www->recvMsg(args->netfd) == 0) {
+           done = true;
+       }
+
+       // Process incoming messages
+       if (!www->processClientRequest(args->netfd)) {
+//         hand->die();        // tell all the threads for this connection to 
die
+//         hand->notifyin();
+           log_debug("Net HTTP server done for fd #%d...", args->netfd);
+//         done = true;
+       }
+//     www->dump();
+       if ((www->getField("content-type") == "application/x-amf")
+           && (www->getField("content-type") == "application/x-amf")
+           && (www->getFilespec() == "/echo/gateway")) {
+           cerr << "GOT A GATEWAY REQUEST" << endl;
+       }
+       
+#if 0
+       string response = cache.findResponse(filestream->getFilespec());
+       if (response.empty()) {
+           cerr << "FIXME no cache hit for: " << www.getFilespec() << endl;
+//         www.clearHeader();
+//         amf::Buffer &ss = www.formatHeader(filestream->getFileSize(), 
HTTP::LIFE_IS_GOOD);
+//         www.writeNet(args->netfd, (boost::uint8_t 
*)www.getHeader().c_str(), www.getHeader().size());
+//         cache.addResponse(www.getFilespec(), www.getHeader());
+       } else {
+           cerr << "FIXME cache hit on: " << www.getFilespec() << endl;
+           www.writeNet(args->netfd, (boost::uint8_t *)response.c_str(), 
response.size());
+       }       
+#endif
+       
+       // Unless the Keep-Alive flag is set, this isn't a persisant network
+       // connection.
+       if (!www->keepAlive()) {
+           log_debug("Keep-Alive is off", www->keepAlive());
+           result = false;
+           done = true;
+       } else {
+           log_debug("Keep-Alive is on", www->keepAlive());
+           result = true;
+//         done = true;
+       }
+#ifdef USE_STATISTICS
+       struct timespec end;
+       clock_gettime (CLOCK_REALTIME, &end);
+       log_debug("Processing time for GET request was %f seconds",
+                 (float)((end.tv_sec - start.tv_sec) + ((end.tv_nsec - 
start.tv_nsec)/1e9)));
+#endif
+    } while(done != true);
+    
+//    hand->notify();
+    
+    log_debug("http_handler all done now finally...");
+
+    return result;
+} // end of httphandler
+} // end of extern C
+    
+} // end of gnash namespace
+
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

=== added file 'cygnal/http_server.h'
--- a/cygnal/http_server.h      1970-01-01 00:00:00 +0000
+++ b/cygnal/http_server.h      2009-03-31 00:53:35 +0000
@@ -0,0 +1,118 @@
+// 
+//   Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef _HTTP_SERVER_H_
+#define _HTTP_SERVER_H_
+
+#include <string>
+#include <map>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+#include <boost/shared_array.hpp>
+#include <boost/scoped_array.hpp>
+#include <sstream>
+
+#include "amf.h"
+#include "cque.h"
+#include "rtmp.h"
+#include "http.h"
+#include "handler.h"
+#include "network.h"
+#include "buffer.h"
+#include "diskstream.h"
+
+namespace cygnal
+{
+    
+class DSOEXPORT HTTPServer : public gnash::HTTP
+{
+public:
+    HTTPServer();
+    ~HTTPServer();
+
+    // These are for the protocol itself
+    boost::shared_ptr<amf::Buffer> processClientRequest(int fd);
+    boost::shared_ptr<amf::Buffer> processGetRequest(int fd);
+    boost::shared_ptr<amf::Buffer> processPostRequest(int fd);
+    boost::shared_ptr<amf::Buffer> processPutRequest(int fd);
+    boost::shared_ptr<amf::Buffer> processDeleteRequest(int fd);
+    boost::shared_ptr<amf::Buffer> processConnectRequest(int fd);
+    boost::shared_ptr<amf::Buffer> processOptionsRequest(int fd);
+    boost::shared_ptr<amf::Buffer> processHeadRequest(int fd);
+    boost::shared_ptr<amf::Buffer> processTraceRequest(int fd);
+
+    // Handle the response for the request.
+    boost::shared_ptr<amf::Buffer> formatServerReply(http_status_e code);
+    amf::Buffer &formatGetReply(gnash::DiskStream::filetype_e type, size_t 
size, http_status_e code); 
+    amf::Buffer &formatGetReply(size_t size, http_status_e code); 
+    amf::Buffer &formatGetReply(http_status_e code); 
+    amf::Buffer &formatPostReply(rtmpt_cmd_e code);
+    amf::Buffer &formatErrorResponse(http_status_e err);
+
+    // These methods extract data from an RTMPT message. RTMP is an
+    // extension to HTTP that adds commands to manipulate the
+    // connection's persistance.
+    rtmpt_cmd_e extractRTMPT(boost::uint8_t *data);
+    rtmpt_cmd_e extractRTMPT(amf::Buffer &data)
+       { return extractRTMPT(data.reference()); };    
+
+#if 0
+    // Examine the beginning of the data for an HTTP request command
+    // like GET or POST, etc...
+    http_method_e extractCommand(boost::uint8_t *data);
+    http_method_e extractCommand(amf::Buffer &data)
+       { return extractCommand(data.reference()); };    
+
+    // process all the header fields in the Buffer, storing them internally
+    // in _fields. The address returned is the address where the Content data
+    // starts, and is "Content-Length" bytes long, of "Content-Type" data.
+    boost::uint8_t *processHeaderFields(amf::Buffer &buf);
+#endif
+    
+#if 0
+    // Parse an Echo Request message coming from the Red5 echo_test.
+    std::vector<boost::shared_ptr<amf::Element > > 
parseEchoRequest(gnash::amf::Buffer &buf) { return 
parseEchoRequest(buf.reference(), buf.size()); };
+    std::vector<boost::shared_ptr<amf::Element > > 
parseEchoRequest(boost::uint8_t *buf, size_t size);
+    
+    // format a response to the 'echo' test used for testing Gnash.
+    gnash::amf::Buffer &formatEchoResponse(const std::string &num, 
amf::Element &el);
+    gnash::amf::Buffer &formatEchoResponse(const std::string &num, amf::Buffer 
&data);
+    gnash::amf::Buffer &formatEchoResponse(const std::string &num, uint8_t 
*data, size_t size);
+#endif
+
+    void dump();
+    
+private:
+    
+};
+
+// This is the thread for all incoming HTTP connections
+extern "C" {
+    DSOEXPORT bool http_handler(gnash::Network::thread_params_t *args);
+}
+
+} // end of gnash namespace
+
+// end of _HTTP_SERVER_H_
+#endif
+
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

=== added file 'cygnal/proc.cpp'
--- a/cygnal/proc.cpp   1970-01-01 00:00:00 +0000
+++ b/cygnal/proc.cpp   2009-03-16 22:44:59 +0000
@@ -0,0 +1,245 @@
+// 
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string>
+#include <cstring>
+#include <signal.h>
+#include <iostream>
+#include <cstdlib>
+
+#include "log.h"
+#include "crc.h"
+#include "proc.h"
+#include "network.h"
+
+using namespace std;
+using namespace gnash;
+
+namespace cygnal
+{
+
+LogFile& dbglogfile = LogFile::getDefaultInstance();
+static CRcInitFile& crcfile = CRcInitFile::getDefaultInstance();
+
+Proc::Proc (void)
+{
+//    GNASH_REPORT_FUNCTION;
+}
+
+Proc::~Proc (void)
+{
+//    GNASH_REPORT_FUNCTION;
+}
+
+bool
+Proc::startCGI(void)
+{
+//    GNASH_REPORT_FUNCTION;
+    log_unimpl("%s", __PRETTY_FUNCTION__);
+    return false;
+}
+
+Proc&
+Proc::getDefaultInstance()
+{
+//    GNASH_REPORT_FUNCTION;
+    static Proc c;
+    return c;
+}
+
+
+bool
+Proc::startCGI(const string &filespec, boost::uint16_t port)
+{
+//    GNASH_REPORT_FUNCTION;
+    return startCGI(filespec, false, port);
+}
+
+bool
+Proc::startCGI(const string &filespec)
+{
+//    GNASH_REPORT_FUNCTION;
+    return startCGI(filespec, false, 0);
+}
+
+bool
+Proc::startCGI(const string &filespec, bool outflag)
+{
+
+    return startCGI(filespec, outflag, 0);
+}
+
+bool
+Proc::startCGI(const string &filespec, bool outflag, boost::uint16_t port)
+{
+//    GNASH_REPORT_FUNCTION;
+    struct stat procstats;
+    pid_t childpid;
+    char *cmd_line[20];
+    
+    _output[filespec] = outflag;
+
+    string path;
+    if (crcfile.getCgiRoot().size() > 0) {
+        path = crcfile.getCgiRoot().c_str();
+        log_debug (_("Document Root for CGI files is: %s"), path);
+    } else {
+        // Yes, I know this is a hack.
+        path = "/var/www/html/cygnal/cgi-bin";
+    }
+//    string path = filespec;
+    path += filespec;
+        
+    // simple debug junk
+    log_debug("Starting \"%s\"", path);
+
+    // See if the file actually exists, otherwise we can't spawn it
+    if (stat(path.c_str(), &procstats) == -1) {
+        log_error("Invalid filespec for CGI: \"%s\"", path);
+//        perror(filespec.c_str());
+       return (false);
+    }
+
+    // setup a command line. By default, argv[0] is the name of the process
+    cmd_line[0] = new char(filespec.size()+1);
+    strcpy(cmd_line[0], filespec.c_str());
+
+    // If the parent has verbosity on, chances are the child should too.
+//     if (dbglogfile.getVerbosity() > 0) {
+    cmd_line[1] = new char(3);
+    strcpy(cmd_line[1], "-n");
+    cmd_line[2] = new char(4);
+    strcpy(cmd_line[2], "-vv");
+    cmd_line[3] = 0;
+//     }
+    
+    // When running multiple cgis, we prefer to specify the port it's using.
+    if (port > 0) {
+        cmd_line[3] = new char(3);
+        strcpy(cmd_line[3], "-p");
+        cmd_line[4] = new char(10);
+        sprintf(cmd_line[4], "%d", port);
+        cmd_line[5] = 0;
+    }
+
+
+    // fork ourselves silly
+    childpid = fork();
+    
+//    boost::mutex::scoped_lock lock(_mutex);
+    
+    // childpid is a positive integer, if we are the parent, and fork() worked
+    if (childpid > 0) {
+       _pids[filespec] = childpid;
+        return (true);
+    }
+    
+    // childpid is -1, if the fork failed, so print out an error message
+    if (childpid == -1) {
+        // fork() failed
+       perror(filespec.c_str());
+       return (false);
+    }
+
+    // If we are the child, exec the new process, then go away
+    if (childpid == 0) {
+       // Turn off all output, if requested
+       if (outflag == false) {
+           close(1);
+           open("/dev/null", O_WRONLY);
+           close(2);
+           open("/dev/null", O_WRONLY);
+       }
+       // Start the desired executable
+       execv(path.c_str(), cmd_line);
+       perror(path.c_str());
+       exit(0);
+    }
+    
+    return (true);
+}
+
+int
+Proc::findCGI(const string &filespec)
+{
+//    GNASH_REPORT_FUNCTION;
+    log_debug("Finding \"%s\"", filespec);    
+    boost::mutex::scoped_lock lock(_mutex);
+
+    return _pids[filespec];
+}
+
+bool
+Proc::stopCGI(void)
+{
+//    GNASH_REPORT_FUNCTION;
+    log_unimpl("%s", __PRETTY_FUNCTION__);
+    boost::mutex::scoped_lock lock(_mutex);
+
+    return false;
+}
+    
+bool
+Proc::stopCGI(const string &filespec)
+{
+//    GNASH_REPORT_FUNCTION;
+    log_debug("Stopping \"%s\"", filespec);
+
+    boost::mutex::scoped_lock lock(_mutex);
+    pid_t pid = _pids[filespec];
+    
+    if (kill (pid, SIGQUIT) == -1) {
+       return (false);
+    } else {
+       return (true);
+    }
+}
+ 
+bool
+Proc::setOutput(const string &filespec, bool outflag)
+{
+//    GNASH_REPORT_FUNCTION;
+    boost::mutex::scoped_lock lock(_mutex);
+    _output[filespec] = outflag;
+    
+    return (true);
+}
+
+bool
+Proc::getOutput(const string &filespec)
+{
+//    GNASH_REPORT_FUNCTION;
+    boost::mutex::scoped_lock lock(_mutex);
+    
+    return _output[filespec];
+}
+
+bool
+Proc::connectCGI (const string &host, boost::uint16_t port)
+{
+//    GNASH_REPORT_FUNCTION;
+    return createClient(host, port);
+}
+
+
+} // end of cygnal namespace

=== added file 'cygnal/proc.h'
--- a/cygnal/proc.h     1970-01-01 00:00:00 +0000
+++ b/cygnal/proc.h     2009-03-31 00:53:35 +0000
@@ -0,0 +1,79 @@
+// 
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef __PROC_H__
+#define __PROC_H__ 1
+
+#include <string>
+#include <map>
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+
+#include "network.h"
+#include "dsodefs.h"
+
+namespace cygnal
+{
+  
+class Proc : public gnash::Network {
+public:
+    DSOEXPORT Proc (void);
+    DSOEXPORT ~Proc (void);
+    static Proc& getDefaultInstance();
+    
+    // These flags control whether the stdout of the child process gets 
displayed
+    bool setOutput (const std::string &output, bool outflag);
+    bool getOutput (const std::string &output);
+
+    // This starts the process running via the usual fork() & exec()
+    bool startCGI (void);
+    bool startCGI (const std::string &filespec);
+    bool startCGI (const std::string &filespec, boost::uint16_t port);
+    bool startCGI (const std::string &filespec, bool output);
+    bool startCGI (const std::string &filespec, bool output, boost::uint16_t 
port);
+
+    void setDocroot(const std::string &path) { _docroot = path; } ;
+    std::string &getDocroot() { return _docroot; };
+    
+    // This opens a network connection to the process
+    bool connectCGI (const std::string &host, boost::uint16_t port);
+
+    // This finds the process
+    int findCGI (const std::string &filespec);
+
+    // This stop the process
+    bool stopCGI (void);
+    bool stopCGI (const std::string &filespec);
+private:
+    std::map<std::string, bool> _output;
+    std::map<std::string, int>  _pids;
+    std::map<std::string, int>  _cons;
+    std::string                 _docroot;
+    
+    boost::mutex       _mutex;
+};
+
+} // end of cygnal namespace
+
+#endif  // end of __PROC_H__
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

=== modified file 'cygnal/rtmp_server.cpp'
--- a/cygnal/rtmp_server.cpp    2009-02-25 22:33:03 +0000
+++ b/cygnal/rtmp_server.cpp    2009-04-01 22:53:00 +0000
@@ -904,7 +904,7 @@
     string url, filespec;
     url = docroot;
     bool done = false;
-    RTMPMsg *body = 0;
+    boost::shared_ptr<RTMPMsg> body;
     static bool initialize = true;
     static bool echo = false;
     bool sendfile = false;

=== modified file 'cygnal/rtmp_server.h'
--- a/cygnal/rtmp_server.h      2009-02-25 22:33:03 +0000
+++ b/cygnal/rtmp_server.h      2009-03-16 23:34:13 +0000
@@ -16,7 +16,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 #ifndef _RTMP_SERVER_H_
-#define _RTMP_SERVER_H_ 1
+#define _RTMP_SERVER_H_
 
 #include <boost/cstdint.hpp>
 #include <boost/shared_ptr.hpp>
@@ -30,11 +30,12 @@
 #include "buffer.h"
 #include "diskstream.h"
 #include "rtmp_msg.h"
+#include "dsodefs.h"
 
 namespace cygnal
 {
 
-class DSOEXPORT RTMPServer : public gnash::RTMP
+class RTMPServer : public gnash::RTMP
 {
 public:
     RTMPServer();
@@ -85,7 +86,7 @@
 };
 
 // This is the thread for all incoming RTMP connections
-bool rtmp_handler(gnash::Network::thread_params_t *args);
+bool DSOEXPORT rtmp_handler(gnash::Network::thread_params_t *args);
 
 } // end of gnash namespace
 // end of _RTMP_SERVER_H_

=== modified file 'cygnal/testsuite/cygnal.all/Makefile.am'
--- a/cygnal/testsuite/cygnal.all/Makefile.am   2009-02-25 22:33:03 +0000
+++ b/cygnal/testsuite/cygnal.all/Makefile.am   2009-03-25 22:33:46 +0000
@@ -34,7 +34,7 @@
        $(top_builddir)/libbase/libgnashbase.la \
        $(top_builddir)/libamf/libgnashamf.la \
        $(top_builddir)/libnet/libgnashnet.la \
-       libcygnal.la \
+       $(top_builddir)/cygnal/libcygnal.la \
        $(BOOST_LIBS) \
        $(PTHREAD_LIBS)
 

=== modified file 'cygnal/testsuite/cygnal.exp'
--- a/cygnal/testsuite/cygnal.exp       2009-02-25 22:33:03 +0000
+++ b/cygnal/testsuite/cygnal.exp       2009-04-05 21:09:00 +0000
@@ -451,8 +451,6 @@
     catch {close -i $sid}
 }
 
-
-
 # testcases is set by the Makefile in the site.exp data file.
 #foreach file $testcases {
 #     expect {

=== modified file 'libamf/amf.cpp'
--- a/libamf/amf.cpp    2009-04-23 14:46:54 +0000
+++ b/libamf/amf.cpp    2009-06-07 21:14:22 +0000
@@ -553,6 +553,9 @@
        for (ait = props.begin(); ait != props.end(); ait++) {
            counter++;
            boost::shared_ptr<amf::Element> el = (*(ait));
+#if 0
+           // FIXME: Red5's echo tests like to turn strict array's into ecma
+           // arrays, but we shouldn't do that in the core.
            // If we see an undefined data item, then switch to an ECMA
            // array which is more compact. At least this is what Red5 does.
            if (el->getType() == Element::UNDEFINED_AMF0) {
@@ -570,10 +573,11 @@
                }
                continue;
            } else {
+#endif
                if (sparse) {
                    sparse = false;
-            std::ostringstream os;
-            os << counter;
+                   std::ostringstream os;
+                   os << counter;
                    amf::Element elnum(os.str().c_str(), el->to_number());
                    *buf += AMF::encodeElement(elnum);
                    double nodes = items;
@@ -589,7 +593,7 @@
                        break;
                    }
                }
-           }
+//         }
 //         el->dump();
        }
     }
@@ -941,6 +945,11 @@
     ++tmpptr;
 
     switch (type) {
+        case Element::NOTYPE:
+        {
+           log_error("Element has no type!");
+           break;
+       }
         case Element::NUMBER_AMF0:
         {
             // Make sure this isn't less than 0. We check this above at
@@ -950,6 +959,7 @@
             if (static_cast<size_t>(tooFar - tmpptr) < sizeof(const double)) {
                 log_error(_("AMF data segment too short to contain"
                             "type NUMBER"));
+               el.reset();
                 return el;
             }
             double swapped = *(reinterpret_cast<const double*>(tmpptr));
@@ -1222,13 +1232,13 @@
     // length to a value, this is tottaly bogus, and I'm tired of
     // braindamaging code to keep valgrind happy.
     if (length <= 0) {
-    log_debug("No Property name, object done");
-    return el;
+//     log_debug("No Property name, object done %x, %x", (void *)in, (void 
*)tooFar);
+       return el;
     }
     
     if (length + tmpptr > tooFar) {
-    log_error("%d bytes for a string is over the safe limit of %d. Putting the 
rest of the buffer into the string, line %d", length, SANE_STR_SIZE, __LINE__);
-    length = tooFar - tmpptr;
+       log_error("%d bytes for a string is over the safe limit of %d. Putting 
the rest of the buffer into the string, line %d", length, SANE_STR_SIZE, 
__LINE__);
+       length = tooFar - tmpptr;
     }    
     
     // name is just debugging help to print cleaner, and should be removed 
later
@@ -1237,7 +1247,7 @@
 //    log_debug(_("AMF property name is: %s"), name);
     // Don't read past the end
     if (tmpptr + length < tooFar) {
-    tmpptr += length;
+       tmpptr += length;
     }
     
     char c = *(reinterpret_cast<char *>(tmpptr));
@@ -1245,21 +1255,21 @@
     // If we get a NULL object, there is no data. In that case, we only return
     // the name of the property.
     if (type == Element::NULL_AMF0) {
-    log_debug("No data associated with Property \"%s\"", name);
-    el.reset(new Element);
-    el->setName(name.c_str(), name.size());
-    tmpptr += 1;
-    // Calculate the offset for the next read
+       log_debug("No data associated with Property \"%s\"", name);
+       el.reset(new Element);
+       el->setName(name.c_str(), name.size());
+       tmpptr += 1;
+       // Calculate the offset for the next read
     } else {
-    // process the data with associated with the property.
-    // Go past the data to the start of the next AMF object, which
-    // should be a type byte.
+       // process the data with associated with the property.
+       // Go past the data to the start of the next AMF object, which
+       // should be a type byte.
 //     tmpptr += length;
-    el = extractAMF(tmpptr, tooFar);
-    if (el) {
-        el->setName(name.c_str(), name.size()); // FIXME: arg, overwrites the 
name for TypedObjects
-    }
-    tmpptr += totalsize();
+       el = extractAMF(tmpptr, tooFar);
+       if (el) {
+           el->setName(name.c_str(), name.size()); // FIXME: arg, overwrites 
the name for TypedObjects
+       }
+       tmpptr += totalsize();
     }
 
     //delete name;

=== modified file 'libamf/amf_msg.cpp'
--- a/libamf/amf_msg.cpp        2009-04-23 14:46:54 +0000
+++ b/libamf/amf_msg.cpp        2009-06-07 21:14:22 +0000
@@ -143,7 +143,7 @@
     tmpptr += sizeof(boost::uint16_t);
     string str1(reinterpret_cast<const char *>(tmpptr), length);
     msg->target = str1;
-    if (static_cast<size_t>(tmpptr - data) > size) {
+    if ((tmpptr - data) > static_cast<int>(size)) {
         boost::format msg("Trying to read past the end of data! Wants %1% 
bytes, given %2% bytes");
         msg % length % size;
         throw GnashException(msg.str());
@@ -162,7 +162,7 @@
     string str2(reinterpret_cast<const char *>(tmpptr), length);
     msg->response = str2;
     tmpptr += length;
-    if (static_cast<size_t>(tmpptr - data) > size) {
+    if ((tmpptr - data) > static_cast<int>(size)) {
         boost::format msg("Trying to read past the end of data! Wants %1% 
bytes, given %2% bytes");
         msg % length % size;
         throw GnashException(msg.str());
@@ -197,10 +197,12 @@
 boost::shared_ptr<AMF_msg::context_header_t>
 AMF_msg::parseAMFPacket(boost::uint8_t *data, size_t size)
 {
-//    GNASH_REPORT_FUNCTION;
+    GNASH_REPORT_FUNCTION;
 //    _messages.push_back();
     boost::uint8_t *ptr = data + sizeof(AMF_msg::context_header_t);
     boost::shared_ptr<context_header_t> header = 
AMF_msg::parseContextHeader(data, size);
+
+//     log_debug("%s: %s", __PRETTY_FUNCTION__, hexify(data, size, true));
     
     AMF amf;
     /// Read all the messages from the AMF packet
@@ -230,8 +232,8 @@
 }
 
 boost::shared_ptr<amf::Buffer>
-AMF_msg::encodeAMFPacket(const std::string &/* target */,
-                         const std::string &/* response */, size_t /* size */)
+AMF_msg::encodeAMFPacket(const std::string & /* target */,
+                         const std::string & /*response */, size_t /* size */)
 {
 //    GNASH_REPORT_FUNCTION;
 

=== modified file 'libamf/buffer.cpp'
--- a/libamf/buffer.cpp 2009-02-25 22:33:03 +0000
+++ b/libamf/buffer.cpp 2009-03-25 22:33:14 +0000
@@ -668,6 +668,11 @@
 //    GNASH_REPORT_FUNCTION;
     boost::scoped_array<boost::uint8_t> tmp;
 
+    // If there is no size, don't do anything
+    if (size == 0) {
+       return *this;
+    }
+    
     // If we don't have any data yet in this buffer, resizing is cheap, as
     // we don't havce to copy any data.
     if (_seekptr == _data.get()) {
@@ -728,7 +733,7 @@
 {
     os << "Buffer is " << _seekptr-_data.get() << "/" << _nbytes << " bytes: ";
      // Skip in-memory address " at " << (void *)_data.get() << endl;
-    if (_nbytes < 0xffff) {
+    if (_nbytes > 0) {
        const size_t bytes = _seekptr - _data.get();
        os << gnash::hexify((unsigned char *)_data.get(), bytes, false) << endl;
        os << gnash::hexify((unsigned char *)_data.get(), bytes, true) << endl;

=== modified file 'libamf/element.cpp'
--- a/libamf/element.cpp        2009-02-26 08:04:27 +0000
+++ b/libamf/element.cpp        2009-03-26 17:08:22 +0000
@@ -1451,13 +1451,9 @@
 {
 //    GNASH_REPORT_FUNCTION;
     if ((size > 0) && (name != 0)) {
-       if (isascii(*name)) {
-           _name = new char[size+1];
-           std::copy(name, name+size, _name);
-           *(_name + size) = 0;
-       } else {
-           log_error("Got unprintable characters for the element name!");
-       }
+       _name = new char[size+1];
+       std::copy(name, name+size, _name);
+       *(_name + size) = 0;
     }
 }
 

=== modified file 'libbase/GC.h'
--- a/libbase/GC.h      2009-02-25 22:33:03 +0000
+++ b/libbase/GC.h      2009-03-12 03:49:13 +0000
@@ -28,9 +28,7 @@
 #include <string>
 #include <algorithm> //for std::find
 
-#ifndef NDEBUG
-# include <boost/thread.hpp>
-#endif
+#include <boost/thread.hpp>
 
 #include "dsodefs.h"
 
@@ -227,8 +225,10 @@
        ///
        void addCollectable(const GcResource* item)
        {
+         boost::thread self;
+         // Don't add an object from a thread
+         if (self == mainThread) {       
 #ifndef NDEBUG
-               boost::thread self;
                assert(self == mainThread);
                assert(item);
                assert(! item->isReachable());
@@ -237,6 +237,7 @@
 #endif
 
                _resList.push_back(item);
+         }
 #if GNASH_GC_DEBUG > 1
                log_debug(_("GC %p: collectable %p added, num collectables: 
%d"), (void*)this, (void*)item, _resList.size());
 #endif
@@ -301,12 +302,10 @@
 
        static GC* _singleton;
 
-#ifndef NDEBUG
        /// The thread that initialized the GC is 
        /// the only one allowed to run the collector
        /// and to register collectable objects
        boost::thread mainThread;
-#endif
 
        /// Number of resources in collectable list at end of last
        /// collect() call.

=== modified file 'libcore/as_value.cpp'
--- a/libcore/as_value.cpp      2009-04-08 11:48:21 +0000
+++ b/libcore/as_value.cpp      2009-06-07 21:14:22 +0000
@@ -17,6 +17,16 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
+#include <boost/shared_ptr.hpp>
+#include <cmath> // std::fmod
+#include <boost/algorithm/string/case_conv.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/format.hpp>
+#include <locale>
+#include <sstream>
+#include <iomanip>
+#include <string>
+
 #include "smart_ptr.h" // GNASH_USE_GC
 #include "as_value.h"
 #include "as_object.h"
@@ -42,29 +52,20 @@
 #include "SimpleBuffer.h"
 #include "StringPredicates.h"
 
-#include <cmath> // std::fmod
-#include <boost/algorithm/string/case_conv.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/format.hpp>
-#include <locale>
-#include <sstream>
-#include <iomanip>
-#include <string>
-
 // Define the macro below to make abstract equality operator verbose
 //#define GNASH_DEBUG_EQUALITY 1
 
 // Define the macro below to make to_primitive verbose
-//#define GNASH_DEBUG_CONVERSION_TO_PRIMITIVE 1
+// #define GNASH_DEBUG_CONVERSION_TO_PRIMITIVE 1
 
 // Define this macro to make soft references activity verbose
-//#define GNASH_DEBUG_SOFT_REFERENCES
+#define GNASH_DEBUG_SOFT_REFERENCES
 
 // Define this macro to make AMF parsing verbose
-//#define GNASH_DEBUG_AMF_DESERIALIZE
+#define GNASH_DEBUG_AMF_DESERIALIZE 1
 
 // Define this macto to make AMF writing verbose
-//#define GNASH_DEBUG_AMF_SERIALIZE
+// #define GNASH_DEBUG_AMF_SERIALIZE 1
 
 namespace gnash {
 
@@ -196,14 +197,22 @@
                 str = val.to_string();
             }
             el.reset(new amf::Element(name, str));
-        }
-
-        else if (val.is_bool()) {
+        } else if (val.is_bool()) {
             bool flag = val.to_bool();
             el.reset(new amf::Element(name, flag));
-        }
-
-        else if (val.is_number()) { 
+        } else if (val.is_object()) {
+//            el.reset(new amf::Element(name, flag));
+        } else if (val.is_null()) {
+           boost::shared_ptr<amf::Element> tmpel(new amf::Element);
+           tmpel->setName(name);
+           tmpel->makeNull();
+            el = tmpel;
+        } else if (val.is_undefined()) {
+           boost::shared_ptr<amf::Element> tmpel(new amf::Element);
+           tmpel->setName(name);
+           tmpel->makeUndefined();
+            el = tmpel;
+        } else if (val.is_number()) { 
             double dub;
             if (val.is_undefined()) {
                 dub = 0.0;
@@ -282,13 +291,16 @@
         boost::uint16_t namelen = name.size();
         _buf.appendNetworkShort(namelen);
         _buf.append(name.c_str(), namelen);
+#if 0
         if ( ! val.writeAMF0(_buf, _offsetTable, _vm, _allowStrict) )
         {
             log_error("Problems serializing an object's member");
             _error=true;
         }
+#else
+    log_error("writeAMF0 disabled for now");
+#endif
     }
-
 private:
 
     bool _allowStrict;
@@ -847,24 +859,30 @@
     }
 }
 
-std::auto_ptr<amf::Element>
+boost::shared_ptr<amf::Element>
 as_value::to_element() const
 {
     VM& vm = VM::get();
     //int swfVersion = vm.getSWFVersion();
-    std::auto_ptr<amf::Element> el ( new amf::Element );
+    boost::shared_ptr<amf::Element> el ( new amf::Element );
     boost::intrusive_ptr<as_object> ptr = to_object();
 
     switch (m_type) {
+      case UNDEFINED:
+         el->makeUndefined();
+         break;
+      case NULLTYPE:
+         el->makeNull();
+         break;
+      case BOOLEAN:
+         el->makeBoolean(getBool());
+         break;
       case  STRING:
          el->makeString(getStr());
          break;
       case NUMBER:
          el->makeNumber(getNum());
          break;
-      case BOOLEAN:
-         el->makeBoolean(getBool());
-         break;
       case OBJECT:
       {
          el->makeObject();
@@ -1130,6 +1148,13 @@
 }
 
 void
+as_value::set_unsupported()
+{
+       m_type = UNSUPPORTED;
+       _value = boost::blank();
+}
+
+void
 as_value::set_as_object(as_object* obj)
 {
        if ( ! obj )
@@ -1837,10 +1862,20 @@
        :
        m_type(UNDEFINED)
 {
+//     GNASH_REPORT_FUNCTION;    
+//     el.dump();
+    
     VM& vm = VM::get();
     string_table& st = vm.getStringTable();
-    
+
     switch (el.getType()) {
+      case amf::Element::NOTYPE:
+      {
+#ifdef GNASH_DEBUG_AMF_DESERIALIZE
+         log_debug("as_value(Element&) : AMF type NO TYPE!");
+#endif
+         break;
+      }
       case amf::Element::NULL_AMF0:
       {
 #ifdef GNASH_DEBUG_AMF_DESERIALIZE
@@ -1894,8 +1929,16 @@
 #ifdef GNASH_DEBUG_AMF_DESERIALIZE
             log_debug("as_value(Element&) : AMF type STRING");
 #endif
-            std::string str = el.to_string();
-            set_string(str);
+           std::string str;
+           // If there is data, convert it to a string for the as_value
+           if (el.getDataSize() != 0) {
+               str = el.to_string();
+               // Element's store the property name as the name, not as data.
+           } else if (el.getNameSize() != 0) {
+               str = el.getName();
+           }
+           
+           set_string(str);
             break;
       }
 
@@ -1905,18 +1948,22 @@
 #ifdef GNASH_DEBUG_AMF_DESERIALIZE
           log_debug("as_value(Element&) : AMF type OBJECT");
 #endif
-          as_object* obj = new as_object(getObjectInterface());
+         as_object* obj = new as_object(getObjectInterface());
           if (el.propertySize()) {
               for (size_t i=0; i < el.propertySize(); i++) {
-              const boost::shared_ptr<amf::Element> prop = el.getProperty(i);
-              if (prop == 0) {
-                  break;
-              } else {
-                  obj->set_member(st.find(prop->getName()), as_value(*prop));
-              }
+                 const boost::shared_ptr<amf::Element> prop = 
el.getProperty(i);
+                 if (prop == 0) {
+                     break;
+                 } else {
+                     if (prop->getNameSize() == 0) {
+                         log_debug("%s:(%d) Property has no name!", 
__PRETTY_FUNCTION__, __LINE__);
+                     } else {
+                         obj->set_member(st.find(prop->getName()), 
as_value(*prop));
+                     }
+                 }
               }
           }
-          set_as_object(obj);
+         set_as_object(obj);
           break;
       }
 
@@ -1932,12 +1979,12 @@
           Array_as* obj = new Array_as;
           if (el.propertySize()) {
               for (size_t i=0; i < el.propertySize(); i++) {
-              const boost::shared_ptr<amf::Element> prop = el.getProperty(i);
-              if (prop == 0) {
-                  break;
-              } else {
-                  obj->set_member(st.find(prop->getName()), as_value(*prop));
-              }
+                 const boost::shared_ptr<amf::Element> prop = 
el.getProperty(i);
+                 if (prop == 0) {
+                     break;
+                 } else {
+                     obj->set_member(st.find(prop->getName()), 
as_value(*prop));
+                 }
               }
           }
           set_as_object(obj);
@@ -1959,7 +2006,11 @@
               if (prop == 0) {
                   break;
               } else {
-                  obj->set_member(st.find(prop->getName()), as_value(*prop));
+                 if (prop->getNameSize() == 0) {
+                     log_debug("%s:(%d) Property has no name!", 
__PRETTY_FUNCTION__, __LINE__);
+                 } else {
+                     obj->set_member(st.find(prop->getName()), 
as_value(*prop));
+                 }
               }
           }
           
@@ -1975,14 +2026,23 @@
 
       case amf::Element::DATE_AMF0:
       {
-        log_unimpl("DATE Element to as_value");
-        //if (swfVersion > 5) m_type = STRING;
-        break;
+#ifdef GNASH_DEBUG_AMF_DESERIALIZE
+         log_debug("as_value(Element&) : AMF type DATE");
+#endif
+         double num = el.to_number();
+         set_double(num);
+         break;
       }
-
+      //if (swfVersion > 5) m_type = STRING;
+      
       case amf::Element::UNSUPPORTED_AMF0:
-          log_unimpl("Unsupported data type is not supported yet");
-          break;
+      {
+#ifdef GNASH_DEBUG_AMF_DESERIALIZE
+         log_debug("as_value(Element&) : AMF type UNSUPPORTED");
+#endif
+         set_unsupported();
+         break;
+      }
       case amf::Element::RECORD_SET_AMF0:
           log_unimpl("Record Set data type is not supported yet");
           break;

=== modified file 'libcore/as_value.h'
--- a/libcore/as_value.h        2009-04-03 09:48:13 +0000
+++ b/libcore/as_value.h        2009-04-05 22:01:27 +0000
@@ -36,6 +36,7 @@
 #include <boost/type_traits/is_floating_point.hpp>
 #include <boost/utility/enable_if.hpp>
 #include <boost/static_assert.hpp>
+#include <boost/shared_ptr.hpp>
 
 #include "utility.h" // UNUSED
 #include "string_table.h"
@@ -118,6 +119,10 @@
                NULLTYPE,
                NULLTYPE_EXCEPT,
 
+               /// NULL value
+               UNSUPPORTED,
+               UNSUPPORTED_EXCEPT,
+
                /// Boolean value
                BOOLEAN,
                BOOLEAN_EXCEPT,
@@ -370,7 +375,7 @@
        double  to_number() const;
 
        /// Get an AMF element representation for this value
-       std::auto_ptr<amf::Element> to_element() const;
+        boost::shared_ptr<amf::Element> to_element() const;
 
        /// Conversion to 32bit integer
        //
@@ -565,6 +570,9 @@
        /// Set this value to the NULL value
        void set_null();
 
+       /// Set this value to the Unsupported value
+       void set_unsupported();
+
        /// Equality operator, follows strict equality semantic
        //
        /// See strictly_equals
@@ -590,11 +598,14 @@
 
        bool is_bool() const { return (m_type == BOOLEAN); }
 
-       bool is_exception() const
+       bool is_unsupported() const { return (m_type == UNSUPPORTED); }
+
+        bool is_exception() const
        { return (m_type == UNDEFINED_EXCEPT || m_type == NULLTYPE_EXCEPT
                || m_type == BOOLEAN_EXCEPT || m_type == NUMBER_EXCEPT
                || m_type == OBJECT_EXCEPT || m_type == AS_FUNCTION_EXCEPT
-               || m_type == MOVIECLIP_EXCEPT || m_type == STRING_EXCEPT);
+               || m_type == MOVIECLIP_EXCEPT || m_type == STRING_EXCEPT
+               || m_type == UNSUPPORTED_EXCEPT);
        }
 
        // Flag or unflag an as_value as an exception -- this gets flagged

=== modified file 'libcore/namedStrings.cpp'
--- a/libcore/namedStrings.cpp  2009-05-27 13:02:02 +0000
+++ b/libcore/namedStrings.cpp  2009-06-07 21:14:22 +0000
@@ -62,8 +62,8 @@
        string_table::svt( "_focusrect", NSV::PROP_uFOCUSRECT ),
        string_table::svt( "_framesloaded", NSV::PROP_uFRAMESLOADED ),
        string_table::svt( "_height", NSV::PROP_uHEIGHT ),
-    string_table::svt( "g", NSV::PROP_G ),
-    string_table::svt( "h", NSV::PROP_H ),
+        string_table::svt( "g", NSV::PROP_G ),
+        string_table::svt( "h", NSV::PROP_H ),
        string_table::svt( "height", NSV::PROP_HEIGHT ),
        string_table::svt( "_highquality", NSV::PROP_uHIGHQUALITY ),
        string_table::svt( "_quality", NSV::PROP_uQUALITY ),
@@ -84,7 +84,7 @@
        string_table::svt( "onLoadError", NSV::PROP_ON_LOAD_ERROR ),
        string_table::svt( "onLoadProgress", NSV::PROP_ON_LOAD_PROGRESS ),
        string_table::svt( "onLoadInit", NSV::PROP_ON_LOAD_INIT ),
-    string_table::svt( "onSoundComplete", NSV::PROP_ON_SOUND_COMPLETE ),
+        string_table::svt( "onSoundComplete", NSV::PROP_ON_SOUND_COMPLETE ),
        string_table::svt( "onUnload", NSV::PROP_ON_UNLOAD ),
        string_table::svt( "onEnterFrame", NSV::PROP_ON_ENTER_FRAME ),
        string_table::svt( "onConstruct", NSV::PROP_ON_CONSTRUCT ),
@@ -112,7 +112,7 @@
        string_table::svt( "onResult", NSV::PROP_ON_RESULT ),
        string_table::svt( "onMetaData", NSV::PROP_ON_META_DATA ),
        string_table::svt( "onConnect", NSV::PROP_ON_CONNECT ),
-    string_table::svt( "onXML", NSV::PROP_ON_XML ),
+        string_table::svt( "onXML", NSV::PROP_ON_XML ),
        string_table::svt( "parseXML", NSV::PROP_PARSE_XML ),
        string_table::svt( "onTimer", NSV::PROP_ON_TIMER ),
        string_table::svt( "_parent", NSV::PROP_uPARENT ),

=== modified file 'libnet/cache.h'
--- a/libnet/cache.h    2009-02-27 16:59:46 +0000
+++ b/libnet/cache.h    2009-03-16 23:34:13 +0000
@@ -31,6 +31,7 @@
 #include "statistics.h"
 #include "diskstream.h"
 #include "getclocktime.hpp"
+#include "dsodefs.h"
 
 /// \namespace gnash
 ///    This is the main namespace for Gnash and it's libraries.
@@ -48,9 +49,9 @@
 public:
     Cache();
     ~Cache();
-    static Cache& getDefaultInstance();
+    DSOEXPORT static Cache& getDefaultInstance();
     
-    void addPath(const std::string &name, const std::string &fullpath);
+    void DSOEXPORT addPath(const std::string &name, const std::string 
&fullpath);
     std::string &findPath(const std::string &name);
     void removePath(const std::string &name);
     
@@ -59,7 +60,7 @@
     void removeResponse(const std::string &name);
     
     void addFile(const std::string &name, boost::shared_ptr<DiskStream > 
&file);
-    boost::shared_ptr<DiskStream> findFile(const std::string &name);
+    boost::shared_ptr<DiskStream> DSOEXPORT findFile(const std::string &name);
     void removeFile(const std::string &name);
     
     ///  \brief Dump the internal data of this class in a human readable form.
@@ -69,7 +70,7 @@
     void dump(std::ostream& os) const;    
 
 #ifdef USE_STATS_CACHE
-    std::string stats(bool xml) const;
+    std::string DSOEXPORT stats(bool xml) const;
 #endif
 private:
     /// \var Cache::_pathnames

=== modified file 'libnet/cque.cpp'
--- a/libnet/cque.cpp   2009-02-25 22:33:03 +0000
+++ b/libnet/cque.cpp   2009-03-26 19:24:16 +0000
@@ -93,7 +93,7 @@
 bool
 CQue::push(boost::shared_ptr<amf::Buffer> data)
 {
-    GNASH_REPORT_FUNCTION;
+//     GNASH_REPORT_FUNCTION;
     boost::mutex::scoped_lock lock(_mutex);
     _que.push_back(data);
 #ifdef USE_STATS_QUEUE
@@ -195,8 +195,17 @@
 // Merge sucessive buffers into one single larger buffer. This is for some
 // protocols, than have very long headers.
 boost::shared_ptr<amf::Buffer> 
+CQue::merge()
+{
+//     GNASH_REPORT_FUNCTION;
+    
+    return merge(_que.front());
+}
+
+boost::shared_ptr<amf::Buffer> 
 CQue::merge(boost::shared_ptr<amf::Buffer> start)
 {
+//     GNASH_REPORT_FUNCTION;
     // Find iterator to first element to merge
     que_t::iterator from = std::find(_que.begin(), _que.end(), start); 
     if (from == _que.end()) {
@@ -211,27 +220,29 @@
     for (que_t::iterator e=_que.end(); to!=e; ++to) {
         size_t sz = (*to)->size();
         totalsize += sz;
-        if (sz < amf::NETBUFSIZE) break;
-    }
-    if (to == _que.end()) {
-        // Didn't find an element ending the merge
-        return start;          // FIXME:
-    }
-
+//     log_debug("%s: Totalsize is %s", __PRETTY_FUNCTION__, totalsize);
+        if (sz < amf::NETBUFSIZE) {
+           break;
+       }
+    }
+    totalsize += 24;
+//     log_debug("%s: Final Totalsize is %s", __PRETTY_FUNCTION__, totalsize);
+    
     // Merge all elements in a single buffer. We have totalsize now.
     boost::shared_ptr<amf::Buffer> newbuf(new Buffer(totalsize));
-    boost::uint8_t *tmp = newbuf->reference();
-    ++to;
     for (que_t::iterator i=from; i!=to; ++i) {
-        boost::shared_ptr<amf::Buffer> buf = *i;
-        size_t sz = buf->size();
-        std::copy(buf->reference(), buf->reference() + sz, tmp);
+//     log_debug("%s: copying %d bytes, space left is %d, totalsize is %d", 
__PRETTY_FUNCTION__,
+//               (*i)->allocated(), newbuf->spaceLeft(), totalsize);
+//     (*i)->dump();
+//     if (newbuf->spaceLeft() >= (*i)->allocated()) {
+           *newbuf += *i;
+//     }
+       
        //
        // NOTE: If we're the buffer owners, it is safe to delete
        //       the buffer now.
        // delete buf;
        //
-        tmp += sz;
     }
 
     // Finally erase all merged elements, and replace with the composite one

=== modified file 'libnet/cque.h'
--- a/libnet/cque.h     2009-02-25 22:33:03 +0000
+++ b/libnet/cque.h     2009-03-25 22:30:54 +0000
@@ -17,7 +17,7 @@
 //
 
 #ifndef __CQUE_H__
-#define __CQUE_H__ 1
+#define __CQUE_H__
 
 #include <boost/cstdint.hpp>
 #include <boost/thread/mutex.hpp>
@@ -53,7 +53,7 @@
     // Pop the first date element off the que
     boost::shared_ptr<amf::Buffer> DSOEXPORT pop();
     // Peek at the first date element witjhout removing it from the que
-    boost::shared_ptr<amf::Buffer> peek();
+    boost::shared_ptr<amf::Buffer> DSOEXPORT peek();
     // Get the number of elements in the que
     size_t DSOEXPORT size();
     // Wait for a condition variable to trigger
@@ -69,7 +69,8 @@
     void remove(boost::shared_ptr<amf::Buffer> it);
     // Merge sucessive buffers into one single larger buffer. This is for some
     // protocols, than have very long headers.
-    boost::shared_ptr<amf::Buffer> merge(boost::shared_ptr<amf::Buffer> begin);
+    boost::shared_ptr<amf::Buffer> DSOEXPORT 
merge(boost::shared_ptr<amf::Buffer> begin);
+    boost::shared_ptr<amf::Buffer> DSOEXPORT merge();
 
     boost::shared_ptr<amf::Buffer> operator[] (int index) { return 
_que[index]; };
     

=== modified file 'libnet/diskstream.h'
--- a/libnet/diskstream.h       2009-02-27 16:59:46 +0000
+++ b/libnet/diskstream.h       2009-03-16 23:34:13 +0000
@@ -31,6 +31,7 @@
 #include "cque.h"
 #include "statistics.h"
 #include "getclocktime.hpp"
+#include "dsodefs.h"
 #include <boost/scoped_ptr.hpp>
 
 /// \namespace gnash
@@ -82,15 +83,15 @@
     FILETYPE_ENCODED
   } filetype_e;
 
-    DiskStream();
-    DiskStream(const std::string &filespec);
-    DiskStream(const std::string &filespec, amf::Buffer &buf);
-    DiskStream(const std::string &filespec, boost::uint8_t *data, size_t size);
-    DiskStream(const std::string &filespec, int netfd);
-    ~DiskStream();
+    DSOEXPORT DiskStream();
+    DSOEXPORT DiskStream(const std::string &filespec);
+    DSOEXPORT DiskStream(const std::string &filespec, amf::Buffer &buf);
+    DSOEXPORT DiskStream(const std::string &filespec, boost::uint8_t *data, 
size_t size);
+    DSOEXPORT DiskStream(const std::string &filespec, int netfd);
+    DSOEXPORT ~DiskStream();
 
     /// \brief Close the open disk file and it's associated stream.
-    void close();
+    DSOEXPORT void close();
 
     /// \brief Open a file to be streamed.
     ///
@@ -103,9 +104,9 @@
     ///                collecting statistics on this stream.
     ///
     /// @return True if the file was opened sucessfully, false if not.
-    bool open(const std::string &filespec);
-    bool open(const std::string &filespec, int netfd);
-    bool open(const std::string &filespec, int netfd, gnash::Statistics  
&statistics);
+    DSOEXPORT bool open(const std::string &filespec);
+    DSOEXPORT bool open(const std::string &filespec, int netfd);
+    DSOEXPORT bool open(const std::string &filespec, int netfd, 
gnash::Statistics  &statistics);
 
     /// \brief Stream the file that has been loaded,
     ///
@@ -178,9 +179,9 @@
     ///
     /// @return A real pointer to the location of the data at the
     ///                location pointed to by the offset.
-    boost::uint8_t *loadToMem(size_t filesize, off_t offset);
-    boost::uint8_t *loadToMem(off_t offset);
-    boost::uint8_t *loadToMem() { return loadToMem(_offset); };
+    DSOEXPORT boost::uint8_t *loadToMem(size_t filesize, off_t offset);
+    DSOEXPORT boost::uint8_t *loadToMem(off_t offset);
+    DSOEXPORT boost::uint8_t *loadToMem() { return loadToMem(_offset); };
 
     /// \brief Write the data in memory to disk
     ///
@@ -192,10 +193,10 @@
     /// @param size The amount of data in bytes to be written
     ///
     /// @return true if the operation suceeded, false if it failed.
-    bool writeToDisk(const std::string &filespec, boost::uint8_t *data, size_t 
size);
-    bool writeToDisk(const std::string &filespec, amf::Buffer &data);
-    bool writeToDisk(const std::string &filespec);
-    bool writeToDisk();
+    DSOEXPORT bool writeToDisk(const std::string &filespec, boost::uint8_t 
*data, size_t size);
+    DSOEXPORT bool writeToDisk(const std::string &filespec, amf::Buffer &data);
+    DSOEXPORT bool writeToDisk(const std::string &filespec);
+    DSOEXPORT bool writeToDisk();
 
     /// \brief Write the existing data to the Network.
     ///

=== modified file 'libnet/http.cpp'
--- a/libnet/http.cpp   2009-03-09 01:01:24 +0000
+++ b/libnet/http.cpp   2009-03-26 19:23:30 +0000
@@ -34,8 +34,8 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <algorithm>
+
 #include "GnashSystemIOHeaders.h" // read()
-
 #include "http.h"
 #include "amf.h"
 #include "element.h"
@@ -133,6 +133,220 @@
     return *this; 
 }
 
+
+boost::uint8_t *
+HTTP::processHeaderFields(amf::Buffer &buf)
+{
+  //    GNASH_REPORT_FUNCTION;
+    string head(reinterpret_cast<const char *>(buf.reference()));
+
+    // The end of the header block is always followed by a blank line
+    string::size_type end = head.find("\r\n\r\n", 0);
+//    head.erase(end, buf.size()-end);
+    Tok t(head, Sep("\r\n"));
+    for (Tok::iterator i = t.begin(); i != t.end(); ++i) {
+       string::size_type pos = i->find(":", 0);
+       if (pos != string::npos) {
+           string name = i->substr(0, pos);
+           string value = i->substr(pos+2, i->size());
+           std::transform(name.begin(), name.end(), name.begin(), 
+                          (int(*)(int)) tolower);
+           std::transform(value.begin(), value.end(), value.begin(), 
+                          (int(*)(int)) tolower);
+           _fields[name] = value;
+           if (name == "keep-alive") {
+               _keepalive = true;
+               if ((value != "on") && (value != "off")) {
+                   _max_requests = strtol(value.c_str(), NULL, 0);
+                   log_debug("Setting Max Requests for Keep-Alive to %d", 
_max_requests);
+               }
+           }
+           if (name == "connection") {
+               if (value.find("keep-alive", 0) != string::npos) {
+                   _keepalive = true;
+               }
+           }
+           if (name == "content-length") {
+               _filesize = strtol(value.c_str(), NULL, 0);
+               log_debug("Setting Content Length to %d", _filesize);
+           }
+           if (name == "content-type") {
+               // This is the type used by flash when sending a AMF data via 
POST
+               if (value == "application/x-amf") {
+//                 log_debug("Got AMF data in the POST request!");
+                   _filetype = DiskStream::FILETYPE_AMF;
+               }
+               // This is the type used by wget when sending a file via POST
+               if (value == "application/x-www-form-urlencoded") {
+//                 log_debug("Got file data in the POST request");
+                   _filetype = DiskStream::FILETYPE_ENCODED;
+               }
+               log_debug("Setting Content Type to %d", _filetype);
+           }
+           
+//         cerr << "FIXME: " << (void *)i << " : " << dec <<  end << endl;
+       } else {
+           const boost::uint8_t *cmd = reinterpret_cast<const boost::uint8_t 
*>(i->c_str());
+           if (extractCommand(const_cast<boost::uint8_t *>(cmd)) == 
HTTP::HTTP_NONE) {
+               break;
+#if 1
+           } else {
+               log_debug("Got a request, parsing \"%s\"", *i);
+               string::size_type start = i->find(" ");
+               string::size_type params = i->find("?");
+               string::size_type pos = i->find("HTTP/");
+               if (pos != string::npos) {
+                   // The version is the last field and is the protocol name
+                   // followed by a slash, and the version number. Note that
+                   // the version is not a double, even though it has a dot
+                   // in it. It's actually two separate integers.
+                   _version.major = i->at(pos+5) - '0';
+                   _version.minor = i->at(pos+7) - '0';
+                   log_debug (_("Version: %d.%d"), _version.major, 
_version.minor);
+                   // the filespec in the request is the middle field, 
deliminated
+                   // by a space on each end.
+                   if (params != string::npos) {
+                       _params = i->substr(params+1, end);
+                       _filespec = i->substr(start+1, params);
+                       log_debug("Parameters for file: \"%s\"", _params);
+                   } else {
+                       _filespec = i->substr(start+1, pos-start-2);
+                   }
+                   log_debug("Requesting file: \"%s\"", _filespec);
+
+                   // HTTP 1.1 enables persistant network connections
+                   // by default.
+                   if (_version.minor > 0) {
+                       log_debug("Enabling Keep Alive by default for HTTP > 
1.0");
+                       _keepalive = true;
+                   }
+               }
+           }
+#endif
+       }
+    }
+    
+    return buf.reference() + end + 4;
+}
+
+// // Parse an Echo Request message coming from the Red5 echo_test. This
+// // method should only be used for testing purposes.
+// vector<boost::shared_ptr<amf::Element > >
+// HTTP::parseEchoRequest(boost::uint8_t *data, size_t size)
+// {
+// //    GNASH_REPORT_FUNCTION;
+    
+//     vector<boost::shared_ptr<amf::Element > > headers;
+       
+//     // skip past the header bytes, we don't care about them.
+//     boost::uint8_t *tmpptr = data + 6;
+    
+//     boost::uint16_t length;
+//     length = ntohs((*(boost::uint16_t *)tmpptr) & 0xffff);
+//     tmpptr += sizeof(boost::uint16_t);
+
+//     // Get the first name, which is a raw string, and not preceded by
+//     // a type byte.
+//     boost::shared_ptr<amf::Element > el1(new amf::Element);
+    
+//     // If the length of the name field is corrupted, then we get out of
+//     // range quick, and corrupt memory. This is a bit of a hack, but
+//     // reduces memory errors caused by some of the corrupted tes cases.
+//     boost::uint8_t *endstr = std::find(tmpptr, tmpptr+length, '\0');
+//     if (endstr != tmpptr+length) {
+//     log_debug("Caught corrupted string! length was %d, null at %d",
+//               length,  endstr-tmpptr);
+//     length = endstr-tmpptr;
+//     }
+//     el1->setName(tmpptr, length);
+//     tmpptr += length;
+//     headers.push_back(el1);
+    
+//     // Get the second name, which is a raw string, and not preceded by
+//     // a type byte.
+//     length = ntohs((*(boost::uint16_t *)tmpptr) & 0xffff);
+//     tmpptr += sizeof(boost::uint16_t);
+//     boost::shared_ptr<amf::Element > el2(new amf::Element);
+
+// //     std::string name2(reinterpret_cast<const char *>(tmpptr), length);
+// //     el2->setName(name2.c_str(), name2.size());
+//     // If the length of the name field is corrupted, then we get out of
+//     // range quick, and corrupt memory. This is a bit of a hack, but
+//     // reduces memory errors caused by some of the corrupted tes cases.
+//     endstr = std::find(tmpptr, tmpptr+length, '\0');
+//     if (endstr != tmpptr+length) {
+//     log_debug("Caught corrupted string! length was %d, null at %d",
+//               length,  endstr-tmpptr);
+//     length = endstr-tmpptr;
+//     }
+//     el2->setName(tmpptr, length);
+//     headers.push_back(el2);
+//     tmpptr += length;
+
+//     // Get the last two pieces of data, which are both AMF encoded
+//     // with a type byte.
+//     amf::AMF amf;
+//     boost::shared_ptr<amf::Element> el3 = amf.extractAMF(tmpptr, tmpptr + 
size);
+//     headers.push_back(el3);
+//     tmpptr += amf.totalsize();
+    
+//     boost::shared_ptr<amf::Element> el4 = amf.extractAMF(tmpptr, tmpptr + 
size);
+//     headers.push_back(el4);
+
+//      return headers;
+// }
+
+// // format a response to the 'echo' test used for testing Gnash. This
+// // is only used for testing by developers. The format appears to be
+// // two strings, followed by a double, followed by the "onResult".
+// amf::Buffer &
+// HTTP::formatEchoResponse(const std::string &num, amf::Element &el)
+// {
+// //    GNASH_REPORT_FUNCTION;
+//     boost::shared_ptr<amf::Buffer> data;
+
+//     amf::Element nel;
+//     if (el.getType() == amf::Element::TYPED_OBJECT_AMF0) {
+//     nel.makeTypedObject();
+//     string name = el.getName();
+//     nel.setName(name);
+//     if (el.propertySize()) {
+//         // FIXME: see about using std::reverse() instead.
+//         for (int i=el.propertySize()-1; i>=0; i--) {
+// //      for (int i=0 ; i<el.propertySize(); i++) {
+//             boost::shared_ptr<amf::Element> child = el.getProperty(i);
+//             nel.addProperty(child);
+//         }
+//         data = nel.encode();
+//     } else {
+//         data = el.encode();
+//     }
+//     } else {
+//     data = el.encode();
+//     }
+
+//     return formatEchoResponse(num, data->reference(), data->allocated());
+// }
+
+#if 0                          // FIXME:
+// Client side parsing of response message codes
+boost::shared_ptr<HTTP::http_response_t> 
+HTTP::parseStatus(const std::string &line)
+{
+//    GNASH_REPORT_FUNCTION;
+
+    boost::shared_ptr<http_response_t> status;
+    // The respnse is a number followed by the error message.
+    string::size_type pos = line.find(" ", 0);
+    if (pos != string::npos) {
+       status.reset(new http_response_t);
+       status->code = static_cast<HTTP::http_status_e>(strtol(line.substr(0, 
pos).c_str(), NULL, 0));
+       status->msg = line.substr(pos+1, line.size());
+    }
+
+    return status;
+}
+
 HTTP::http_method_e
 HTTP::processClientRequest(int fd)
 {
@@ -417,6 +631,21 @@
     log_unimpl("TRACE request");
     return false;
 }
+#endif
+
+// Convert the Content-Length field to a number we can use
+size_t
+HTTP::getContentLength()
+{
+    //    GNASH_REPORT_FUNCTION;
+    std::string length = getField("content-length");
+    if (length.size() > 0) {
+       return static_cast<size_t>(strtol(length.c_str(), NULL, 0));
+    }
+
+    return 0;
+}
+
 
 // http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5 (5.3 Request 
Header Fields)
 bool
@@ -501,101 +730,6 @@
     return false;
 }
 
-boost::uint8_t *
-HTTP::processHeaderFields(amf::Buffer &buf)
-{
-  //    GNASH_REPORT_FUNCTION;
-    string head(reinterpret_cast<const char *>(buf.reference()));
-
-    // The end of the header block is always followed by a blank line
-    string::size_type end = head.find("\r\n\r\n", 0);
-//    head.erase(end, buf.size()-end);
-    Tok t(head, Sep("\r\n"));
-    for (Tok::iterator i = t.begin(); i != t.end(); ++i) {
-       string::size_type pos = i->find(":", 0);
-       if (pos != string::npos) {
-           string name = i->substr(0, pos);
-           string value = i->substr(pos+2, i->size());
-           std::transform(name.begin(), name.end(), name.begin(), 
-                          (int(*)(int)) tolower);
-           std::transform(value.begin(), value.end(), value.begin(), 
-                          (int(*)(int)) tolower);
-           _fields[name] = value;
-           if (name == "keep-alive") {
-               _keepalive = true;
-               if ((value != "on") && (value != "off")) {
-                   _max_requests = strtol(value.c_str(), NULL, 0);
-                   log_debug("Setting Max Requests for Keep-Alive to %d", 
_max_requests);
-               }
-           }
-           if (name == "connection") {
-               if (value.find("keep-alive", 0) != string::npos) {
-                   _keepalive = true;
-               }
-           }
-           if (name == "content-length") {
-               _filesize = strtol(value.c_str(), NULL, 0);
-               log_debug("Setting Content Length to %d", _filesize);
-           }
-           if (name == "content-type") {
-               // This is the type used by flash when sending a AMF data via 
POST
-               if (value == "application/x-amf") {
-//                 log_debug("Got AMF data in the POST request!");
-                   _filetype = DiskStream::FILETYPE_AMF;
-               }
-               // This is the type used by wget when sending a file via POST
-               if (value == "application/x-www-form-urlencoded") {
-//                 log_debug("Got file data in the POST request");
-                   _filetype = DiskStream::FILETYPE_ENCODED;
-               }
-               log_debug("Setting Content Type to %d", _filetype);
-           }
-           
-//         cerr << "FIXME: " << (void *)i << " : " << dec <<  end << endl;
-       } else {
-           const boost::uint8_t *cmd = reinterpret_cast<const boost::uint8_t 
*>(i->c_str());
-           if (extractCommand(const_cast<boost::uint8_t *>(cmd)) == 
HTTP::HTTP_NONE) {
-               break;
-#if 1
-           } else {
-               log_debug("Got a request, parsing \"%s\"", *i);
-               string::size_type start = i->find(" ");
-               string::size_type params = i->find("?");
-               string::size_type pos = i->find("HTTP/");
-               if (pos != string::npos) {
-                   // The version is the last field and is the protocol name
-                   // followed by a slash, and the version number. Note that
-                   // the version is not a double, even though it has a dot
-                   // in it. It's actually two separate integers.
-                   _version.major = i->at(pos+5) - '0';
-                   _version.minor = i->at(pos+7) - '0';
-                   log_debug (_("Version: %d.%d"), _version.major, 
_version.minor);
-                   // the filespec in the request is the middle field, 
deliminated
-                   // by a space on each end.
-                   if (params != string::npos) {
-                       _params = i->substr(params+1, end);
-                       _filespec = i->substr(start+1, params);
-                       log_debug("Parameters for file: \"%s\"", _params);
-                   } else {
-                       _filespec = i->substr(start+1, pos-start-2);
-                   }
-                   log_debug("Requesting file: \"%s\"", _filespec);
-
-                   // HTTP 1.1 enables persistant network connections
-                   // by default.
-                   if (_version.minor > 0) {
-                       log_debug("Enabling Keep Alive by default for HTTP > 
1.0");
-                       _keepalive = true;
-                   }
-               }
-           }
-#endif
-       }
-    }
-    
-    return buf.reference() + end + 4;
-}
-
 boost::shared_ptr<std::vector<std::string> >
 HTTP::getFieldItem(const std::string &name)
 {
@@ -818,43 +952,6 @@
 }
 
 amf::Buffer &
-HTTP::formatErrorResponse(http_status_e code)
-{
-//    GNASH_REPORT_FUNCTION;
-
-    char num[12];
-    // First build the message body, so we know how to set Content-Length
-    _buffer += "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n";
-    _buffer += "<html><head>\r\n";
-    _buffer += "<title>";
-    sprintf(num, "%d", code);
-    _buffer += num;
-    _buffer += " Not Found</title>\r\n";
-    _buffer += "</head><body>\r\n";
-    _buffer += "<h1>Not Found</h1>\r\n";
-    _buffer += "<p>The requested URL ";
-    _buffer += _filespec;
-    _buffer += " was not found on this server.</p>\r\n";
-    _buffer += "<hr>\r\n";
-    _buffer += "<address>Cygnal (GNU/Linux) Server at ";
-    _buffer += getField("host");
-    _buffer += " </address>\r\n";
-    _buffer += "</body></html>\r\n";
-
-    // First build the header
-    formatDate();
-    formatServer();
-    formatContentLength(_filesize);
-    formatConnection("close");
-    formatContentType(_filetype);
-
-    // All HTTP messages are followed by a blank line.
-    terminateHeader();
-
-    return _buffer;
-}
-
-amf::Buffer &
 HTTP::formatDate()
 {
 //    GNASH_REPORT_FUNCTION;
@@ -1026,170 +1123,6 @@
     return formatLastModified(date.str());
 }
 
-amf::Buffer &
-HTTP::formatGetReply(http_status_e code)
-{
-
-//    GNASH_REPORT_FUNCTION;
-    
-    return formatHeader(_filesize, code);
-}
-
-amf::Buffer &
-HTTP::formatGetReply(size_t size, http_status_e code)
-{
-//    GNASH_REPORT_FUNCTION;
-    
-    formatHeader(size, code);
-    
-//    int ret = Network::writeNet(_header.str());    
-//    boost::uint8_t *ptr = (boost::uint8_t *)_body.str().c_str();
-//     buf->copy(ptr, _body.str().size());
-//    _handler->dump();
-
-#if 0
-    if (_header.str().size()) {
-        log_debug (_("Sent GET Reply"));
-       return _buffer;
-    } else {
-       clearHeader();
-       log_debug (_("Couldn't send GET Reply, no header data"));
-    }    
-#endif
-    
-    return _buffer;
-}
-
-amf::Buffer &
-HTTP::formatPostReply(rtmpt_cmd_e /* code */)
-{
-    GNASH_REPORT_FUNCTION;
-
-    formatDate();
-    formatServer();
-    formatContentType(DiskStream::FILETYPE_AMF);
-    // All HTTP messages are followed by a blank line.
-    terminateHeader();
-    return _buffer;
-
-#if 0
-    formatHeader(_filesize, code);
-    boost::shared_ptr<amf::Buffer> buf = new amf::Buffer;
-    if (_header.str().size()) {
-       buf->resize(_header.str().size());
-       string str = _header.str();
-       buf->copy(str);
-       _handler->pushout(buf);
-       _handler->notifyout();
-        log_debug (_("Sent GET Reply"));
-       return true; // Default to true
-    } else {
-       clearHeader();
-       log_debug (_("Couldn't send POST Reply, no header data"));
-    }
-#endif
-
-    return _buffer;
-}
-
-// Parse an Echo Request message coming from the Red5 echo_test. This
-// method should only be used for testing purposes.
-vector<boost::shared_ptr<amf::Element > >
-HTTP::parseEchoRequest(boost::uint8_t *data, size_t size)
-{
-//    GNASH_REPORT_FUNCTION;
-    
-    vector<boost::shared_ptr<amf::Element > > headers;
-       
-    // skip past the header bytes, we don't care about them.
-    boost::uint8_t *tmpptr = data + 6;
-    
-    boost::uint16_t length;
-    length = ntohs((*(boost::uint16_t *)tmpptr) & 0xffff);
-    tmpptr += sizeof(boost::uint16_t);
-
-    // Get the first name, which is a raw string, and not preceded by
-    // a type byte.
-    boost::shared_ptr<amf::Element > el1(new amf::Element);
-    
-    // If the length of the name field is corrupted, then we get out of
-    // range quick, and corrupt memory. This is a bit of a hack, but
-    // reduces memory errors caused by some of the corrupted tes cases.
-    boost::uint8_t *endstr = std::find(tmpptr, tmpptr+length, '\0');
-    if (endstr != tmpptr+length) {
-       log_debug("Caught corrupted string! length was %d, null at %d",
-                 length,  endstr-tmpptr);
-       length = endstr-tmpptr;
-    }
-    el1->setName(tmpptr, length);
-    tmpptr += length;
-    headers.push_back(el1);
-    
-    // Get the second name, which is a raw string, and not preceded by
-    // a type byte.
-    length = ntohs((*(boost::uint16_t *)tmpptr) & 0xffff);
-    tmpptr += sizeof(boost::uint16_t);
-    boost::shared_ptr<amf::Element > el2(new amf::Element);
-
-//     std::string name2(reinterpret_cast<const char *>(tmpptr), length);
-//     el2->setName(name2.c_str(), name2.size());
-    // If the length of the name field is corrupted, then we get out of
-    // range quick, and corrupt memory. This is a bit of a hack, but
-    // reduces memory errors caused by some of the corrupted tes cases.
-    endstr = std::find(tmpptr, tmpptr+length, '\0');
-    if (endstr != tmpptr+length) {
-       log_debug("Caught corrupted string! length was %d, null at %d",
-                 length,  endstr-tmpptr);
-       length = endstr-tmpptr;
-    }
-    el2->setName(tmpptr, length);
-    headers.push_back(el2);
-    tmpptr += length;
-
-    // Get the last two pieces of data, which are both AMF encoded
-    // with a type byte.
-    amf::AMF amf;
-    boost::shared_ptr<amf::Element> el3 = amf.extractAMF(tmpptr, tmpptr + 
size);
-    headers.push_back(el3);
-    tmpptr += amf.totalsize();
-    
-    boost::shared_ptr<amf::Element> el4 = amf.extractAMF(tmpptr, tmpptr + 
size);
-    headers.push_back(el4);
-
-     return headers;
-}
-
-// format a response to the 'echo' test used for testing Gnash. This
-// is only used for testing by developers. The format appears to be
-// two strings, followed by a double, followed by the "onResult".
-amf::Buffer &
-HTTP::formatEchoResponse(const std::string &num, amf::Element &el)
-{
-//    GNASH_REPORT_FUNCTION;
-    boost::shared_ptr<amf::Buffer> data;
-
-    amf::Element nel;
-    if (el.getType() == amf::Element::TYPED_OBJECT_AMF0) {
-       nel.makeTypedObject();
-       string name = el.getName();
-       nel.setName(name);
-       if (el.propertySize()) {
-           // FIXME: see about using std::reverse() instead.
-           for (int i=el.propertySize()-1; i>=0; i--) {
-//         for (int i=0 ; i<el.propertySize(); i++) {
-               boost::shared_ptr<amf::Element> child = el.getProperty(i);
-               nel.addProperty(child);
-           }
-           data = nel.encode();
-       } else {
-           data = el.encode();
-       }
-    } else {
-       data = el.encode();
-    }
-
-    return formatEchoResponse(num, data->reference(), data->allocated());
-}
 
 amf::Buffer &
 HTTP::formatEchoResponse(const std::string &num, amf::Buffer &data)
@@ -1256,95 +1189,58 @@
 }
 
 amf::Buffer &
-HTTP::formatRequest(const string & /* url */, http_method_e /* req */)
+HTTP::formatRequest(const string &url, http_method_e cmd)
 {
 //    GNASH_REPORT_FUNCTION;
-
-#if 0
-    _header.str("");
-
-    _header << req << " " << url << "HTTP/1.1" << "\r\n";
-    _header << "User-Agent: Opera/9.01 (X11; Linux i686; U; en)" << "\r\n";
-    _header << "Accept: text/html, application/xml;q=0.9, 
application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, 
*/*;q=0.1" << "\r\n";
-
-    _header << "Accept-Language: en" << "\r\n";
-    _header << "Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1" << "\r\n";
-    
-    _header << "Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0" << 
"\r\n";
-    _header << "Referer: " << url << "\r\n";
-
-    _header << "TE: deflate, gzip, chunked, identity, trailers" << "\r\n";
-#endif
-    
+    
+    clearHeader();
+
+    switch (cmd) {
+    case HTTP::HTTP_GET:
+       _buffer = "GET ";
+       break;
+    case HTTP::HTTP_POST:
+       _buffer = "POST ";
+       break;
+    case HTTP::HTTP_HEAD:
+       _buffer = "HEAD ";
+       break;
+    case HTTP::HTTP_CONNECT:
+       _buffer = "CONNECT ";
+       break;
+    case HTTP::HTTP_TRACE:
+       _buffer = "TRACE ";
+       break;
+    case HTTP::HTTP_OPTIONS:
+       _buffer = "OPTIONS ";
+       break;
+    default:
+       break;
+    }
+    _buffer += url;
+
+    _buffer += " HTTP/1.1";
+//     sprintf(num, "%d.%d", _version.major, _version.minor);
+//     _buffer += num;
+    // end the line
+    _buffer += "\r\n";
+
+    formatHost("localhost");
+    formatAgent("Gnash");
+
+    // Post messages want a bunch more fields than a GET request
+    if (cmd == HTTP::HTTP_POST) {
+       formatContentType(DiskStream::FILETYPE_AMF);
+       formatEncoding("deflate, gzip, x-gzip, identity, *;q=0");
+       formatConnection("Keep-Alive");
+    }
+
+//     // All HTTP messages are followed by a blank line.
+//     terminateHeader();
+
     return _buffer;
 }
 
-/// These methods extract data from an RTMPT message. RTMP is an
-/// extension to HTTP that adds commands to manipulate the
-/// connection's persistance.
-//
-/// The URL to be opened has the following form:
-/// http://server/<comand>/[<client>/]<index>
-/// <command>
-///    denotes the RTMPT request type, "OPEN", "SEND", "IDLE", "CLOSE")
-/// <client>
-///    specifies the id of the client that performs the requests
-///    (only sent for established sessions)
-/// <index>
-///    is a consecutive number that seems to be used to detect missing packages
-HTTP::rtmpt_cmd_e
-HTTP::extractRTMPT(boost::uint8_t *data)
-{
-    GNASH_REPORT_FUNCTION;
-
-    string body = reinterpret_cast<const char *>(data);
-    string tmp, cid, indx;
-    HTTP::rtmpt_cmd_e cmd;
-
-    // force the case to make comparisons easier
-    std::transform(body.begin(), body.end(), body.begin(), 
-               (int(*)(int)) toupper);
-    string::size_type start, end;
-
-    // Extract the command first
-    start = body.find("OPEN", 0);
-    if (start != string::npos) {
-        cmd = HTTP::OPEN;
-    }
-    start = body.find("SEND", 0);
-    if (start != string::npos) {
-        cmd = HTTP::SEND;
-    }
-    start = body.find("IDLE", 0);
-    if (start != string::npos) {
-        cmd = HTTP::IDLE;
-    }
-    start = body.find("CLOSE", 0);
-    if (start != string::npos) {
-        cmd = HTTP::CLOSE;
-    }
-
-    // Extract the optional client id
-    start = body.find("/", start+1);
-    if (start != string::npos) {
-       end = body.find("/", start+1);
-       if (end != string::npos) {
-           indx = body.substr(end, body.size());
-           cid = body.substr(start, (end-start));
-       } else {
-           cid = body.substr(start, body.size());
-       }
-    }
-
-    _index = strtol(indx.c_str(), NULL, 0);
-    _clientid = strtol(cid.c_str(), NULL, 0);
-    end =  body.find("\r\n", start);
-//     if (end != string::npos) {
-//         cmd = HTTP::CLOSE;
-//     }
-
-    return cmd;
-}
 
 HTTP::http_method_e
 HTTP::extractCommand(boost::uint8_t *data)
@@ -1375,6 +1271,8 @@
         cmd = HTTP::HTTP_OPTIONS;
     } else if (memcmp(data, "DELETE", 4) == 0) {
         cmd = HTTP::HTTP_DELETE;
+    } else if (memcmp(data, "HTTP", 4) == 0) {
+        cmd = HTTP::HTTP_RESPONSE;
     }
 
     // For valid requests, the second argument, delimited by spaces
@@ -1451,18 +1349,152 @@
     return Network::writeNet(data, size);
 }
 
+size_t
+HTTP::recvChunked(boost::uint8_t *data, size_t size)
+{
+//     GNASH_REPORT_FUNCTION;
+    bool done = false;
+    bool chunks = true;
+    size_t total = 0;
+    size_t pktsize = 0;
+    
+    if (size == 0) {
+       return 0;
+    }
+    
+    // A chunked transfer sends a count of bytes in ASCII hex first,
+    // and that line is terminated with the usual \r\n HTTP header field
+    // line number. There is supposed to be a ';' before the \r\n, as this
+    // field can have other attributes, but the OpenStreetMap server doesn't
+    // use the semi-colon, as it's optional, and rarely used anyway.
+    boost::shared_ptr<amf::Buffer> buf;
+    boost::uint8_t *start = std::find(data, data+size, '\r') + 2;
+    if (start != data+size) {
+       // extract the total size of the chunk
+       std::string bytes(data, start-2);
+       size_t sizesize = start-data;
+       total = static_cast<size_t>(strtol(bytes.c_str(), NULL, 16));
+       log_debug("%s: Total size for first chunk is: %d, data size %d (%d)",
+                 __PRETTY_FUNCTION__, total, size, sizesize);
+       buf.reset(new amf::Buffer(total+2));
+       // Add the existing data from the previous packet
+       buf->copy(data+sizesize, size-sizesize);
+    }
+
+    // The size of the packet we need to read has a 2 byte terminator "\r\n",
+    // like any other HTTP header field, so we have to read those bytes too
+    // so we can stay sychronized with the start of each chunk.
+    pktsize = total - buf->allocated() + 2;
+//     log_debug("%s: Total Packet size for first chunk is: %d", 
__PRETTY_FUNCTION__,
+//           pktsize);
+    
+    done = false;
+    size_t ret = 0;
+
+    // Keep reading chunks as long as they arrive
+    while (chunks) {
+       do {
+           if (!pktsize) {
+               total = 0;
+               // Only read a few bytes, as we have todo a resize, so the less
+               // data to copy the better. We only do this to get the total 
size
+               // of the chunk, which we need to know when it's done. As we 
can't
+               // tell we're done processing chunks till one has a length of
+               // "0\r\n", this is important.
+               pktsize = 12;
+               buf.reset(new amf::Buffer(pktsize+2));
+           }
+           ret = readNet(buf->reference() + buf->allocated(), pktsize, 60);
+           //buf->dump();
+           // We got data.
+           if (ret == 0) {
+               log_debug("no data yet for fd #%d, continuing...", getFileFd());
+               done = true;
+           }
+           if (ret) {
+               // manually set the seek pointer in the buffer, as we read
+               // the data into the raw memory allocated to the buffer. We
+               // only want to do this if we got data of course.
+               buf->setSeekPointer(buf->end() + ret);
+               if (!total) {
+                   start = std::find(buf->reference(), buf->reference()+ret, 
'\r') + 2;
+                   if (start != buf->reference()+ret) {
+                       // extract the total size of the chunk
+                       std::string bytes(buf->reference(), start-2);
+                       total = static_cast<size_t>(strtol(bytes.c_str(), NULL, 
16));
+                       // The total size of the last chunk is always "0"
+                       if (total == 0) {
+                           log_debug("%s: end of chunks!", 
__PRETTY_FUNCTION__);
+                           pktsize = 0;
+                           done = true;
+                           chunks = false;
+                       } else {
+                           pktsize = total+8; // FIXME: why do we need an 8 
here ?
+//                         log_debug("%s: Total size for chunk is: %d (%s), 
adding %d bytes",
+//                                   __PRETTY_FUNCTION__, total, bytes, (start 
- buf->reference()));
+                           amf::Buffer tmpbuf(start - buf->reference());
+                           // don't forget the two bytes for the "\r\n"
+                           tmpbuf.copy(buf->reference() + bytes.size() + 2, 
(start - buf->reference()));
+                           buf->clear(); // FIXME: debug only
+                           buf->resize(total);
+                           buf->copy(tmpbuf.reference(), tmpbuf.size());
+                       }
+                   }
+               }
+               
+               // If we got less data than specified, we need to keep reading 
data
+               if (ret < buf->size()) {
+                   pktsize -= ret;
+                   if (pktsize == 0) {
+                       done = true;
+                   } else {
+//                     log_debug("Didn't get a full packet, reading more 
data");
+                       continue;
+                   }
+               }
+           }
+       } while (!done);
+//     log_debug("%s: finished packet, ret is %d, pktsize is %d\r\n%s", 
__PRETTY_FUNCTION__, ret, pktsize,
+//               hexify(buf->reference(), buf->allocated(), true));
+       if (pktsize == 0) {
+           // The last two bytes of the chunk are always "\r\n", which we 
remove so it
+           // doesn't become part of the binary data being sent in the chunk.
+           if ((*(buf->end()-2) == '\r') && (*(buf->end()-1) == '\n')) {
+               *(buf->end()-2) = 0; // '\r'
+               *(buf->end()-1) = 0; // '\n'
+               buf->setSeekPointer(buf->end() - 2);
+           }
+           _que.push(buf);
+       }
+       done = false;           // reset
+    } // end of while chunks
+    
+    return _que.size();
+}
+
 int
 HTTP::recvMsg(int fd)
 {
+//     GNASH_REPORT_FUNCTION;
+    return recvMsg(fd, 0);
+}
+
+int
+HTTP::recvMsg(int fd, size_t size)
+{
     GNASH_REPORT_FUNCTION;
-    int ret = 0;
+    size_t ret = 0;
+
+    if (size == 0) {
+       size = amf::NETBUFSIZE;
+    }
     
     log_debug("Starting to wait for data in net for fd #%d", fd);
     Network net;
 
     do {
-       boost::shared_ptr<amf::Buffer> buf(new amf::Buffer);
-       int ret = net.readNet(fd, *buf, 5);
+       boost::shared_ptr<amf::Buffer> buf(new amf::Buffer(size));
+       ret = net.readNet(fd, *buf, 5);
 //     cerr << __PRETTY_FUNCTION__ << ret << " : " << (char *)buf->reference() 
<< endl;
 
        // the read timed out as there was no data, but the socket is still 
open.
@@ -1472,7 +1504,7 @@
        }
        // ret is "no position" when the socket is closed from the other end of 
the connection,
        // so we're done.
-       if ((ret == static_cast<int>(string::npos)) || (ret == -1)) {
+       if ((ret == static_cast<size_t>(string::npos)) || 
(static_cast<int>(ret) == -1)) {
            log_debug("socket for fd #%d was closed...", fd);
            return 0;
        }
@@ -1488,16 +1520,15 @@
            } else {
                _que.push(buf);
            }
-
-        // ret must be more than 0 here
-           if (static_cast<size_t>(ret) == buf->size()) {
+           // ret must be more than 0 here
+           if (ret == buf->size()) {
                continue;
            }
        } else {
            log_debug("no more data for fd #%d, exiting...", fd);
            return 0;
        }
-       if (ret == -1) {
+       if (static_cast<int>(ret) == -1) {
          log_debug("Handler done for fd #%d, can't read any data...", fd);
          return -1;
        }
@@ -1509,6 +1540,7 @@
     return ret;
 }
 
+
 void
 HTTP::dump() {
 //    GNASH_REPORT_FUNCTION;
@@ -1530,92 +1562,6 @@
     log_debug (_("==== ==== ===="));
 }
 
-extern "C" {
-bool
-http_handler(Network::thread_params_t *args)
-{
-//    GNASH_REPORT_FUNCTION;
-//    struct thread_params thread_data;
-    string url, filespec, parameters;
-    HTTP *www = new HTTP;
-    bool result = false;
-    
-//    Network *net = reinterpret_cast<Network *>(args->handler);
-    bool done = false;
-//    www.setHandler(net);
-
-    log_debug(_("Starting HTTP Handler for fd #%d, tid %ld"),
-             args->netfd, get_thread_id());
-    
-    string docroot = args->filespec;
-
-    www->setDocRoot(docroot);
-    log_debug("Starting to wait for data in net for fd #%d", args->netfd);
-
-    // Wait for data, and when we get it, process it.
-    do {
-       
-#ifdef USE_STATISTICS
-       struct timespec start;
-       clock_gettime (CLOCK_REALTIME, &start);
-#endif
-
-       // See if we have any messages waiting
-       if (www->recvMsg(args->netfd) == 0) {
-           done = true;
-       }
-
-       // Process incoming messages
-       if (!www->processClientRequest(args->netfd)) {
-//         hand->die();        // tell all the threads for this connection to 
die
-//         hand->notifyin();
-           log_debug("Net HTTP done for fd #%d...", args->netfd);
-//         done = true;
-       }
-//     www.dump();
-       
-#if 0
-       string response = cache.findResponse(filestream->getFilespec());
-       if (response.empty()) {
-           cerr << "FIXME no cache hit for: " << www.getFilespec() << endl;
-//         www.clearHeader();
-//         amf::Buffer &ss = www.formatHeader(filestream->getFileSize(), 
HTTP::LIFE_IS_GOOD);
-//         www.writeNet(args->netfd, (boost::uint8_t 
*)www.getHeader().c_str(), www.getHeader().size());
-//         cache.addResponse(www.getFilespec(), www.getHeader());
-       } else {
-           cerr << "FIXME cache hit on: " << www.getFilespec() << endl;
-           www.writeNet(args->netfd, (boost::uint8_t *)response.c_str(), 
response.size());
-       }       
-#endif
-       
-       // Unless the Keep-Alive flag is set, this isn't a persisant network
-       // connection.
-       if (!www->keepAlive()) {
-           log_debug("Keep-Alive is off", www->keepAlive());
-           result = false;
-           done = true;
-       } else {
-           log_debug("Keep-Alive is on", www->keepAlive());
-           result = true;
-//         done = true;
-       }
-#ifdef USE_STATISTICS
-       struct timespec end;
-       clock_gettime (CLOCK_REALTIME, &end);
-       log_debug("Processing time for GET request was %f seconds",
-                 (float)((end.tv_sec - start.tv_sec) + ((end.tv_nsec - 
start.tv_nsec)/1e9)));
-#endif
-    } while(done != true);
-    
-//    hand->notify();
-    
-    log_debug("http_handler all done now finally...");
-
-    return result;
-} // end of httphandler
-    
-} // end of extern C
-
 } // end of gnash namespace
 
 

=== modified file 'libnet/http.h'
--- a/libnet/http.h     2009-03-09 01:01:24 +0000
+++ b/libnet/http.h     2009-03-25 22:31:57 +0000
@@ -108,7 +108,8 @@
         HTTP_PUT,
         HTTP_DELETE,
         HTTP_TRACE,
-        HTTP_CONNECT
+        HTTP_CONNECT,
+       HTTP_RESPONSE           // unique to gnash
     } http_method_e;
     typedef enum {
        OPEN,
@@ -116,10 +117,11 @@
        IDLE,
        CLOSE
     } rtmpt_cmd_e;
-    struct status_codes {
-        const char *code;
-        const char *msg;
-    };
+    // A response from an FTTP request has a code an an error message
+    typedef struct {
+       http_status_e code;
+       std::string   msg;
+    } http_response_t;
     typedef struct {
        int major;
        int minor;
@@ -128,26 +130,18 @@
     HTTP(Handler *hand);
     ~HTTP();
 
-    // These are for the protocol itself
-    http_method_e processClientRequest(int fd);
-    bool processGetRequest(int fd);
-    bool processPostRequest(int fd);
-    bool processPutRequest(int fd);
-    bool processDeleteRequest(int fd);
-    bool processConnectRequest(int fd);
-    bool processOptionsRequest(int fd);
-    bool processHeadRequest(int fd);
-    bool processTraceRequest(int fd);
-
     // Check the Header fields to make sure they're valid values.
     bool checkRequestFields(amf::Buffer &buf);
     bool checkEntityFields(amf::Buffer &buf);
     bool checkGeneralFields(amf::Buffer &buf);
 
-    // Parse an Echo Request message coming from the Red5 echo_test.
+//     // Parse an Echo Request message coming from the Red5 echo_test.
     std::vector<boost::shared_ptr<amf::Element > > 
parseEchoRequest(amf::Buffer &buf) { return parseEchoRequest(buf.reference(), 
buf.size()); };
     std::vector<boost::shared_ptr<amf::Element > > 
parseEchoRequest(boost::uint8_t *buf, size_t size);
     
+    // Convert the Content-Length field to a number we can use
+    size_t getContentLength();
+
     // process all the header fields in the Buffer, storing them internally
     // in _fields. The address returned is the address where the Content data
     // starts, and is "Content-Length" bytes long, of "Content-Type" data.
@@ -160,7 +154,10 @@
 
     // Get an array of values for header field 'name'.
     boost::shared_ptr<std::vector<std::string> > getFieldItem(const 
std::string &name);
-    
+
+    // Client side parsing of response message codes
+    boost::shared_ptr<http_response_t> parseStatus(const std::string &line);
+
     // Handle the response for the request.
     boost::shared_ptr<amf::Buffer> formatServerReply(http_status_e code);
     amf::Buffer &formatGetReply(DiskStream::filetype_e type, size_t size, 
http_status_e code); 
@@ -171,19 +168,6 @@
     // Make copies of ourself
     HTTP &operator = (HTTP &obj);
 
-    // These methods extract data from an RTMPT message. RTMP is an
-    // extension to HTTP that adds commands to manipulate the
-    // connection's persistance.
-    rtmpt_cmd_e extractRTMPT(boost::uint8_t *data);
-    rtmpt_cmd_e extractRTMPT(amf::Buffer &data)
-       { return extractRTMPT(data.reference()); };
-
-    // Examine the beginning of the data for an HTTP request command
-    // like GET or POST, etc...
-    http_method_e extractCommand(boost::uint8_t *data);
-    http_method_e extractCommand(amf::Buffer &data)
-       { return extractCommand(data.reference()); };    
-    
     /// @note These methods add data to the fields in the HTTP header.
     /// \brief clear the data in the stored header
     bool clearHeader();
@@ -249,7 +233,7 @@
     // All HTTP messages are terminated with a blank line
     void terminateHeader() { _buffer += "\r\n"; };    
     
-    amf::Buffer &formatErrorResponse(http_status_e err);
+//     amf::Buffer &formatErrorResponse(http_status_e err);
     
     // Return the header that's been built up.
     boost::uint8_t *getHeader() { return _buffer.reference(); };
@@ -271,8 +255,11 @@
     /// @param fd The file descriptor to read from
     ///
     /// @return The number of bytes sent
-    int DSOEXPORT recvMsg(int fd);
+    int recvMsg(int fd);
+    int recvMsg(int fd, size_t size);
 
+    size_t recvChunked(boost::uint8_t *data, size_t size);
+    
     /// \brief Send a message to the other end of the network connection.
     ///
     /// @param data A real pointer to the data.
@@ -283,12 +270,12 @@
     /// @param void Send the contents of the _header and _body.
     ///
     /// @return The number of bytes sent
-    int DSOEXPORT sendMsg();
-    int DSOEXPORT sendMsg(int fd);
-    int DSOEXPORT sendMsg(const boost::uint8_t *data, size_t size);
-    int DSOEXPORT sendMsg(boost::shared_ptr<amf::Buffer> &buf)
+    int sendMsg();
+    int sendMsg(int fd);
+    int sendMsg(const boost::uint8_t *data, size_t size);
+    int sendMsg(boost::shared_ptr<amf::Buffer> &buf)
        { return sendMsg(buf->reference(), buf->size()); };
-    int DSOEXPORT sendMsg(std::stringstream &sstr)
+    int sendMsg(std::stringstream &sstr)
        { return sendMsg(reinterpret_cast<const boost::uint8_t 
*>(sstr.str().c_str()), sstr.str().size()); };
     
     // These accessors are used mostly just for debugging.
@@ -304,8 +291,24 @@
     
     void setHandler(Handler *hand) { _handler = hand; };
     void setDocRoot(const std::string &path) { _docroot = path; };
-    
-private:
+    std::string &getDocRoot() { return _docroot; };
+    
+    // Pop the first date element off the que
+    boost::shared_ptr<amf::Buffer> DSOEXPORT popChunk() { return _que.pop(); };
+    // Peek at the first date element witjhout removing it from the que
+    boost::shared_ptr<amf::Buffer> DSOEXPORT peekChunk() { return _que.peek(); 
};
+    // Get the number of elements in the que
+    size_t DSOEXPORT sizeChunks() { return _que.size(); };
+
+    boost::shared_ptr<amf::Buffer> DSOEXPORT mergeChunks() { return 
_que.merge(); };
+    
+protected:
+    // Examine the beginning of the data for an HTTP request command
+    // like GET or POST, etc...
+    http_method_e extractCommand(boost::uint8_t *data);
+    http_method_e extractCommand(amf::Buffer &data)
+       { return extractCommand(data.reference()); };    
+
     typedef boost::char_separator<char> Sep;
     typedef boost::tokenizer<Sep> Tok;
     http_method_e      _cmd;
@@ -332,7 +335,7 @@
     std::string                _docroot;
 };  
 
-// This is the thread for all incoming HTTP connections
+// This is the thread for all incoming HTTP connections for the server
 extern "C" {
     bool DSOEXPORT http_handler(Network::thread_params_t *args);
 }

=== modified file 'libnet/network.cpp'
--- a/libnet/network.cpp        2009-05-04 22:20:08 +0000
+++ b/libnet/network.cpp        2009-06-07 21:14:22 +0000
@@ -139,15 +139,7 @@
     struct sockaddr_in sock_in;
     int             on, type;
     int             retries = 0;
-    in_addr_t       nodeaddr;
 
-#if 0
-    if (port < 1024) {
-       log_error(_("Can't connect to privileged port #%d"), port);
-       return -1;
-    }
-#endif
-    
     if (_listenfd >= 2) {
        log_debug("already connected to port %hd", port);
        return _listenfd;
@@ -201,6 +193,7 @@
 
     retries = 0;
 
+//     in_addr_t       nodeaddr;
 //     nodeaddr = inet_lnaof(*thisaddr);
     while (retries < 5) {
         if (bind(_listenfd, reinterpret_cast<struct sockaddr *>(&sock_in),
@@ -355,6 +348,7 @@
         if (ret == 0) {
             if (_debug) {
                 log_debug(_("The accept() socket for fd #%d timed out waiting 
to write"), fd);
+               return 0;
             }
         }
        
@@ -520,12 +514,9 @@
     char                thishostname[MAXHOSTNAMELEN];
     struct protoent     *proto;
 
-    assert( ! connected() );
-
-    if (port < 1024) {
-        log_error(_("Can't connect to privileged port %hd"), port);
-        _connected = false;
-        return false;
+//    assert( ! connected() );
+    if (connected()) {
+       return true;
     }
 
     _port = port;    
@@ -824,6 +815,8 @@
     fd_set              fdset;
     int                 ret = -1;
 
+//     boost::mutex::scoped_lock lock(_net_mutex);
+
     if (_debug) {
        log_debug (_("Trying to read %d bytes from fd #%d"), nbytes, fd);
     }
@@ -1001,6 +994,8 @@
     fd_set              fdset;
     int                 ret = -1;
 
+    boost::mutex::scoped_lock lock(_net_mutex);
+    
     // We need a writable, and not const point for byte arithmetic.
     byte_t *bufptr = const_cast<byte_t *>(buffer);
 

=== modified file 'libnet/network.h'
--- a/libnet/network.h  2009-05-15 19:38:36 +0000
+++ b/libnet/network.h  2009-06-07 21:14:22 +0000
@@ -60,10 +60,10 @@
 namespace gnash {
 
 // Define the ports for the RTMP protocols
-const short ADMIN_PORT = 1111;
-const short RTMP_PORT = 1935;
-const short RTMPE_PORT = 1935;
-const short RTMPT_PORT = 80;
+const short ADMIN_PORT  = 1111;
+const short RTMP_PORT   = 1935;
+const short RTMPE_PORT  = 1935;
+const short RTMPT_PORT  = 80;
 const short RTMPTE_PORT = 80;
 const short RTMPTS_PORT = 443;
 
@@ -234,10 +234,20 @@
     int getListenFd() const { return _listenfd; };
     void setListenFd(int x) { _listenfd = x; };
     const std::string& getURL() const { return _url; }
+    void setURL(const std::string& url) { _url = url; }
+
     const std::string& getProtocol() const  { return _protocol; }
+    void setProtocol(const std::string& proto) { _protocol = proto; }
+
     const std::string& getHost() const { return _host; }
+    void setHost(const std::string& host) { _host = host; }
+
     const std::string& getPortStr() const { return _portstr; }
+    void setPortStr(const std::string& port) { _portstr = port; }
+
     const std::string& getPath() const { return _path; }
+    void setPath(const std::string& path) { _path = path; }
+
     void setTimeout(int x) { _timeout = x; }
     int getTimeout() const { return _timeout; }
 
@@ -277,12 +287,14 @@
     bool        _connected;
     bool        _debug;
     int         _timeout;
+    size_t     _bytes_loaded;
     /// \var Handler::_handlers
     ///                Keep a list of all active network connections
     std::map<int, entry_t *> _handlers;
     std::vector<struct pollfd> _pollfds;
     // This is the mutex that controls access to the que.
     boost::mutex       _poll_mutex;
+    boost::mutex       _net_mutex;
 };
 
 } // end of gnash namespace

=== modified file 'libnet/rtmp.cpp'
--- a/libnet/rtmp.cpp   2009-02-25 22:33:03 +0000
+++ b/libnet/rtmp.cpp   2009-04-05 21:19:54 +0000
@@ -94,7 +94,8 @@
     "Blank 0x11",
     "Notify",
     "Shared object",
-    "Invoke"
+    "Invoke",
+    "FLV Data"
 };
 
 const char *ping_str[] = {
@@ -273,10 +274,10 @@
     boost::uint8_t *tmpptr = in;
 
     head->channel = *tmpptr & RTMP_INDEX_MASK;
-    log_debug (_("The AMF channel index is %d"), head->channel);
+//     log_debug (_("The AMF channel index is %d"), head->channel);
     
     head->head_size = headerSize(*tmpptr++);
-    log_debug (_("The header size is %d"), head->head_size);
+//     log_debug (_("The header size is %d"), head->head_size);
 
     if (head->head_size > RTMP_MAX_HEADER_SIZE) {
        head.reset();
@@ -290,7 +291,7 @@
         _mystery_word = (_mystery_word << 8) + *tmpptr++;
         _mystery_word = (_mystery_word << 8) + *tmpptr++;
 
-        log_debug(_("The mystery word is: %d"), _mystery_word);
+//         log_debug(_("The mystery word is: %d"), _mystery_word);
     }
 
     if (head->head_size >= 8) {
@@ -298,54 +299,38 @@
         head->bodysize = (head->bodysize << 8) + *tmpptr++;
         head->bodysize = (head->bodysize << 8) + *tmpptr++;
         head->bodysize = head->bodysize & 0xffffff;
-        log_debug(_("The body size is: %d"), head->bodysize);
+//         log_debug(_("The body size is: %d"), head->bodysize);
     }
 
     if (head->head_size >= 8) {
        boost::uint8_t byte = *tmpptr;
         head->type = (content_types_e)byte;
         tmpptr++;
-       if (head->type <= RTMP::INVOKE ) {
-           log_debug(_("The type is: %s"), content_str[head->type]);
-       } else {
-           log_debug(_("The type is: 0x%x"), head->type);
-       }
+//     if (head->type <= RTMP::INVOKE ) {
+//         log_debug(_("The type is: %s"), content_str[head->type]);
+//     } else {
+//         log_debug(_("The type is: 0x%x"), head->type);
+//     }
     }
 
     if (head->head_size == 1) {
        if (head->channel == RTMP_SYSTEM_CHANNEL) {
            head->bodysize = sizeof(boost::uint16_t) * 3;
-           log_debug("Got a one byte header system message: %s", hexify(in, 
head->bodysize, false));
+//         log_debug("Got a one byte header system message: %s", hexify(in, 
head->bodysize, false));
        } else {
-           log_debug("Got a continuation packet for channel #%d", 
head->channel);
-           head->bodysize = 0;
+//         log_debug("Got a continuation packet for channel #%d", 
head->channel);
+           head->bodysize = _lastsize[head->channel];
        }
     }
-    
-//     switch(head->type) {
-//       case CHUNK_SIZE:
-//       case BYTES_READ:
-//       case PING:
-//       case SERVER:
-//       case CLIENT:
-//       case VIDEO_DATA:
-//       case NOTIFY:
-//       case SHARED_OBJ:
-//       case INVOKE:
-//           _packet_size = RTMP_VIDEO_PACKET_SIZE;
-//           break;
-//       case AUDIO_DATA:
-//           _packet_size = RTMP_AUDIO_PACKET_SIZE;
-//           break;
-//       default:
-//           log_error (_("ERROR: Unidentified AMF header data type 0x%x"), 
_type);
-//           break;
-//     };
-    
+
+    log_debug("RTMP %s: channel: %d, header_size %d, bodysize: %d",
+             ((head->head_size == 1) ? "same" : content_str[head->type]),
+             head->channel, head->head_size, head->bodysize);
+
     if (head->head_size == 12) {
         head->src_dest = *(reinterpret_cast<RTMPMsg::rtmp_source_e *>(tmpptr));
         tmpptr += sizeof(unsigned int);
-        log_debug(_("The source/destination is: %x"), head->src_dest);
+//         log_debug(_("The source/destination is: %x"), head->src_dest);
     }
 
     return head;
@@ -629,14 +614,15 @@
 // 10629:3086592224] 20:01:20 DEBUG: read 29 bytes from fd 3 from port 0
 // address@hidden
 // 43 00 00 00 00 00 15 14 02 00 08 6f 6e 42 57 44 6f 6e 65 00 40 00 00 00 00 
00 00 00 05
-RTMPMsg *
+boost::shared_ptr<RTMPMsg>
 RTMP::decodeMsgBody(boost::uint8_t *data, size_t size)
 {
-    GNASH_REPORT_FUNCTION;
+//     GNASH_REPORT_FUNCTION;
     AMF amf_obj;
     boost::uint8_t *ptr = data;
     boost::uint8_t* tooFar = ptr + size;
     bool status = false;
+    boost::shared_ptr<RTMPMsg> msg(new RTMPMsg);
 
     // The first data object is the method name of this object.
     boost::shared_ptr<amf::Element> name = amf_obj.extractAMF(ptr, tooFar);
@@ -644,7 +630,8 @@
        ptr += name->getDataSize() + AMF_HEADER_SIZE; // skip the length bytes 
too
     } else {
        log_error("Name field of RTMP Message corrupted!");
-       return 0;
+       msg.reset();
+       return msg;
     }
 
     // The stream ID is the second data object. All messages have these two 
objects
@@ -658,14 +645,10 @@
        }
     } else {
        log_error("Stream ID field of RTMP Message corrupted!");
-       return 0;
+       msg.reset();
+       return msg;
     }
 
-    // This will need to be deleted manually later after usage, it is not
-    // automatically deallocated.
-    RTMPMsg *msg = new RTMPMsg;
-//    memset(msg, 0, sizeof(RTMPMsg));
-
     if (name->to_string() != 0) {
        msg->setMethodName(name->to_string());
     }
@@ -696,7 +679,7 @@
     return msg;
 }
 
-RTMPMsg *
+boost::shared_ptr<RTMPMsg> 
 RTMP::decodeMsgBody(amf::Buffer &buf)
 {
 //    GNASH_REPORT_FUNCTION;
@@ -842,6 +825,15 @@
 // interval. The byte boundary defaults to 128 bytes (video data), but can
 // be changed by the ChunkSize() command.
 bool
+RTMP::sendMsg(int channel, rtmp_headersize_e head_size,
+             size_t total_size, content_types_e type,
+             RTMPMsg::rtmp_source_e routing, amf::Buffer &data)
+{
+//    GNASH_REPORT_FUNCTION;
+    return sendMsg(getFileFd(), channel, head_size, total_size, type, routing, 
data.reference(), data.allocated());
+}
+
+bool
 RTMP::sendMsg(int fd, int channel, rtmp_headersize_e head_size,
              size_t total_size, content_types_e type,
              RTMPMsg::rtmp_source_e routing, amf::Buffer &data)
@@ -850,6 +842,16 @@
     return sendMsg(fd, channel, head_size, total_size, type, routing, 
data.reference(), data.allocated());
 }
 
+
+bool
+RTMP::sendMsg(int channel, rtmp_headersize_e head_size,
+             size_t total_size, content_types_e type,
+             RTMPMsg::rtmp_source_e routing, boost::uint8_t *data, size_t size)
+{
+//  GNASH_REPORT_FUNCTION;
+    return sendMsg(getFileFd(), channel, head_size, total_size, type, routing, 
data, size);
+}
+
 bool
 RTMP::sendMsg(int fd, int channel, rtmp_headersize_e head_size,
              size_t total_size, content_types_e type,
@@ -877,6 +879,7 @@
 
     // First send the full header, afterwards we only use continuation
     // headers, which are only one byte.
+    sleep(1);
     ret = writeNet(fd, head->reference(), head->size());
     if (ret == -1) {
        log_error("Couldn't write the RTMP header!");
@@ -1076,7 +1079,7 @@
 boost::shared_ptr<amf::Buffer> 
 RTMP::recvMsg(int fd)
 {
-    GNASH_REPORT_FUNCTION;
+//     GNASH_REPORT_FUNCTION;
 
     int ret = 0;
     //bool nopacket = true;
@@ -1097,7 +1100,9 @@
        }
        if ((ret == 1) && (*(buf->reference()) == 0xff)) {
            log_debug("Got an empty packet from the server at line %d", 
__LINE__);
-           continue;
+           ret = 0;
+           buf->clear();
+           continue;
        }
        // ret is "no position" when the socket is closed from the other end of 
the connection,
        // so we're done.
@@ -1115,7 +1120,6 @@
     return buf;
 }
 
-
 // Split a large buffer into multiple smaller ones of the default chunksize
 // of 128 bytes. We read network data in big chunks because it's more 
efficient,
 // but RTMP uses a weird scheme of a standard header, and then every chunksize
@@ -1124,14 +1128,14 @@
 boost::shared_ptr<RTMP::queues_t>
 RTMP::split(amf::Buffer &buf)
 {
-    GNASH_REPORT_FUNCTION;
+//     GNASH_REPORT_FUNCTION;
     return split(buf.reference(), buf.allocated());
 }
 
 boost::shared_ptr<RTMP::queues_t>
 RTMP::split(boost::uint8_t *data, size_t size)
 {
-    GNASH_REPORT_FUNCTION;
+//     GNASH_REPORT_FUNCTION;
 
     if (data == 0) {
        log_error("Buffer pointer is invalid.");
@@ -1157,9 +1161,7 @@
        // processed differently.
        // FIXME: skip system messages for now!
        if (rthead->channel == RTMP_SYSTEM_CHANNEL) {
-           log_debug("FIXME: %s: Got a message on the system channel!", 
__FUNCTION__);
-//         ptr += rthead->head_size + rthead->bodysize;
-//         continue;
+//         log_debug("FIXME: %s: Got a message on the system channel!", 
__FUNCTION__);
        }
        // Make sure the header size we just got is in range. We can
        // proceed as long as it is in range, but if it is out of
@@ -1171,7 +1173,7 @@
            if (rthead->head_size <= 4) {
                rthead->bodysize = _lastsize[rthead->channel];
            }
-           if ((rthead->head_size > 1)) {
+           if ((rthead->head_size > 1) || (ptr == data)) {
 //             cerr << "New packet for channel #" << rthead->channel << " of 
size "
 //                  << (rthead->head_size + rthead->bodysize) << endl;
                // give it some memory to store data in. We store
@@ -1240,7 +1242,7 @@
                // complete all the data up to the body size from the header.
 //             cerr << _queues[rthead->channel].size() << " messages in queue 
for channel "
 //                  << rthead->channel << endl;
-               if (rthead->head_size == 1){
+               if ((rthead->head_size == 1) && (ptr != data)) {
 //                 cerr << "FOLLOWING PACKET!" << " for channel " << 
rthead->channel << endl;
 //                 cerr << "Space Left in buffer for channel " << 
rthead->channel << " is: "
 //                      << chunk->spaceLeft() << endl;

=== modified file 'libnet/rtmp.h'
--- a/libnet/rtmp.h     2009-02-25 22:33:03 +0000
+++ b/libnet/rtmp.h     2009-04-01 22:53:00 +0000
@@ -31,6 +31,7 @@
 #include "buffer.h"
 #include "rtmp_msg.h"
 #include "cque.h"
+#include "dsodefs.h"
 
 namespace gnash
 {
@@ -235,8 +236,8 @@
     int getMysteryWord()        { return _mystery_word; };
 
     // Decode an RTMP message
-    RTMPMsg *decodeMsgBody(boost::uint8_t *data, size_t size);
-    RTMPMsg *decodeMsgBody(amf::Buffer &buf);
+    boost::shared_ptr<RTMPMsg> decodeMsgBody(boost::uint8_t *data, size_t 
size);
+    boost::shared_ptr<RTMPMsg> decodeMsgBody(amf::Buffer &buf);
     
     virtual boost::shared_ptr<rtmp_ping_t> decodePing(boost::uint8_t *data);
     boost::shared_ptr<rtmp_ping_t> decodePing(amf::Buffer &buf);
@@ -279,11 +280,17 @@
     // interval. (128 bytes for video data by default). Each message main
     // contain multiple packets.
     bool sendMsg(amf::Buffer &data);
-    bool sendMsg(int fd, int channel, rtmp_headersize_e head_size,
-             size_t total_size, content_types_e type,
-             RTMPMsg::rtmp_source_e routing, amf::Buffer &data);
-    bool sendMsg(int fd, int channel, rtmp_headersize_e head_size,
-             size_t total_size, content_types_e type,
+    bool sendMsg(int channel, rtmp_headersize_e head_size,
+             size_t total_size, content_types_e type,
+             RTMPMsg::rtmp_source_e routing, amf::Buffer &data);
+    bool sendMsg(int fd, int channel, rtmp_headersize_e head_size,
+             size_t total_size, content_types_e type,
+             RTMPMsg::rtmp_source_e routing, amf::Buffer &data);
+    bool sendMsg(int channel, rtmp_headersize_e head_size,
+                size_t total_size, content_types_e type,
+                RTMPMsg::rtmp_source_e routing, boost::uint8_t *data, size_t 
size);
+    bool sendMsg(int fd, int channel, rtmp_headersize_e head_size,
+                size_t total_size, content_types_e type,
                 RTMPMsg::rtmp_source_e routing, boost::uint8_t *data, size_t 
size);
     
 #if 0

=== modified file 'libnet/rtmp_client.cpp'
--- a/libnet/rtmp_client.cpp    2009-02-25 22:33:03 +0000
+++ b/libnet/rtmp_client.cpp    2009-04-02 15:04:09 +0000
@@ -51,13 +51,16 @@
 namespace gnash
 {
 
+extern const char *ping_str[];
+
 // The rcfile is loaded and parsed here:
 static RcInitFile& rcfile = RcInitFile::getDefaultInstance();
 
 extern map<int, Handler *> handlers;
 
 RTMPClient::RTMPClient()
-    : _connections(0)
+    : _connected(false),
+      _connections(0)
 {
 //    GNASH_REPORT_FUNCTION;
 }
@@ -65,6 +68,8 @@
 RTMPClient::~RTMPClient()
 {
 //    GNASH_REPORT_FUNCTION;
+    _connected = false;
+
     _properties.clear();
 //    delete _body;
 }
@@ -116,7 +121,7 @@
     swfUrlnode->makeString("swfUrl", swfUrl);
     obj->addProperty(swfUrlnode);
 
-//    filespec = "rtmp://localhost/oflaDemo";
+//    filespec = "rtmp://localhost:5935/oflaDemo";
     ElementSharedPtr tcUrlnode(new amf::Element);
     tcUrlnode->makeString("tcUrl", tcUrl);
     obj->addProperty(tcUrlnode);
@@ -145,10 +150,11 @@
     pageUrlnode->makeString("pageUrl", pageUrl);
     obj->addProperty(pageUrlnode);
 
+#if 0
     ElementSharedPtr objencodingnode(new Element);
     objencodingnode->makeNumber("objectEncoding", 0.0);
     obj->addProperty(objencodingnode);
-    
+#endif
 //    size_t total_size = 227;
 //     Buffer *out = encodeHeader(0x3, RTMP::HEADER_12, total_size,
 //                                      RTMP::INVOKE, RTMP::FROM_CLIENT);
@@ -166,6 +172,38 @@
     return buf;
 }
 
+boost::shared_ptr<amf::Buffer>
+RTMPClient::encodeEchoRequest(const std::string &method, double id, 
amf::Element &el)
+{
+//    GNASH_REPORT_FUNCTION;
+    boost::shared_ptr<amf::Element> str(new amf::Element);
+    str->makeString(method);
+    boost::shared_ptr<Buffer> strobj = str->encode();
+
+    // Encod ethe stream ID
+    boost::shared_ptr<amf::Element>  num(new amf::Element);
+    num->makeNumber(id);
+    boost::shared_ptr<Buffer> numobj = num->encode();
+
+    // Set the NULL object element that follows the stream ID
+    boost::shared_ptr<amf::Element> null(new amf::Element);
+    null->makeNull();
+    boost::shared_ptr<Buffer> nullobj = null->encode();
+
+    boost::shared_ptr<Buffer> elobj = el.encode();
+
+    size_t totalsize = strobj->size() + numobj->size() + nullobj->size() + 
elobj->size();
+
+    boost::shared_ptr<Buffer> buf(new Buffer(totalsize));
+    
+    *buf += strobj;
+    *buf += numobj;
+    *buf += nullobj;
+    *buf += elobj;
+
+    return buf;
+}
+
 // 43 00 1a 21 00 00 19 14 02 00 0c 63 72 65 61 74  C..!.......creat
 // 65 53 74 72 65 61 6d 00 40 08 00 00 00 00 00 00  address@hidden
 // 05                                                    .               
@@ -351,56 +389,217 @@
     }
 }
 
-// The client finished the handshake process by sending the second
+// The client finishes the handshake process by sending the second
 // data block we get from the server as the response
 bool
 RTMPClient::clientFinish()
 {
     GNASH_REPORT_FUNCTION;
+    amf::Buffer data;
+    return clientFinish(data);
+}
 
+bool
+RTMPClient::clientFinish(amf::Buffer &data)
+{
+    GNASH_REPORT_FUNCTION;
+    bool done = false;
     int ret = 0;
+    int offset = 0;
+
+    
+    // The total size of incoming bytes is twice the handshake size, plus the 
handshake
+    // header byte. Then we append the NetConnection::connect packet as well.
+    size_t maxsize = (RTMP_HANDSHAKE_SIZE*2)+1+data.size();
+    boost::shared_ptr<amf::Buffer> buf(new amf::Buffer(maxsize));
+    do {
+       ret = readNet(buf->reference() + offset, buf->size() - offset);
+       offset += ret;
+       buf->setSeekPointer(buf->reference() + offset);
+       if (offset == (RTMP_HANDSHAKE_SIZE*2)+1) {
+           done = true;
+       }
+       if (ret < 0) {
+           log_error (_("Couldn't read data block in handshake!"));
+           done = true;
+       }
+    } while (!done);    
+    
+    if (buf->allocated() > RTMP_HANDSHAKE_SIZE) {
+       log_debug (_("Read first data block in handshake"));
+    } else {
+       log_error (_("Couldn't read first data block in handshake"));
+    }
+    if (buf->allocated() > RTMP_HANDSHAKE_SIZE*2) {
+       log_debug (_("Read second data block in handshake"));
+    } else {
+       log_error (_("Couldn't read second data block in handshake"));
+       return false;
+    }
+
+#if 1
+    if (memcmp(buf->reference() + RTMP_HANDSHAKE_SIZE + 1, 
_handshake->reference(), RTMP_HANDSHAKE_SIZE) == 0) {
+       log_debug("Handshake matched");
+    } else {
+       log_debug("Handshake didn't match");
+//     return false;
+    }
+    *buf += data;
+#endif
+    
+    // For some reason, Red5 won't connect unless the connect packet is
+    // part of the final handshake packet. Sending the identical data with
+    // two writeNet()s won't connect. Go figure...
+    _handshake->resize(RTMP_HANDSHAKE_SIZE + data.size());
+    // FIXME: unless the handshake is all zeros, Gnash won't connect to
+    // Red5 for some reason. Cygnal isn't so picky.
     _handshake->clear();
+    _handshake->setSeekPointer(_handshake->reference() + RTMP_HANDSHAKE_SIZE);
+    // Add the NetConnection::connect() packet
+    _handshake->append(data.reference(), data.allocated());
+    ret = writeNet(_handshake->reference(), _handshake->allocated());
+    if ( ret <= 0 ) {
+       return false;
+    }
     
-    gnashSleep(1000000); // FIXME: why do we still need a delay here, when 
readNet() does a select ?
-    ret = readNet(_handshake->reference(), RTMP_HANDSHAKE_SIZE);
-    if (ret == RTMP_HANDSHAKE_SIZE) {
-        log_debug (_("Read first data block in handshake"));
-    } else {
-        log_error (_("Couldn't read first data block in handshake"));
-//        return false;
-    }
-    if (ret > RTMP_HANDSHAKE_SIZE) {
-       ret = readNet(_handshake->reference(), RTMP_HANDSHAKE_SIZE);
-       if (ret == RTMP_HANDSHAKE_SIZE) {        
-           log_debug (_("Read second data block in handshake"));
-       } else {
-           log_error (_("Couldn't read second data block in handshake"));
-//        return false;
-       }
-    }
-    ret = readNet(_handshake->reference(), RTMP_HANDSHAKE_SIZE);
-    if (ret == RTMP_HANDSHAKE_SIZE) {        
-        log_debug (_("Read second data block in handshake"));
-    } else {
-        log_error (_("Couldn't read second data block in handshake"));
-//        return false;
-    }
-    if (ret > RTMP_HANDSHAKE_SIZE) {
-       ret = readNet(_handshake->reference(), RTMP_HANDSHAKE_SIZE);
-       if (ret == RTMP_HANDSHAKE_SIZE) {        
-           log_debug (_("Read second data block in handshake"));
-       } else {
-           log_error (_("Couldn't read second data block in handshake"));
-//        return false;
-       }
-    }
-
-    ret = writeNet(_handshake->reference(), RTMP_HANDSHAKE_SIZE);
-    if ( ret <= 0 ) return false;
+    // Since the handshake completed sucessfully, we're connected.
+    _connected == true;
 
     return true;
 }
 
+// Get and process an RTMP response. After reading all the data, then we have
+// split it up on the chunksize boudaries, and into the respective queues
+// for each channel.
+RTMPClient::msgque_t
+RTMPClient::recvResponse()
+{
+    GNASH_REPORT_FUNCTION;
+
+    RTMPClient::msgque_t msgque;
+    
+    // Read the responses back from the server.  This is usually a series of 
system
+    // messages on channel 2, and the response message on channel 3 from our 
request.
+    boost::shared_ptr<amf::Buffer> response = recvMsg();
+    if (!response) {
+       log_error("Got no response from the RTMP server");
+    }
+
+    // when doing remoting calls I don't see this problem with an empty packet 
from Red5,
+    // but when I do streaming, it's always there, so we need to remove it.
+    boost::uint8_t *pktstart = response->reference();
+    if (*pktstart == 0xff) {
+       log_debug("Got empty packet in buffer.");
+       pktstart++;
+    }
+
+    // The response packet contains multiple messages for multiple channels, 
so we
+    // we have to split the Buffer into seperate messages on a chunksize 
boundary.
+    boost::shared_ptr<RTMP::rtmp_head_t> rthead;
+    boost::shared_ptr<RTMP::queues_t> que = split(pktstart, 
response->allocated()-1);
+
+    // If we got no responses, something obviously went wrong.
+    if (!que->size()) {
+        log_error("No response from INVOKE of NetConnection connect");
+       
+    }
+
+    // There is a queue of queues used to hold all the messages. The first 
queue
+    // is indexed by the channel number, the second queue is all the messages 
that
+    // have arrived for that channel.
+    while (que->size()) {      // see if there are any messages at all
+       log_debug("%s: There are %d channel queues in the RTMP input queue, %d 
messages in front queue",
+                 __PRETTY_FUNCTION__, que->size(), que->front()->size());
+       // Get the CQue for the first channel
+       CQue *channel_q = que->front();
+       que->pop_front();       // remove this Cque from the top level que
+
+       while (channel_q->size()) {
+           // Get the first message in the channel queue
+           boost::shared_ptr<amf::Buffer> ptr = channel_q->pop();
+           ptr->dump();
+           if (ptr) {          // If there is legit data
+               rthead = decodeHeader(ptr->reference());
+               if (!rthead) {
+                   log_error("Couldn't decode RTMP message header");
+                   continue;
+               }
+               switch (rthead->type) {
+                 case RTMP::NONE:
+                     log_error("RTMP packet can't be of none type!");
+                     break;
+                 case RTMP::CHUNK_SIZE:
+                     log_unimpl("Server message data packet");
+                     break;
+                 case RTMP::UNKNOWN:   
+                     log_unimpl("Unknown data packet");
+                     break;
+                 case RTMP::BYTES_READ:
+                     log_unimpl("Bytes Read data packet");
+                     break;
+                 case RTMP::PING:
+                 {
+                     boost::shared_ptr<RTMP::rtmp_ping_t> ping = 
decodePing(ptr->reference() + rthead->head_size);
+                     log_debug("Got a Ping type %s", ping_str[ping->type]);
+                     break;
+                 }
+                 case RTMP::SERVER:
+                     log_unimpl("Server message data packet");
+                     break;
+                 case RTMP::CLIENT:
+                     log_unimpl("Client message data packet");
+                     break;
+                 case RTMP::UNKNOWN2:
+                     log_unimpl("Unknown2 data packet");
+                     break;
+                 case RTMP::AUDIO_DATA:
+                 {
+                     boost::shared_ptr<RTMPMsg> msg = 
decodeMsgBody(ptr->reference() + rthead->head_size, rthead->bodysize);
+                     if (msg) {
+                         msgque.push_back(msg);
+                     }
+                     break;
+                 }
+                 case RTMP::VIDEO_DATA:
+                 {
+                     boost::shared_ptr<RTMPMsg> msg = 
decodeMsgBody(ptr->reference() + rthead->head_size, rthead->bodysize);
+                     if (msg) {
+                         msgque.push_back(msg);
+                     }
+                     break;
+                 }
+                 case RTMP::UNKNOWN3:
+                     log_unimpl("Unknown3 data packet message");
+                     break;
+                 case RTMP::NOTIFY:
+                     log_unimpl("Notify data packet message");
+                     break;
+                 case RTMP::SHARED_OBJ:
+                     log_unimpl("Shared Object data packet message");
+                     break;
+                 case RTMP::INVOKE:
+                 {
+                     boost::shared_ptr<RTMPMsg> msg = 
decodeMsgBody(ptr->reference() + rthead->head_size, rthead->bodysize);
+                     if (msg) {
+                         msgque.push_back(msg);
+                     }
+                     break;
+                 }
+                 case RTMP::FLV_DATA:
+                     log_unimpl("Flv data packet message");
+                     break;
+                 default :
+                     log_error("Couldn't decode RTMP message Body");
+                     break;
+               }
+           }
+       }
+    }
+    
+    return msgque;
+}
+
+
 // bool
 // RTMPClient::packetRequest()
 // {

=== modified file 'libnet/rtmp_client.h'
--- a/libnet/rtmp_client.h      2009-02-25 22:33:03 +0000
+++ b/libnet/rtmp_client.h      2009-04-02 15:04:09 +0000
@@ -16,7 +16,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 #ifndef _RTMP_CLIENT_H_
-#define _RTMP_CLIENT_H_ 1
+#define _RTMP_CLIENT_H_
 
 #include <boost/cstdint.hpp>
 #include <boost/shared_ptr.hpp>
@@ -25,40 +25,55 @@
 #include <time.h>
 
 #include "rtmp.h"
+#include "rtmp_msg.h"
 #include "amf.h"
 #include "element.h"
 #include "handler.h"
 #include "network.h"
 #include "buffer.h"
+#include "dsodefs.h"
 
 namespace gnash
 {
 
-class DSOEXPORT RTMPClient : public RTMP
+class RTMPClient : public RTMP
 {
 public:
-    RTMPClient();
-    ~RTMPClient();
+    DSOEXPORT RTMPClient();
+    DSOEXPORT ~RTMPClient();
 
     bool handShakeWait();
 //    bool handShakeResponse();
     bool clientFinish();
-    bool handShakeRequest();
+    DSOEXPORT bool clientFinish(amf::Buffer &data);
+    DSOEXPORT bool handShakeRequest();
     
     // These are used for creating the primary objects
     // Create the initial object sent to the server, which is 
NetConnection::connect()
-    boost::shared_ptr<amf::Buffer> encodeConnect(const char *app, const char 
*swfUrl, const char *tcUrl,
+    DSOEXPORT boost::shared_ptr<amf::Buffer> encodeConnect(const char *app, 
const char *swfUrl, const char *tcUrl,
                                    double audioCodecs, double videoCodecs, 
double videoFunction,
                                    const char *pageUrl);
     // Create the second object sent to the server, which is 
NetStream():;NetStream()
-    boost::shared_ptr<amf::Buffer> encodeStream(double id);
+    DSOEXPORT boost::shared_ptr<amf::Buffer> encodeStream(double id);
     boost::shared_ptr<amf::Buffer> encodeStreamOp(double id, rtmp_op_e op, 
bool flag);
     boost::shared_ptr<amf::Buffer> encodeStreamOp(double id, rtmp_op_e op, 
bool flag, double pos);
-    boost::shared_ptr<amf::Buffer> encodeStreamOp(double id, rtmp_op_e op, 
bool flag, const std::string &name);
+    DSOEXPORT boost::shared_ptr<amf::Buffer> encodeStreamOp(double id, 
rtmp_op_e op, bool flag, const std::string &name);
     boost::shared_ptr<amf::Buffer> encodeStreamOp(double id, rtmp_op_e op, 
bool flag, const std::string &name, double pos);
 
+    bool isConnected() { return _connected; };
+
+    std::string &getPath() { return _path; };
+    void setPath(std::string &x) { _path = x; };
+
+    DSOEXPORT boost::shared_ptr<amf::Buffer> encodeEchoRequest(const 
std::string &method, double id, amf::Element &el);
+
+    typedef std::deque<boost::shared_ptr<RTMPMsg> > msgque_t;
+    msgque_t recvResponse();
+
     void dump();
   private:
+    std::string _path;
+    bool   _connected;
     double _connections;
 };
 

=== modified file 'libnet/rtmp_msg.cpp'
--- a/libnet/rtmp_msg.cpp       2009-02-25 22:33:03 +0000
+++ b/libnet/rtmp_msg.cpp       2009-03-28 18:36:39 +0000
@@ -140,6 +140,10 @@
                                _status = RTMPMsg::NS_PLAY_FAILED;
                                return _status;
                            }
+                           if (value == "NetStream.InvalidArg") {
+                               _status = RTMPMsg::NS_INVALID_ARGUMENT;
+                               return _status;
+                           }
                            if (value == 
"NetStream.Play.File.Structure.Invalid") {
                                _status = 
RTMPMsg::NS_PLAY_FILE_STRUCTURE_INVALID;
                                return _status;

=== modified file 'libnet/rtmp_msg.h'
--- a/libnet/rtmp_msg.h 2009-02-25 22:33:03 +0000
+++ b/libnet/rtmp_msg.h 2009-03-27 00:38:36 +0000
@@ -32,7 +32,7 @@
 namespace gnash
 {
 
-class DSOEXPORT RTMPMsg
+class RTMPMsg
 {
 public:
     typedef enum {
@@ -86,8 +86,8 @@
        NS_DELETE_STREAM
     } rtmp_status_e;
     typedef enum {
-       FROM_SERVER,                      // Flash com server
-       FROM_CLIENT                       // SWF player
+       FROM_CLIENT,                      // SWF player
+       FROM_SERVER                      // Flash com server
     } rtmp_source_e;
     RTMPMsg();
     ~RTMPMsg();
@@ -118,12 +118,12 @@
     ///                search for.
     ///
     /// @return A smart pointer to the Element for this property.
-    boost::shared_ptr<amf::Element> findProperty(const std::string &name);
+    DSOEXPORT boost::shared_ptr<amf::Element> findProperty(const std::string 
&name);
 
 //    void setHeaderData(RTMP::rtmp_head_t &qhead);
                        
 // Dump internal status to the terminal
-    void dump();
+    DSOEXPORT void dump();
     
   protected:
     rtmp_source_e        _routing;

=== modified file 'testsuite/Makefile.am'
--- a/testsuite/Makefile.am     2009-04-30 16:01:16 +0000
+++ b/testsuite/Makefile.am     2009-06-07 21:14:22 +0000
@@ -17,8 +17,14 @@
 
 AUTOMAKE_OPTIONS = 
 
+DIR_MING=
+
 if ENABLE_MING
-DIR_MING = misc-ming.all actionscript.all
+DIR_MING += misc-ming.all actionscript.all
+endif
+
+if HAS_NETCAT
+DIR_MING += network.all
 endif
 
 if ENABLE_MTASC
@@ -49,10 +55,11 @@
        media \
        as3 \
        actionscript.all \
-       libbase \
+       libbase.all     \
        libamf.all \
        libnet.all \
        libcore.all \
+       network.all \
        samples \
        swfdec \
        misc-ming.all \
@@ -69,7 +76,8 @@
        $(DIR_AS3) \
        $(DIR_SWFDEC_TESTSUITE) \
        libnet.all \
-       libbase \
+       libbase.all     \
+       network.all \
        libamf.all \
        libcore.all \
        samples \

=== modified file 'testsuite/libamf.all/test_amfmsg.cpp'
--- a/testsuite/libamf.all/test_amfmsg.cpp      2009-03-03 23:39:05 +0000
+++ b/testsuite/libamf.all/test_amfmsg.cpp      2009-03-25 22:35:16 +0000
@@ -136,22 +136,22 @@
 void
 test_encoding()
 {
-//     00 06 67 65 74 77 61 79                <- getway, message #1
+//  00 06 67 65 74 77 61 79                <- getway, message #1
 //  00 04 2f 32 32 39                      <- /229, operation name
-//  00 00 00 0e                                <- byte length of message
-//     0a 00 00 00 01                  <- array, 1 item
+//  00 00 00 0e                                   <- byte length of message
+//     0a 00 00 00 01                     <- array, 1 item
 //        00 41 70 43 87 20 00 00 00
 //
 //  00 06 67 65 74 77 61 79                <- getway, message #2
 //  00 04 2f 32 33 30                      <- /230, operation name
-//  00 00 00 0e                                <- byte length of message
-//     0a 00 00 00 01                  <- array, 1 item
+//  00 00 00 0e                                   <- byte length of message
+//     0a 00 00 00 01                     <- array, 1 item
 //        00 41 70 43 ba 00 00 00 00
 //
 //  00 06 67 65 74 77 61 79                <- getway, message #3
 //  00 04 2f 32 33 31                      <- /231, operation name
-//  00 00 00 0e                                <- byte length of message
-//     0a 00 00 00 01                  <- array, 1 item
+//  00 00 00 0e                                   <- byte length of message
+//     0a 00 00 00 01                     <- array, 1 item
 //        00 41 70 43 ac e0 00 00 00
     boost::shared_ptr<Buffer> buf1(new Buffer("00 00 00 00 00 03 00 06 67 65 
74 77 61 79 00 04 2f 32 32 39 00 00 00 0e 0a 00 00 00 01 00 41 70 43 87 20 00 
00 00 00 06 67 65 74 77 61 79 00 04 2f 32 33 30 00 00 00 0e 0a 00 00 00 01 00 
41 70 43 ba 00 00 00 00 00 06 67 65 74 77 61 79 00 04 2f 32 33 31 00 00 00 0e 
0a 00 00 00 01 00 41 70 43 ac e0 00 00 00"));
     double num = *(reinterpret_cast<double *>(buf1->reference()));

=== renamed directory 'testsuite/libbase' => 'testsuite/libbase.all'
=== modified file 'testsuite/libcore.all/AsValueTest.cpp'
--- a/testsuite/libcore.all/AsValueTest.cpp     2009-06-03 16:36:59 +0000
+++ b/testsuite/libcore.all/AsValueTest.cpp     2009-06-07 21:14:22 +0000
@@ -303,7 +303,7 @@
         }
     }
 
-    std::auto_ptr<Element> el1 = as1.to_element();
+    boost::shared_ptr<Element> el1 = as1.to_element();
     boost::shared_ptr<amf::Element> fooel = el1->getProperty(0);
     boost::shared_ptr<amf::Element> barel = el1->getProperty(1);
     if ((el1.get()->getType() == Element::OBJECT_AMF0)

=== modified file 'testsuite/libnet.all/test_http.cpp'
--- a/testsuite/libnet.all/test_http.cpp        2009-03-17 12:32:36 +0000
+++ b/testsuite/libnet.all/test_http.cpp        2009-04-05 22:01:27 +0000
@@ -94,7 +94,7 @@
 
     tests();
     test_post();
-    test_rtmpt();
+//    test_rtmpt();
 }
 
 
@@ -315,9 +315,12 @@
     }
     regfree(&regex_pat);
 
+#if 0
+    // FIXME: should be moved to server side only test case
     // Check the Server field
     http.clearHeader();
-    http.formatErrorResponse(HTTP::NOT_FOUND);
+    HTTPServer https;
+    https.formatErrorResponse(HTTP::NOT_FOUND);
 //    cerr << "FIXME: " << http.getHeader() << endl;
 //    cerr << "FIXME: " << http.getBody() << endl;
     regcomp (&regex_pat, 
"Date:.*Server:.*Content-Length:.*Connection:.*Content-Type:.*$",
@@ -328,7 +331,8 @@
         runtest.pass ("HTTP::formatErrorResponse(header)");
     }
     regfree(&regex_pat);
-
+#endif
+    
 # if 0
     regfree(&regex_pat);
     regcomp (&regex_pat, "DOCTYPE.*<title>404 Not Found</title>.*$",
@@ -371,6 +375,10 @@
 
 // User Agent: Lynx/2.8.6rel.2 libwww-FM/2.14 SSL-MM/1.4.1 OpenSSL/0.9.8b
 
+    
+#if 0
+    // FIXME: should be moved to server side only test case
+    // Check the Server field
     Buffer field1;
     field1 = "GET /index.html HTTP/1.1";
     //    boost::uint8_t *field1 = (boost::uint8_t *)"GET /index.html 
HTTP/1.1";
@@ -407,7 +415,8 @@
     } else {
         runtest.fail ("HTTP::extractCommand(params)");
     }
-
+#endif
+    
 #if 0
     boost::uint8_t *field3 = (boost::uint8_t *) "Keep-Alive: 300";
     HTTP http3;
@@ -588,6 +597,9 @@
     ptr1 += *encstr;
     ptr1.resize();              // shrink the buffer to be the exact size of 
the data
 
+#if 1
+    // FIXME: should be moved to server side only test case
+    // Check the Server field
     AMF amf;
     boost::uint8_t *data1 = http.processHeaderFields(ptr1);
     boost::shared_ptr<amf::Element> el1 = amf.extractAMF(data1, data1 + 15);
@@ -650,6 +662,7 @@
         }
     }
 
+#if 0
     // Make sure we can parse the Red5 echo_test client messages.
     boost::shared_ptr<Buffer> hex1(new Buffer("00 00 00 00 00 01 00 04 65 63 
68 6f 00 02 2f 32 00 00 00 14 0a 00 00 00 01 02 00 0c 48 65 6c 6c 6f 20 77 6f 
72 6c 64 21"));
     boost::shared_ptr<Buffer> hex2(new Buffer("00 00 00 00 00 01 00 0b 2f 32 
2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 02 00 0c 48 65 6c 6c 
6f 20 77 6f 72 6c 64 21"));
@@ -674,17 +687,20 @@
     } else {
         runtest.fail("HTTP::formatEchoResponse()");
     }
+#endif
+#endif
     
     if (dbglogfile.getVerbosity() > 0) {
         http.dump();
     }
 }
 
+#if 0
 void
 test_rtmpt (void)
 {
     HTTP http;
-    
+
     // Boolean True request
     boost::shared_ptr<Buffer> hex_req1(new Buffer("00 00 00 00 00 01 00 04 65 
63 68 6f 00 02 2f 31 00 00 00 07 0a 00 00 00 01 01 01"));
     vector<boost::shared_ptr<amf::Element> > headers1 = 
http.parseEchoRequest(*hex_req1);
@@ -1949,6 +1965,7 @@
     }
 #endif
 }
+#endif
 
 static void
 usage (void)

=== modified file 'testsuite/libnet.all/test_rtmp.cpp'
--- a/testsuite/libnet.all/test_rtmp.cpp        2009-02-25 22:33:03 +0000
+++ b/testsuite/libnet.all/test_rtmp.cpp        2009-04-05 21:08:16 +0000
@@ -603,7 +603,7 @@
 //   63 74 2e 53 75 63 63 65    73 73 00 00 c3 09          ct.Success....
     boost::shared_ptr<amf::Buffer> hex2(new Buffer("02 00 07 5f 72 65 73 75 6c 
74 00 3f f0 00 00 00 00 00 00 05 03 00 0b 61 70 70 6c 69 63 61 74 69 6f 6e 05 
00 05 6c 65 76 65 6c 02 00 06 73 74 61 74 75 73 00 0b 64 65 73 63 72 69 70 74 
69 6f 6e 02 00 15 43 6f 6e 6e 65 63 74 69 6f 6e 20 73 75 63 63 65 65 64 65 64 
2e 00 04 63 6f 64 65 02 00 1d 4e 65 74 43 6f 6e 6e 65 63 74 69 6f 6e 2e 43 6f 
6e 6e 65 63 74 2e 53 75 63 63 65 73 73 00 00 09"));
 
-    RTMPMsg *msg1 = rtmp.decodeMsgBody(*hex2);
+    boost::shared_ptr<RTMPMsg> msg1 = rtmp.decodeMsgBody(*hex2);
     if (msg1) {
         std::vector<boost::shared_ptr<amf::Element> > hell = 
msg1->getElements();
         std::vector<boost::shared_ptr<amf::Element> > props = 
hell[0]->getProperties();        
@@ -620,7 +620,6 @@
     } else {
         runtest.untested("Decoded RTMP Result(NC_CONNECT_SUCCESS) message");
     }
-    delete msg1;
 
 #if 0
     RTMPServer rtmpserv;
@@ -635,7 +634,7 @@
 #endif
     
     boost::shared_ptr<amf::Buffer> hex3(new Buffer("02 00 07 5f 72 65 73 75 6c 
74 00 3f f0 00 00 00 00 00 00 05 03 00 0b 61 70 70 6c 69 63 61 74 69 6f 6e 05 
00 05 6c 65 76 65 6c 02 00 05 65 72 72 6f 72 00 0b 64 65 73 63 72 69 70 74 69 
6f 6e 02 00 00 00 04 63 6f 64 65 02 00 1c 4e 65 74 43 6f 6e 6e 65 63 74 69 6f 
6e 2e 43 6f 6e 6e 65 63 74 2e 46 61 69 6c 65 64 00 00 09"));
-    RTMPMsg *msg2 = rtmp.decodeMsgBody(*hex3);
+    boost::shared_ptr<RTMPMsg> msg2 = rtmp.decodeMsgBody(*hex3);
     std::vector<boost::shared_ptr<amf::Element> > hell = msg2->getElements();
     std::vector<boost::shared_ptr<amf::Element> > props = 
hell[0]->getProperties();        
 //     printf("FIXME: %d, %d, %s:%s\n", props.size(), msg1->getStatus(),
@@ -653,8 +652,6 @@
         runtest.untested("Decoded RTMP result(NC_CONNECT_FAILED(as result)");
     }
 
-    delete msg2;
-    
 //     Buffer hex4 = "43 00 00 00 00 00 48 14 02 00 06 5f 65 72 72 6f 72 00 40 
00 00 00 00 00 00 00 05 03 00 04 63 6f 64 65 02 00 19 4e 65 74 43 6f 6e 6e 65 
63 74 69 6f 6e 2e 43 61 6c 6c 2e 46 61 69 6c 65 64 00 05 6c 65 76 65 6c 02 00 
05 65 72 72 6f 72 00 00 09";
 //     if ((memcmp(hex4->reference(), buf4->reference(), hex4->size()) == 0)) {
 //         runtest.pass("Encoded RTMP result(NC_CONNECT_FAILED(as result)");
@@ -675,7 +672,7 @@
 //     clientid
 //         dsLgYohb
     boost::shared_ptr<amf::Buffer> hex4(new Buffer("02 00 08 6f 6e 53 74 61 74 
75 73 00 00 00 00 00 00 00 00 00 05 03 00 05 6c 65 76 65 6c 02 00 06 73 74 61 
74 75 73 00 04 63 6f 64 65 02 00 14 4e 65 74 53 74 72 65 61 6d 2e 50 6c 61 79 
2e 52 65 73 65 74 00 0b 64 65 73 63 72 69 70 74 69 6f 6e 02 00 2a 50 6c 61 79 
69 6e 67 20 61 6e 64 20 72 65 73 65 74 74 69 6e 67 20 50 44 5f 45 6e 67 6c 69 
73 68 5f 4c 6f 77 40 32 30 30 31 2e 00 07 64 65 74 61 69 6c 73 02 00 13 50 44 
5f 45 6e 67 6c 69 73 68 5f 4c 6f 77 40 32 30 30 31 00 08 63 6c 69 65 6e 74 69 
64 02 00 08 64 73 4c 67 59 6f 68 62 00 00 09"));
-    RTMPMsg *msg4 = rtmp.decodeMsgBody(*hex4);
+    boost::shared_ptr<RTMPMsg> msg4 = rtmp.decodeMsgBody(*hex4);
 //    std::vector<amf::Element *> hell4 = msg4->getElements();
     if ((msg4->getStatus() ==  RTMPMsg::NS_PLAY_RESET)
         && (msg4->getMethodName() == "onStatus")
@@ -685,14 +682,13 @@
     } else {
         runtest.fail("Encoded/Decoded RTMP onStatus(Play Reset)");
     }
-    delete msg4;
     
 // onStatus
 // code
 //     NetStream
 // Data.Start
     boost::shared_ptr<amf::Buffer> hex5(new Buffer("02 00 08 6f 6e 53 74 61 74 
75 73 03 00 04 63 6f 64 65 02 00 14 4e 65 74 53 74 72 65 61 6d 2e 44 61 74 61 
2e 53 74 61 72 74 00 00 09"));
-    RTMPMsg *msg5 = rtmp.decodeMsgBody(*hex5);
+    boost::shared_ptr<RTMPMsg> msg5 = rtmp.decodeMsgBody(*hex5);
     if ((msg5->getStatus() ==  RTMPMsg::NS_DATA_START)
         && (msg5->getMethodName() == "onStatus")
         && (msg5->getStreamID() == -1)
@@ -701,7 +697,6 @@
     } else {
         runtest.fail("Encoded/Decoded RTMP onStatus(Data Start)");
     }
-    delete msg5;
 
 // onStatus
 //     level
@@ -713,7 +708,7 @@
 //     details
 //         address@hidden
     boost::shared_ptr<amf::Buffer> hex6(new Buffer("02 00 08 6f 6e 53 74 61 74 
75 73 00 00 00 00 00 00 00 00 00 05 03 00 05 6c 65 76 65 6c 02 00 06 73 74 61 
74 75 73 00 04 63 6f 64 65 02 00 14 4e 65 74 53 74 72 65 61 6d 2e 50 6c 61 79 
2e 53 74 61 72 74 00 0b 64 65 73 63 72 69 70 74 69 6f 6e 02 00 24 53 74 61 72 
74 65 64 20 70 6c 61 79 69 6e 67 20 50 44 5f 45 6e 67 6c 69 73 68 5f 4c 6f 77 
40 32 30 30 31 2e 00 07 64 65 74 61 69 6c 73 02 00 13 50 44 5f 45 6e 67 6c 69 
73 68 5f 4c 6f 77 40 32 30 30 31 00 08 63 6c 69 65 6e 74 69 64 02 00 08 64 73 
4c 67 59 6f 68 62 00 00 09"));
-    RTMPMsg *msg6 = rtmp.decodeMsgBody(*hex6);
+    boost::shared_ptr<RTMPMsg> msg6 = rtmp.decodeMsgBody(*hex6);
     if ((msg6->getStatus() ==  RTMPMsg::NS_PLAY_START)
         && (msg6->getMethodName() == "onStatus")
         && (msg6->getStreamID() == 0)
@@ -722,11 +717,10 @@
     } else {
         runtest.fail("Encoded/Decoded RTMP onStatus(Play Start)");
     }
-    delete msg6;
 
 // ..............._error.?......... 
..level...error..code...NetConnection.Connect.Rejected..description..A[ 
Server.Reject ] : Virtual host _defa.ultVHost_ is not available....
     boost::shared_ptr<amf::Buffer> hex7(new Buffer("02 00 06 5f 65 72 72 6f 72 
00 3f f0 00 00 00 00 00 00 05 03 00 05 6c 65 76 65 6c 02 00 05 65 72 72 6f 72 
00 04 63 6f 64 65 02 00 1e 4e 65 74 43 6f 6e 6e 65 63 74 69 6f 6e 2e 43 6f 6e 
6e 65 63 74 2e 52 65 6a 65 63 74 65 64 00 0b 64 65 73 63 72 69 70 74 69 6f 6e 
02 00 41 5b 20 53 65 72 76 65 72 2e 52 65 6a 65 63 74 20 5d 20 3a 20 56 69 72 
74 75 61 6c 20 68 6f 73 74 20 5f 64 65 66 61 c3 75 6c 74 56 48 6f 73 74 5f 20 
69 73 20 6e 6f 74 20 61 76 61 69 6c 61 62 6c 65 2e 00 00 09"));
-    RTMPMsg *msg7 = rtmp.decodeMsgBody(*hex7);
+    boost::shared_ptr<RTMPMsg> msg7 = rtmp.decodeMsgBody(*hex7);
     if ((msg7->getStatus() ==  RTMPMsg::NC_CONNECT_REJECTED)
         && (msg7->getMethodName() == "_error")
         && (msg7->size() >= 1)) {
@@ -734,11 +728,10 @@
     } else {
         runtest.fail("Decoded RTMP _error(NC_CONNECT_REJECTED)");
     }
-    delete msg7;
 
 
//.onStatus.............level...error..code...NetStream.Play.StreamNotFound..description..6Failed
 to play gate06_tablan_bcueu_; .stream not 
found...details...gate06_tablan_bcueu_..clientid.A.;..
     boost::shared_ptr<amf::Buffer> hex8(new Buffer("02 00 08 6f 6e 53 74 61 74 
75 73 00 00 00 00 00 00 00 00 00 05 03 00 05 6c 65 76 65 6c 02 00 05 65 72 72 
6f 72 00 04 63 6f 64 65 02 00 1d 4e 65 74 53 74 72 65 61 6d 2e 50 6c 61 79 2e 
53 74 72 65 61 6d 4e 6f 74 46 6f 75 6e 64 00 0b 64 65 73 63 72 69 70 74 69 6f 
6e 02 00 36 46 61 69 6c 65 64 20 74 6f 20 70 6c 61 79 20 67 61 74 65 30 36 5f 
74 61 62 6c 61 6e 5f 62 63 75 65 75 5f 3b 20 c4 73 74 72 65 61 6d 20 6e 6f 74 
20 66 6f 75 6e 64 2e 00 07 64 65 74 61 69 6c 73 02 00 14 67 61 74 65 30 36 5f 
74 61 62 6c 61 6e 5f 62 63 75 65 75 5f 00 08 63 6c 69 65 6e 74 69 64 00 41 d8 
3b b4 e4 00 00 00 00 00 09"));
-    RTMPMsg *msg8 = rtmp.decodeMsgBody(*hex8);
+    boost::shared_ptr<RTMPMsg> msg8 = rtmp.decodeMsgBody(*hex8);
 //    msg4->dump();
 //    std::vector<amf::Element *> hell4 = msg4->getElements();
     if ((msg8->getStatus() ==  RTMPMsg::NS_PLAY_STREAMNOTFOUND)
@@ -748,12 +741,11 @@
     } else {
         runtest.fail("Encoded/Decoded RTMP onStatus(Play Stream Not Found)");
     }
-    delete msg8;
 
 
 
//.....onStatus.............level...status..code...NetStream.Play.Stop..description..%Stopped
 playing 
gate06_tablan_bcueu_...details....gate06_tablan_bcueu_..clientid.A.;.......reason......
     
     boost::shared_ptr<amf::Buffer> hex9(new Buffer("02 00 08 6f 6e 53 74 61 74 
75 73 00 00 00 00 00 00 00 00 00 05 03 00 05 6c 65 76 65 6c 02 00 06 73 74 61 
74 75 73 00 04 63 6f 64 65 02 00 13 4e 65 74 53 74 72 65 61 6d 2e 50 6c 61 79 
2e 53 74 6f 70 00 0b 64 65 73 63 72 69 70 74 69 6f 6e 02 00 25 53 74 6f 70 70 
65 64 20 70 6c 61 79 69 6e 67 20 67 61 74 65 30 36 5f 74 61 62 6c 61 6e 5f 62 
63 75 65 75 5f 2e 00 07 64 65 74 61 69 6c 73 c4 02 00 14 67 61 74 65 30 36 5f 
74 61 62 6c 61 6e 5f 62 63 75 65 75 5f 00 08 63 6c 69 65 6e 74 69 64 00 41 d8 
3b b4 e4 00 00 00 00 06 72 65 61 73 6f 6e 02 00 00 00 00 09"));
-    RTMPMsg *msg9 = rtmp.decodeMsgBody(*hex9);
+    boost::shared_ptr<RTMPMsg> msg9 = rtmp.decodeMsgBody(*hex9);
 //    msg4->dump();
 //    std::vector<amf::Element *> hell4 = msg4->getElements();
     if ((msg9->getStatus() ==  RTMPMsg::NS_PLAY_STOP)
@@ -763,7 +755,6 @@
     } else {
         runtest.fail("Encoded/Decoded RTMP onStatus(Play Stream Stop)");
     }
-    delete msg9;
 }
 
 void

=== modified file 'testsuite/misc-ming.all/Makefile.am'
--- a/testsuite/misc-ming.all/Makefile.am       2009-04-07 09:19:54 +0000
+++ b/testsuite/misc-ming.all/Makefile.am       2009-06-07 21:14:22 +0000
@@ -34,7 +34,6 @@
        PrototypeEventListeners.as \
        DragDropTest.as \
        remoting.as \
-       red5test.as \
        remoting.php \
        gotoFrame2Test.as \
        DrawingApiTest.as \
@@ -316,10 +315,9 @@
 if ENABLE_HTTP_TESTSUITE
 check_SCRIPTS += remotingTestRunner
 endif
-if ENABLE_RED5_TESTING
-check_SCRIPTS += red5testRunner
-endif
-endif
+endif
+
+# check_SCRIPTS += netstreamTestRunner
 
 if MING_VERSION_0_4
 check_SCRIPTS += \
@@ -463,7 +461,7 @@
 new_child_in_unload_testrunner: $(srcdir)/../generic-testrunner.sh 
new_child_in_unload_test.swf
        sh $< $(top_builddir) new_child_in_unload_test.swf > $@
        chmod 755 $@
-               
+
 PlaceObject2Test_SOURCES =     \
        PlaceObject2Test.c      \
        $(NULL)
@@ -704,7 +702,7 @@
 loop_test10runner: $(srcdir)/../generic-testrunner.sh loop_test10.swf Makefile
        sh $<  -f10 -c "#total tests" $(top_builddir) loop_test10.swf > $@
        chmod 755 $@
-               
+
 shape_test_SOURCES = shape_test.c
 shape_test_LDADD = libgnashmingutils.la
 
@@ -735,7 +733,7 @@
        morph_test1.swf \
        $(top_builddir)/testsuite/libtestsuite.la \
        $(NULL)
-       
+
 key_event_test_SOURCES = key_event_test.c
 key_event_test_LDADD = libgnashmingutils.la
 
@@ -756,7 +754,7 @@
        key_event_test.swf \
        $(top_builddir)/testsuite/libtestsuite.la \
        $(NULL)
-       
+
 place_object_test_SOURCES = place_object_test.c        
 place_object_test_LDADD = libgnashmingutils.la
 
@@ -767,7 +765,7 @@
        sh $< -r5 $(top_builddir) place_object_test.swf > $@
        chmod 755 $@
 
-       
+
 place_object_test2_SOURCES = place_object_test2.c      
 place_object_test2_LDADD = libgnashmingutils.la
 
@@ -968,7 +966,7 @@
        sh $< -r5 $(top_builddir) DepthLimitsTest.swf > $@
        chmod 755 $@
 
-       
+
 replace_shapes1test_SOURCES = replace_shapes1test.c    
 replace_shapes1test_LDADD = libgnashmingutils.la
 
@@ -1172,7 +1170,7 @@
 event_handler_scope_testrunner: $(srcdir)/../generic-testrunner.sh 
event_handler_scope_test.swf
        sh $< -r5 $(top_builddir) event_handler_scope_test.swf > $@
        chmod 755 $@
-               
+
 attachMovieTest_SOURCES =      \
        attachMovieTest.c       \
        $(NULL)
@@ -1766,14 +1764,6 @@
        sh $< $(top_builddir) remoting.swf > $@
        chmod 755 $@
 
-red5test.swf: $(srcdir)/red5test.as Dejagnu.swf Makefile 
../actionscript.all/check.as ../actionscript.all/utils.as
-       $(MAKESWF) -n network -r12 -o $@ -v7 -DRED5_HOST='\"$(RED5_HOST)\"' 
-DUSE_DEJAGNU_MODULE -DOUTPUT_VERSION=7 Dejagnu.swf $(srcdir)/red5test.as 
$(srcdir)/../actionscript.all/dejagnu_so_fini.as
-
-red5testRunner: $(srcdir)/../generic-testrunner.sh red5test.swf
-       sh $< $(top_builddir) red5test.swf > $@
-       chmod 755 $@
-       
-
 DragDropTest.swf: $(srcdir)/DragDropTest.as Dejagnu.swf DragDropTestLoaded.swf 
Makefile ../actionscript.all/check.as ../actionscript.all/utils.as
        $(MAKESWF) -r12 -o $@ -v6 -DUSE_DEJAGNU_MODULE -DOUTPUT_VERSION=6 
Dejagnu.swf $(srcdir)/DragDropTest.as
 
@@ -2037,9 +2027,6 @@
 if ENABLE_HTTP_TESTSUITE
 TEST_CASES += remotingTestRunner
 endif
-if ENABLE_RED5_TESTING
-TEST_CASES += red5testRunner
-endif
 endif
 
 if MING_SUPPORTS_INIT_ACTIONS

=== modified file 'testsuite/misc-ming.all/red5test.as'
--- a/testsuite/misc-ming.all/red5test.as       2008-12-20 02:03:30 +0000
+++ b/testsuite/misc-ming.all/red5test.as       2009-03-31 21:36:56 +0000
@@ -21,18 +21,32 @@
 
 #include "../actionscript.all/check.as"
 #include "../actionscript.all/utils.as"
+#include "../actionscript.all/dejagnu.as"
 
 stop();
 
 endOfTest = function()
 {
        //note("END OF TEST");
-       check_totals(9);
-       play();
+//        check_totals(9);
+    totals();
+    play();
 };
 
-if ( ! _root.hasOwnProperty('host') ) {
-    host=RED5_HOST;
+// -P FlashVars='hostname=localhost,rtmptport5080=rtmpport=1935'
+if (hostname == undefined) {
+    hostname="localhost";
+    note("No hostname specified, defaulting to "+hostname);
+}
+
+if (rtmptport == undefined) {
+    rtmptport = 5080;
+    note("No RTMPT port specified, defaulting to "+rtmptport);
+}
+
+if (rtmpport == undefined) {
+    rtmpport = 1935;
+    note("No RTMP port specified, defaulting to "+rtmpport);
 }
 
 nc = new NetConnection;
@@ -40,58 +54,958 @@
 nc.onStatus = function()
 {
     this.statuses.push(arguments);
-       note('NetConnection.onStatus called with args: '+dumpObject(arguments));
+    note('NetConnection.onStatus called with args: ');
+};
+
+nc.onResult = function()
+{
+    this.statuses.push(arguments);
+    note('NetConnection.onResult called with args: '+dumpObject(arguments));
 };
 
 function ResultHandler() {
     this.onResult = function(result) {
         note('default onResult called with args: '+dumpObject(arguments));
     };
-    this.onCustom = function(result) {
-        note('default onCustom called with args: '+dumpObject(arguments));
-    };
-    this.onDebugEvents = function(result) {
-        note('default onDebugEvents called with args: '+dumpObject(arguments));
-    };
-    this.onStatus = function(result) {
-       note("default onStatus called with args: "+dumpObject(arguments));
-    };
+//     this.onCustom = function(result) {
+//         note('default onCustom called with args: '+dumpObject(arguments));
+//     };
+//     this.onDebugEvents = function(result) {
+//         note('default onDebugEvents called with args: 
'+dumpObject(arguments));
+//     };
+//     this.onStatus = function(result) {
+//     note("default onStatus called with args: "+dumpObject(arguments));
+//     };
 };
 
-// nc.onStatus: level:error, code:NetConnection.Connect.InvalidApp
-// nc.onStatus: level:status, code:NetConnection.Connect.Closed
-//nc.connect("rtmp://localhost/");
-
-// nc.onStatus: level:status, code:NetConnection.Connect.Success
-rtmpuri = "rtmp://"+host+"/echo";
+
+
+rtmpuri = "http://"+hostname+":"+rtmptport+"/echo/gateway";;
 note("Connecting to "+rtmpuri);
 nc.connect(rtmpuri);
-check_equals(nc.isConnected, false); // not yet
+// The network connection is not opened at connect() time, but when
+// the first call() is made.
+check_equals(nc.isConnected, false);
 check_equals(nc.statuses.length, 0);
 
-o=new ResultHandler();
-o.onResult = function()
+nc.onResult = function()
 {
+    note("Got a result back from the server.");
     check_equals(nc.isConnected, true); // now it is connected
     check_equals(nc.statuses.length, 1);
     lastStatusArgs = nc.statuses[nc.statuses.length-1];
     check_equals(lastStatusArgs[0].level, 'status');
     check_equals(lastStatusArgs[0].code, 'NetConnection.Connect.Success');
-       check_equals(arguments.toString(), '1');
+};
+
+
+//
+// The Red5 echo tests Null, Undefined, Boolean True, Boolean False,
+// String, Number, Array, Object, Date, Custom Class Remote Class
+//
+
+// This call starts the actual network connection
+result1=false;;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a null result back from the server."+dumpObject(arguments));
+    note(arguments[0]);
+    if (arguments.length == 1) {
+       if (arguments[0] == null) {
+           result1=true;
+       }
+    }
+};
+nc.call("echo", o, null);
+
+result2=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got an undefined result back from the 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == undefined) {
+           result2=true;
+       }
+    }
+};
+nc.call("echo", o, undefined);
+
+// bt=new Boolean(true);
+// o=new ResultHandler();
+// o.onResult = function()
+// {
+//     check_equals(arguments.toString(), trued);
+// };
+// nc.call("echo", o, bt);
+
+// bf=new Boolean(false);
+// nc.call("echo", o, bf);
+
+// Empty String
+result3=false;
+tstr = new String();
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a string result back from the server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0].length == 0) {
+           result3 = true;
+       }
+    }
+};
+nc.call("echo", o, tstr);
+
+// Hello World!
+result4=false;
+tstr2 = "Hello World!";
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a string result back from the server."+dumpObject(arguments));
+//     note("ARG4 is: " +dumpObject(arguments[0]));
+    str = arguments[0].toString();
+    if (arguments.length == 1) {
+       if ((arguments[0].length == 12)
+           && (arguments[0].toString() == "Hello World!")) {
+           result4 = true;
+       }
+    }
+};
+nc.call("echo", o, tstr2);
+
+// test1,test2,test3,test4
+
+// Number 0
+result5=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical 0 result back from the 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == 0) {
+           result5 = true;
+       }
+    }
+};
+nc.call("echo", o, 0);
+
+// Number 1
+result6=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical 1 result back from the 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == 1) {
+           result6 = true;
+       }
+    }
 };
 nc.call("echo", o, 1);
 
-o=new ResultHandler();
-o.onResult = function()
-{
-       check_equals(arguments.toString(), '1,2,3');
-};
-nc.call("echo", o, 1, 2, 3);
-
-o=new ResultHandler();
-o.onResult = function()
-{
-       check_equals(arguments.toString(), '1,two,true,4,5,6');
-    endOfTest();
-};
-nc.call("echo", o, 1, 'two', true, [4,5,6]);
+// Number -1
+result7=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical -1 result back from the 
server."+dumpObject(arguments));
+    if ((arguments.length == 1)) {
+       note("FIXME: "+arguments[0].to_number());
+       result7 = true;
+    }
+};
+nc.call("echo", o, -1);
+
+// Number 256
+result8=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical 256 result back from the 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == 256) {
+           result8 = true;
+       }
+    }
+};
+nc.call("echo", o, 256);
+
+// Number -256
+result9=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical -256 result back from the 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == -256) {
+           result9 = true;
+       }
+    }
+};
+nc.call("echo", o, -256);
+
+// Number 65536
+result10=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical 65536 result back from the 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == 65536) {
+           result10 = true;
+       }
+    }
+};
+nc.call("echo", o, 65536);
+
+// Number -65536
+result11=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical -65536 result back from the 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == -65536) {
+           result11 = true;
+       }
+    }
+};
+nc.call("echo", o, -65536);
+
+// 1.5
+result12=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical 1.5 result back from the 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == 1.5) {
+           result12 = true;
+       }
+    }
+};
+nc.call("echo", o, 1.5);
+
+// -1.5
+result13=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical -1.5 result back from the 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == -1.5) {
+           result13 = true;
+       }
+    }
+};
+nc.call("echo", o, -1.5);
+
+// Number NaN
+result14=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical NaN result back from the 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == NaN) {
+           result14 = true;
+       }
+    }
+};
+nc.call("echo", o, NaN);
+
+// Number Infinity
+result15=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got an numerical infinity result back from the 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == infinity) {
+           result15 = true;
+       }
+    }
+};
+nc.call("echo", o, infinity);
+
+// Number -Infinity
+result16=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical -infinity result back from the 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == -infinity) {
+           result16 = true;
+       }
+    }
+};
+nc.call("echo", o, -infinity);
+
+// o=new ResultHandler();
+// o.onResult = function()
+// {
+//     note("Got a result back from the server.");
+//     check_equals(arguments.toString(), '1,two,true,4,5,6');
+//     endOfTest();
+// };
+// nc.call("echo", o, 1, 'two', true, [4,5,6]);
+
+// o=new ResultHandler();
+// o.onResult = function()
+// {
+//     note("Got a result back from the server.");
+//     check_equals(arguments.toString(), '1,2,3');
+// };
+// nc.call("echo", o, 1, 2, 3);
+
+
+// Test empty array
+tar = new Array();
+result17=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got an empty array result back from the 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0].length == 0) {
+           result17 = true;
+       }
+    }
+};
+nc.call("echo", o, tar);
+
+// Test array with only one item
+result18=false;
+tar = new Array();
+tar.push(1);
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a single item array result back from the 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0][0] == 1) {
+           result18 = true;
+       }
+    }
+};
+nc.call("echo", o, tar);
+
+// Test array with multiple items
+result19=false;
+tar = new Array();
+tar.push(1);
+tar.push(2);
+tar.push(3);
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got an 3 item array result back from the 
server."+dumpObject(arguments));
+    if ((arguments.length == 1) && (arguments[0].length == 3)) {
+       if ((arguments[0][0] == 1) && (arguments[0][1] == 2) && 
(arguments[0][2] == 3))  {
+           result19 = true;
+       }
+    }
+//    note(arguments[0].toString());
+//    check_equals(arguments[0].toString(), "1.2.3");
+};
+nc.call("echo", o, tar);
+
+// Test sparse array
+result20=false;
+tar2 = new Array();
+tar2.push(1);
+tar2.push();
+tar2.push();
+tar2.push();
+tar2.push(5);
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a sparse result back from the server."+dumpObject(arguments));
+    if ((arguments.length == 1) && (arguments[0].length == 2)) {
+       if ((arguments[0][0] == 1) && (arguments[0][1] == 5))  {
+           result20 = true;
+       }   
+    }
+//    check_equals(arguments.toString(), "1..,,5");
+};
+nc.call("echo", o, tar2);
+
+// Do the tests to see what happened last, to give the callbacks time
+// to be executed, as they're a background thread.
+if (result1) {
+    pass("RTMPT: Echo NULL Object");
+} else {
+    fail("RTMPT: Echo NULL Object");
+}
+
+if (result2) {
+    pass("RTMPT: Echo UNDEFINED Object");
+} else {
+    fail("RTMPT: Echo UNDEFINED Object");
+}
+
+if (result3) {
+    pass("RTMPT: Echo empty String");
+} else {
+    fail("RTMPT: Echo empty String");
+}
+
+if (result4) {
+    pass("RTMPT: Echo short String");
+} else {
+    fail("RTMPT: Echo short String");
+}
+
+if (result5) {
+    pass("RTMPT: Echo Number 0");
+} else {
+    fail("RTMPT: Echo Number 0");
+}
+
+if (result6) {
+    pass("RTMPT: Echo Number 1");
+} else {
+    fail("RTMPT: Echo Number 1");
+}
+
+if (result7) {
+    pass("RTMPT: Echo Number -1");
+} else {
+    fail("RTMPT: Echo Number -1");
+}
+if (result8) {
+    pass("RTMPT: Echo Number 256");
+} else {
+    fail("RTMPT: Echo Number 256");
+}
+if (result9) {
+    pass("RTMPT: Echo Number -256");
+} else {
+    fail("RTMPT: Echo Number -256");
+}
+if (result10) {
+    pass("RTMPT: Echo Number 65536");
+} else {
+    fail("RTMPT: Echo Number 65536");
+}
+if (result11) {
+    pass("RTMPT: Echo Number -65536");
+} else {
+    fail("RTMPT: Echo Number -65536");
+}
+if (result12) {
+    pass("RTMPT: Echo Number 1.5");
+} else {
+    fail("RTMPT: Echo Number 1.5");
+}
+if (result13) {
+    pass("RTMPT: Echo Number -1.5");
+} else {
+    fail("RTMPT: Echo Number -1.5");
+}
+if (result14) {
+    pass("RTMPT: Echo Number NaN");
+} else {
+    fail("RTMPT: Echo Number NaN");
+}
+if (result15) {
+    pass("RTMPT: Echo Number Infinity");
+} else {
+    fail("RTMPT: Echo Number Infinity");
+}
+if (result16) {
+    pass("RTMPT: Echo Number -Infinity");
+} else {
+    fail("RTMPT: Echo Number -Infinity");
+}
+
+if (result17) {
+    pass("RTMPT: Echo empty array");
+} else {
+    fail("RTMPT: Echo empty array");
+}
+if (result18) {
+    pass("RTMPT: Echo 1 item array");
+} else {
+    fail("RTMPT: Echo 1 item array");
+}
+if (result19) {
+    pass("ERTMPT: cho 3 item array");
+} else {
+    fail("RTMPT: Echo 3 item array");
+}
+if (result20) {
+    pass("RTMPT: Echo sparse array");
+} else {
+    fail("RTMPT: cho sparse array");
+}
+
+//
+// do the same thing for RTMP
+//
+ncrtmp = new NetConnection;
+ncrtmp.statuses = new Array();
+ncrtmp.onStatus = function()
+{
+    this.statuses.push(arguments);
+    note('NetConnection.onStatus called with args: '+dumpObject(arguments));
+    lastStatusArgs = ncrtmp.statuses[ncrtmp.statuses.length-1];
+    if ((lastStatusArgs[0].level == "status") && (lastStatusArgs[0].code == 
"NetConnection.Connect.Success")) {
+        pass("RTMP connection - status Success");
+    } else {
+        fail("RTMP connection - status Success");
+    }
+};
+
+nc.onResult = function()
+{
+    this.statuses.push(arguments);
+    note('NetConnection.onResult called with args: '+dumpObject(arguments));
+};
+
+
+rtmpuri = "rtmp://"+hostname+":"+rtmpport+"/echo";
+note("Connecting to "+rtmpuri);
+ncrtmp.connect(rtmpuri);
+
+// The network connection is not opened at connect() time, but when
+// the first call() is made.
+if ((ncrtmp.isConnected == false)  && (ncrtmp.statuses.length == 0)) {
+    pass("RTMP connection - connect");
+} else {
+    fail("RTMP connection - connect");
+}
+
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a result back from the  RTMP server.");
+    
+    // now it is connected
+    if ((ncrtmp.isConnected == true) && (ncrtmp.statuses.length == 1)) {
+        pass("RTMP connection - result");
+    } else {
+        fail("RTMP connection - result");        
+    }
+    
+    lastStatusArgs = ncrtmp.statuses[ncrtmp.statuses.length-1];
+    if ((lastStatusArgs[0].level == "status") && (lastStatusArgs[0].code == 
"NetConnection.Connect.Success")) {
+        pass("RTMP connection - status");
+    } else {
+        fail("RTMP connection - status");        
+    }
+    
+};
+
+// This call starts the actual network connection
+result1=false;;
+o.onResult = function()
+{
+    note("Got a null result back from the RTMP server."+dumpObject(arguments));
+    note(arguments[0]);
+    if (arguments.length == 1) {
+       if (arguments[0] == null) {
+           result1=true;
+       }
+    }
+};
+ncrtmp.call("echo", o, null);
+
+// Empty String
+result3=false;
+tstr = new String();
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a string result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0].length == 0) {
+           result3 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, tstr);
+
+// Hello World!
+result4=false;
+tstr2 = "Hello World!";
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a string result back from the RTMP 
server."+dumpObject(arguments));
+//     note("ARG4 is: " +dumpObject(arguments[0]));
+    str = arguments[0].toString();
+    if (arguments.length == 1) {
+       if ((arguments[0].length == 12)
+           && (arguments[0].toString() == "Hello World!")) {
+           result4 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, tstr2);
+
+// test1,test2,test3,test4
+
+// Number 0
+result5=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical 0 result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == 0) {
+           result5 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, 0);
+
+// Number 1
+result6=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical 1 result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == 1) {
+           result6 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, 1);
+
+// Number -1
+result7=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical -1 result back from the RTMP 
server."+dumpObject(arguments));
+    if ((arguments.length == 1)) {
+       note("FIXME: "+arguments[0].to_number());
+       result7 = true;
+    }
+};
+ncrtmp.call("echo", o, -1);
+
+// Number 256
+result8=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical 256 result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == 256) {
+           result8 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, 256);
+
+// Number -256
+result9=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical -256 result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == -256) {
+           result9 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, -256);
+
+// Number 65536
+result10=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical 65536 result back from the  
RTMPserver."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == 65536) {
+           result10 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, 65536);
+
+// Number -65536
+result11=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical -65536 result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == -65536) {
+           result11 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, -65536);
+
+// 1.5
+result12=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical 1.5 result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == 1.5) {
+           result12 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, 1.5);
+
+// -1.5
+result13=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical -1.5 result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == -1.5) {
+           result13 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, -1.5);
+
+// Number NaN
+result14=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical NaN result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == NaN) {
+           result14 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, NaN);
+
+// Number Infinity
+result15=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got an numerical infinity result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == infinity) {
+           result15 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, infinity);
+
+// Number -Infinity
+result16=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical -infinity result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == -infinity) {
+           result16 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, -infinity);
+
+// o=new ResultHandler();
+// o.onResult = function()
+// {
+//     note("Got a result back from the server.");
+//     check_equals(arguments.toString(), '1,two,true,4,5,6');
+//     endOfTest();
+// };
+// ncrtmp.call("echo", o, 1, 'two', true, [4,5,6]);
+
+// o=new ResultHandler();
+// o.onResult = function()
+// {
+//     note("Got a result back from the server.");
+//     check_equals(arguments.toString(), '1,2,3');
+// };
+// ncrtmp.call("echo", o, 1, 2, 3);
+
+
+// Test empty array
+tar = new Array();
+result17=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got an empty array result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0].length == 0) {
+           result17 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, tar);
+
+// Test array with only one item
+result18=false;
+tar = new Array();
+tar.push(1);
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a single item array result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0][0] == 1) {
+           result18 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, tar);
+
+// Test array with multiple items
+result19=false;
+tar = new Array();
+tar.push(1);
+tar.push(2);
+tar.push(3);
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got an 3 item array result back from the RTMP 
server."+dumpObject(arguments));
+    if ((arguments.length == 1) && (arguments[0].length == 3)) {
+       if ((arguments[0][0] == 1) && (arguments[0][1] == 2) && 
(arguments[0][2] == 3))  {
+           result19 = true;
+       }
+    }
+//    note(arguments[0].toString());
+//    check_equals(arguments[0].toString(), "1.2.3");
+};
+ncrtmp.call("echo", o, tar);
+
+// Test sparse array
+result20=false;
+tar2 = new Array();
+tar2.push(1);
+tar2.push();
+tar2.push();
+tar2.push();
+tar2.push(5);
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a sparse result back from the RTMP 
server."+dumpObject(arguments));
+    if ((arguments.length == 1) && (arguments[0].length == 2)) {
+       if ((arguments[0][0] == 1) && (arguments[0][1] == 5))  {
+           result20 = true;
+       }   
+    }
+//    check_equals(arguments.toString(), "1..,,5");
+};
+ncrtmp.call("echo", o, tar2);
+
+if (result1) {
+    pass("RTMP: Echo NULL Object");
+} else {
+    fail("RTMP: Echo NULL Object");
+}
+
+if (result3) {
+    pass("RTMP: Echo empty String");
+} else {
+    fail("RTMP: Echo empty String");
+}
+
+if (result4) {
+    pass("RTMP: Echo short String");
+} else {
+    fail("RTMP: Echo short String");
+}
+
+if (result5) {
+    pass("RTMP: Echo Number 0");
+} else {
+    fail("RTMP: Echo Number 0");
+}
+
+if (result6) {
+    pass("RTMP: Echo Number 1");
+} else {
+    fail("RTMP: Echo Number 1");
+}
+
+if (result7) {
+    pass("RTMP: Echo Number -1");
+} else {
+    fail("RTMP: Echo Number -1");
+}
+if (result8) {
+    pass("RTMP: Echo Number 256");
+} else {
+    fail("RTMP: Echo Number 256");
+}
+if (result9) {
+    pass("RTMP: Echo Number -256");
+} else {
+    fail("RTMP: Echo Number -256");
+}
+if (result10) {
+    pass("RTMP: Echo Number 65536");
+} else {
+    fail("RTMP: Echo Number 65536");
+}
+if (result11) {
+    pass("RTMP: Echo Number -65536");
+} else {
+    fail("RTMP: Echo Number -65536");
+}
+if (result12) {
+    pass("RTMP: Echo Number 1.5");
+} else {
+    fail("RTMP: Echo Number 1.5");
+}
+if (result13) {
+    pass("RTMP: Echo Number -1.5");
+} else {
+    fail("RTMP: Echo Number -1.5");
+}
+if (result14) {
+    pass("RTMP: Echo Number NaN");
+} else {
+    fail("Echo Number NaN");
+}
+if (result15) {
+    pass("RTMP: Echo Number Infinity");
+} else {
+    fail("RTMP: Echo Number Infinity");
+}
+if (result16) {
+    pass("RTMP: Echo Number -Infinity");
+} else {
+    fail("RTMP: Echo Number -Infinity");
+}
+
+if (result17) {
+    pass("RTMP: Echo empty array");
+} else {
+    fail("RTMP: Echo empty array");
+}
+if (result18) {
+    pass("RTMP: Echo 1 item array");
+} else {
+    fail("RTMP: Echo 1 item array");
+}
+if (result19) {
+    pass("RTMP: Echo 3 item array");
+} else {
+    fail("RTMP: Echo 3 item array");
+}
+if (result20) {
+    pass("RTMP: Echo sparse array");
+} else {
+    fail("RTMP: Echo sparse array");
+}

=== added directory 'testsuite/network.all'
=== added file 'testsuite/network.all/Dejagnu.c'
--- a/testsuite/network.all/Dejagnu.c   1970-01-01 00:00:00 +0000
+++ b/testsuite/network.all/Dejagnu.c   2009-04-01 02:49:29 +0000
@@ -0,0 +1,95 @@
+/* 
+ *   Copyright (C) 2005, 2006, 2009 Free Software Foundation, Inc.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ *
+ */ 
+
+/*
+ * Generate a Dejagnu.swf file for import from self-contained
+ * SWF testcases
+ *
+ * run as ./Dejagnu <mediadir>
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ming.h>
+
+#include "ming_utils.h"
+
+#define OUTPUT_VERSION 5
+#define OUTPUT_FILENAME "Dejagnu.swf"
+
+int
+main(int argc, char** argv)
+{
+       SWFMovie mo;
+       SWFMovieClip dejaclip;
+       const char *srcdir=".";
+       SWFFont bfont; 
+
+
+       /*********************************************
+        *
+        * Initialization
+        *
+        *********************************************/
+
+       if ( argc>1 ) srcdir=argv[1];
+       else
+       {
+               fprintf(stderr, "Usage: %s <mediadir>\n", argv[0]);
+               return 1;
+       }
+
+       puts("Setting things up");
+
+       Ming_init();
+        Ming_useSWFVersion (OUTPUT_VERSION);
+       Ming_setScale(20.0); /* let's talk pixels */
+ 
+       mo = newSWFMovie();
+       SWFMovie_setRate(mo, 1);
+       SWFMovie_setDimension(mo, 628, 1024);
+
+       bfont = get_default_font(srcdir);
+
+       /*********************************************
+        *
+        * Body
+        *
+        *********************************************/
+
+       dejaclip = get_dejagnu_clip((SWFBlock)bfont, 3000, 0, 50, 800, 800);
+
+       SWFMovie_add(mo, (SWFBlock)dejaclip);
+       SWFMovie_addExport(mo, (SWFBlock)dejaclip, "dejagnu");
+
+       SWFMovie_nextFrame(mo); /* showFrame */
+
+
+       /*****************************************************
+        *
+        * Output movie
+        *
+        *****************************************************/
+
+       puts("Saving " OUTPUT_FILENAME );
+
+       SWFMovie_save(mo, OUTPUT_FILENAME);
+
+       return 0;
+}

=== added file 'testsuite/network.all/Makefile.am'
--- a/testsuite/network.all/Makefile.am 1970-01-01 00:00:00 +0000
+++ b/testsuite/network.all/Makefile.am 2009-04-01 02:49:29 +0000
@@ -0,0 +1,140 @@
+## Process this file with automake to generate Makefile.in
+# 
+# Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+AUTOMAKE_OPTIONS = dejagnu -Wno-portability
+
+abs_top_builddir=$(shell cd $(top_builddir); pwd)
+abs_builddir=$(shell cd $(top_builddir)/testsuite/network.all; pwd)
+abs_mediadir = $(shell cd $(srcdir)/../media; pwd)
+
+CLEANFILES =  \
+       gnash-dbg.log \
+       site.exp.bak \
+       testrun.sum \
+       testrun.log
+
+EXTRA_DIST = \
+       http.as \
+       rtmp.as \
+       netstream.as
+
+AM_CPPFLAGS = \
+       -I$(top_srcdir)/libbase \
+       -I$(top_srcdir)/libmedia \
+       -I$(top_srcdir)/libsound \
+       -I$(top_srcdir)/backend \
+       -I$(top_srcdir)/libcore  \
+       -I$(top_srcdir)/libcore/parser  \
+       -I$(top_srcdir)/libcore/vm \
+       -I$(top_srcdir)/libcore/asobj \
+       -I$(top_srcdir)/testsuite \
+       -I$(top_srcdir)/testsuite/misc-ming.all \
+       $(MING_CFLAGS) \
+       $(OPENGL_CFLAGS) \
+       $(BOOST_CFLAGS) \
+       -DMING_VERSION_CODE=$(MING_VERSION_CODE) \
+       $(NULL)
+
+AM_LDFLAGS = \
+       $(MING_LIBS) \
+       $(OPENGL_LIBS) \
+       $(GIF_LIBS) \
+       $(NULL)
+
+check_PROGRAMS = \
+       Dejagnu \
+       Dejagnu.swf \
+       $(NULL)
+
+check_SCRIPTS = \
+       http.swf \
+       rtmp.swf
+
+# if MAKESWF_SUPPORTS_PREBUILT_CLIPS
+#   check_SCRIPTS += remotingTestRunner
+#   check_SCRIPTS += red5testRunner
+# endif
+
+check_LTLIBRARIES = libgnashmingutils.la 
+libgnashmingutils_la_SOURCES = \
+       $(top_srcdir)/testsuite/misc-ming.all/ming_utils.h \
+       $(top_srcdir)/testsuite/misc-ming.all/ming_utils.c
+
+http.swf: $(srcdir)/http.as Dejagnu.swf Makefile ../actionscript.all/check.as 
../actionscript.all/utils.as
+       $(MAKESWF) -n network -r12 -o $@ -v7 -DRED5_HOST='\"$(RED5_HOST)\"' 
-DUSE_DEJAGNU_MODULE -DOUTPUT_VERSION=7 Dejagnu.swf $(srcdir)/http.as 
$(srcdir)/../actionscript.all/dejagnu_so_fini.as
+
+httpTestRunner: $(srcdir)/../generic-testrunner.sh http.swf
+       sh $< $(top_builddir) http.swf > $@
+       chmod 755 $@
+
+rtmp.swf: $(srcdir)/rtmp.as Dejagnu.swf Makefile ../actionscript.all/check.as 
../actionscript.all/utils.as
+       $(MAKESWF) -n network -r12 -o $@ -v7 -DRED5_HOST='\"$(RED5_HOST)\"' 
-DUSE_DEJAGNU_MODULE -DOUTPUT_VERSION=7 Dejagnu.swf $(srcdir)/rtmp.as 
$(srcdir)/../actionscript.all/dejagnu_so_fini.as
+
+rtmpTestRunner: $(srcdir)/../generic-testrunner.sh rtmp.swf
+       sh $< $(top_builddir) rtmp.swf > $@
+       chmod 755 $@
+
+netstream.swf: $(srcdir)/netstream.as Dejagnu.swf Makefile 
../actionscript.all/check.as ../actionscript.all/utils.as
+       $(MAKESWF) -n network -r12 -o $@ -v7 -DRED5_HOST='\"$(RED5_HOST)\"' 
-DUSE_DEJAGNU_MODULE -DOUTPUT_VERSION=7 Dejagnu.swf $(srcdir)/netstream.as 
$(srcdir)/../actionscript.all/dejagnu_so_fini.as
+
+netstreamRunner: $(srcdir)/../generic-testrunner.sh netstream.swf
+       sh $< $(top_builddir) netstream.swf > $@
+       chmod 755 $@
+
+Dejagnu_SOURCES = \
+       Dejagnu.c       \
+       $(NULL)
+Dejagnu_LDADD = libgnashmingutils.la
+
+Dejagnu.swf: Dejagnu
+       ./Dejagnu $(top_srcdir)/testsuite/media
+
+clean-local: 
+       -rm *.swf media *.pp *unner
+
+TEST_DRIVERS = network.exp
+TEST_CASES = \
+       http.swf \
+       rtmp.swf \
+       $(NULL)
+
+if MAKESWF_SUPPORTS_PREBUILT_CLIPS
+# if ENABLE_HTTP_TESTSUITE
+# TEST_CASES += remotingTestRunner
+# endif
+# TEST_CASES += red5testRunner
+endif
+
+check-DEJAGNU: site-update $(check_PROGRAMS)
+       @runtest=$(RUNTEST); \
+       if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
+           GNASH_GC_TRIGGER_THRESHOLD=0 GNASHRC=../gnashrc $$runtest 
$(RUNTESTFLAGS) $(TEST_DRIVERS); true; \
+       else \
+         echo "WARNING: could not find \`runtest'" 1>&2; \
+          for i in "$(TEST_CASES)"; do \
+           GNASH_GC_TRIGGER_THRESHOLD=0 GNASHRC=../gnashrc $(SHELL) $$i; \
+         done; \
+       fi
+
+site-update: site.exp
+       @rm -fr site.exp.bak
+       @cp site.exp site.exp.bak
+       @sed -e '/testcases/d' site.exp.bak > site.exp
+       @echo "# This is a list of the pre-compiled testcases" >> site.exp
+       @echo "set testcases \"$(TEST_CASES)\"" >> site.exp
+

=== added file 'testsuite/network.all/http.as'
--- a/testsuite/network.all/http.as     1970-01-01 00:00:00 +0000
+++ b/testsuite/network.all/http.as     2009-04-01 20:53:29 +0000
@@ -0,0 +1,565 @@
+// This test relies on a default deploy of red5 on localhost
+//
+// Build with:
+//     makeswf -n network -o red5test.swf ../Dejagnu.swf red5test.as 
../actionscript.all/dejagnu_so_fini.as
+// Run with:
+//     firefox red5test.swf
+// Or:
+//     gnash red5test.swf
+//
+//
+
+#define info _root.note
+#define note _root.note
+#define fail_check _root.fail
+#define pass_check  _root.pass
+#define xfail_check _root.xfail
+#define xpass_check _root.xpass
+
+note("SWF" + OUTPUT_VERSION + " - " + System.capabilities.version + "\n");
+rcsid="red5test.as - <bzr revno here>";
+
+#include "../actionscript.all/check.as"
+#include "../actionscript.all/utils.as"
+#include "../actionscript.all/dejagnu.as"
+
+stop();
+
+endOfTest = function()
+{
+       //note("END OF TEST");
+//        check_totals(9);
+    totals();
+    play();
+};
+
+// -P FlashVars='hostname=localhost,rtmptport5080=rtmpport=1935'
+if (hostname == undefined) {
+    hostname="localhost";
+    note("No hostname specified, defaulting to "+hostname);
+}
+
+if (rtmptport == undefined) {
+    rtmptport = 5080;
+    note("No HTTP port specified, defaulting to "+rtmptport);
+}
+
+if (rtmpport == undefined) {
+    rtmpport = 1935;
+    note("No HTTP port specified, defaulting to "+rtmpport);
+}
+
+nc = new NetConnection;
+nc.statuses = new Array();
+nc.onStatus = function()
+{
+    note('NetConnection.onStatus called with args: '+dumpObject(arguments));
+};
+
+nc.onResult = function()
+{
+    note('NetConnection.onResult called with args: '+dumpObject(arguments));
+    if ((lastStatusArgs[0].level == "status") && (lastStatusArgs[0].code == 
"NetConnection.Connect.Success")) {
+        pass("HTTP connection - status Success");
+    } else {
+        fail("HTTP connection - status Success");
+    }
+};
+
+function ResultHandler() {
+    this.onResult = function(result) {
+        note('default onResult called with args: '+dumpObject(arguments));
+    };
+//     this.onCustom = function(result) {
+//         note('default onCustom called with args: '+dumpObject(arguments));
+//     };
+//     this.onDebugEvents = function(result) {
+//         note('default onDebugEvents called with args: 
'+dumpObject(arguments));
+//     };
+//     this.onStatus = function(result) {
+//     note("default onStatus called with args: "+dumpObject(arguments));
+//     };
+};
+
+
+
+rtmpuri = "http://"+hostname+":"+rtmptport+"/echo/gateway";;
+note("Connecting to "+rtmpuri);
+nc.connect(rtmpuri);
+// The network connection is not opened at connect() time, but when
+// the first call() is made.
+
+if (nc.isConnected == false) { // now it is connected
+    pass("HTTP connection - status isConnected");
+} else {
+    fail("HTTP connection - status isConnected");
+}
+
+nc.onResult = function()
+{
+    note("Got a connection result back from the server.");
+    if (nc.isConnected == true) { // now it is connected
+        pass("HTTP connection - status isConnected");
+    } else {
+        fail("HTTP connection - status isConnected");
+    }
+    lastStatusArgs = nc.statuses[nc.statuses.length-1];
+    if ((lastStatusArgs[0].level == "status") && (lastStatusArgs[0].code == 
"NetConnection.Connect.Success")) {
+        pass("HTTP connection - status Success");
+    } else {
+        fail("HTTP connection - status Success");
+    }
+};
+
+
+//
+// The Red5 echo tests Null, Undefined, Boolean True, Boolean False,
+// String, Number, Array, Object, Date, Custom Class Remote Class
+//
+
+// This call starts the actual network connection
+result1=false;;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a null result back from the HTTP server."+dumpObject(arguments));
+    note(arguments[0]);
+    if (arguments.length == 1) {
+       if (arguments[0] == null) {
+           result1=true;
+       }
+    }
+};
+nc.call("echo", o, null);
+if (nc.isConnected == true) { // now it is connected
+    pass("HTTP connection - status isConnected");
+} else {
+    fail("HTTP connection - status isConnected");
+}
+
+result2=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got an undefined result back from the HTTP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == undefined) {
+           result2=true;
+       }
+    }
+};
+nc.call("echo", o, undefined);
+
+// bt=new Boolean(true);
+// o=new ResultHandler();
+// o.onResult = function()
+// {
+//     check_equals(arguments.toString(), trued);
+// };
+// nc.call("echo", o, bt);
+
+// bf=new Boolean(false);
+// nc.call("echo", o, bf);
+
+// Empty String
+result3=false;
+tstr = new String();
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a string result back from the HTTP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0].length == 0) {
+           result3 = true;
+       }
+    }
+};
+nc.call("echo", o, tstr);
+
+// Hello World!
+result4=false;
+tstr2 = "Hello World!";
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a string result back from the HTTP 
server."+dumpObject(arguments));
+//     note("ARG4 is: " +dumpObject(arguments[0]));
+    str = arguments[0].toString();
+    if (arguments.length == 1) {
+       if ((arguments[0].length == 12)
+           && (arguments[0].toString() == "Hello World!")) {
+           result4 = true;
+       }
+    }
+};
+nc.call("echo", o, tstr2);
+
+// test1,test2,test3,test4
+
+// Number 0
+result5=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical 0 result back from the HTTP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == 0) {
+           result5 = true;
+       }
+    }
+};
+nc.call("echo", o, 0);
+
+// Number 1
+result6=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical 1 result back from the HTTP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == 1) {
+           result6 = true;
+       }
+    }
+};
+nc.call("echo", o, 1);
+
+// Number -1
+result7=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical -1 result back from the HTTP 
server."+dumpObject(arguments));
+    if ((arguments.length == 1)) {
+       note("FIXME: "+arguments[0].to_number());
+       result7 = true;
+    }
+};
+nc.call("echo", o, -1);
+
+// Number 256
+result8=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical 256 result back from the HTTP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == 256) {
+           result8 = true;
+       }
+    }
+};
+nc.call("echo", o, 256);
+
+// Number -256
+result9=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical -256 result back from the HTTP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == -256) {
+           result9 = true;
+       }
+    }
+};
+nc.call("echo", o, -256);
+
+// Number 65536
+result10=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical 65536 result back from the HTTP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == 65536) {
+           result10 = true;
+       }
+    }
+};
+nc.call("echo", o, 65536);
+
+// Number -65536
+result11=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical -65536 result back from the HTTP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == -65536) {
+           result11 = true;
+       }
+    }
+};
+nc.call("echo", o, -65536);
+
+// 1.5
+result12=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical 1.5 result back from the HTTP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == 1.5) {
+           result12 = true;
+       }
+    }
+};
+nc.call("echo", o, 1.5);
+
+// -1.5
+result13=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical -1.5 result back from the  
HTTPserver."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == -1.5) {
+           result13 = true;
+       }
+    }
+};
+nc.call("echo", o, -1.5);
+
+// Number NaN
+result14=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical NaN result back from the HTTP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == NaN) {
+           result14 = true;
+       }
+    }
+};
+nc.call("echo", o, NaN);
+
+// Number Infinity
+result15=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got an numerical infinity result back from the HTTP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == infinity) {
+           result15 = true;
+       }
+    }
+};
+nc.call("echo", o, infinity);
+
+// Number -Infinity
+result16=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical -infinity result back from the HTTP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == -infinity) {
+           result16 = true;
+       }
+    }
+};
+nc.call("echo", o, -infinity);
+
+// o=new ResultHandler();
+// o.onResult = function()
+// {
+//     note("Got a result back from the server.");
+//     check_equals(arguments.toString(), '1,two,true,4,5,6');
+//     endOfTest();
+// };
+// nc.call("echo", o, 1, 'two', true, [4,5,6]);
+
+// o=new ResultHandler();
+// o.onResult = function()
+// {
+//     note("Got a result back from the server.");
+//     check_equals(arguments.toString(), '1,2,3');
+// };
+// nc.call("echo", o, 1, 2, 3);
+
+
+// Test empty array
+tar = new Array();
+result17=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got an empty array result back from the HTTP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0].length == 0) {
+           result17 = true;
+       }
+    }
+};
+nc.call("echo", o, tar);
+
+// Test array with only one item
+result18=false;
+tar = new Array();
+tar.push(1);
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a single item array result back from the HTTP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0][0] == 1) {
+           result18 = true;
+       }
+    }
+};
+nc.call("echo", o, tar);
+
+// Test array with multiple items
+result19=false;
+tar = new Array();
+tar.push(1);
+tar.push(2);
+tar.push(3);
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got an 3 item array result back from the HTTP 
server."+dumpObject(arguments));
+    if ((arguments.length == 1) && (arguments[0].length == 3)) {
+       if ((arguments[0][0] == 1) && (arguments[0][1] == 2) && 
(arguments[0][2] == 3))  {
+           result19 = true;
+       }
+    }
+//    note(arguments[0].toString());
+//    check_equals(arguments[0].toString(), "1.2.3");
+};
+nc.call("echo", o, tar);
+
+// Test sparse array
+result20=false;
+tar2 = new Array();
+tar2.push(1);
+tar2.push();
+tar2.push();
+tar2.push();
+tar2.push(5);
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a sparse result back from the HTTP 
server."+dumpObject(arguments));
+    if ((arguments.length == 1) && (arguments[0].length == 2)) {
+       if ((arguments[0][0] == 1) && (arguments[0][1] == 5))  {
+           result20 = true;
+       }   
+    }
+//    check_equals(arguments.toString(), "1..,,5");
+};
+nc.call("echo", o, tar2);
+
+// Do the tests to see what happened last, to give the callbacks time
+// to be executed, as they're a background thread.
+if (result1) {
+    pass("RTMPT: Echo NULL Object");
+} else {
+    fail("RTMPT: Echo NULL Object");
+}
+
+if (result2) {
+    pass("RTMPT: Echo UNDEFINED Object");
+} else {
+    fail("RTMPT: Echo UNDEFINED Object");
+}
+
+if (result3) {
+    pass("RTMPT: Echo empty String");
+} else {
+    fail("RTMPT: Echo empty String");
+}
+
+if (result4) {
+    pass("RTMPT: Echo short String");
+} else {
+    fail("RTMPT: Echo short String");
+}
+
+if (result5) {
+    pass("RTMPT: Echo Number 0");
+} else {
+    fail("RTMPT: Echo Number 0");
+}
+
+if (result6) {
+    pass("RTMPT: Echo Number 1");
+} else {
+    fail("RTMPT: Echo Number 1");
+}
+
+if (result7) {
+    pass("RTMPT: Echo Number -1");
+} else {
+    fail("RTMPT: Echo Number -1");
+}
+if (result8) {
+    pass("RTMPT: Echo Number 256");
+} else {
+    fail("RTMPT: Echo Number 256");
+}
+if (result9) {
+    pass("RTMPT: Echo Number -256");
+} else {
+    fail("RTMPT: Echo Number -256");
+}
+if (result10) {
+    pass("RTMPT: Echo Number 65536");
+} else {
+    fail("RTMPT: Echo Number 65536");
+}
+if (result11) {
+    pass("RTMPT: Echo Number -65536");
+} else {
+    fail("RTMPT: Echo Number -65536");
+}
+if (result12) {
+    pass("RTMPT: Echo Number 1.5");
+} else {
+    fail("RTMPT: Echo Number 1.5");
+}
+if (result13) {
+    pass("RTMPT: Echo Number -1.5");
+} else {
+    fail("RTMPT: Echo Number -1.5");
+}
+if (result14) {
+    pass("RTMPT: Echo Number NaN");
+} else {
+    fail("RTMPT: Echo Number NaN");
+}
+if (result15) {
+    pass("RTMPT: Echo Number Infinity");
+} else {
+    fail("RTMPT: Echo Number Infinity");
+}
+if (result16) {
+    pass("RTMPT: Echo Number -Infinity");
+} else {
+    fail("RTMPT: Echo Number -Infinity");
+}
+
+if (result17) {
+    pass("RTMPT: Echo empty array");
+} else {
+    fail("RTMPT: Echo empty array");
+}
+if (result18) {
+    pass("RTMPT: Echo 1 item array");
+} else {
+    fail("RTMPT: Echo 1 item array");
+}
+if (result19) {
+    pass("RTMPT: Echo 3 item array");
+} else {
+    fail("RTMPT: Echo 3 item array");
+}
+if (result20) {
+    pass("RTMPT: Echo sparse array");
+} else {
+    fail("RTMPT: cho sparse array");
+}
+

=== added file 'testsuite/network.all/netstream.as'
--- a/testsuite/network.all/netstream.as        1970-01-01 00:00:00 +0000
+++ b/testsuite/network.all/netstream.as        2009-04-01 02:49:29 +0000
@@ -0,0 +1,28 @@
+
+//Open a new NetConnection to attach a remote object
+var nc = new NetConnection();
+
+//RTMP=(Real-Time Messaging Protocol) 
+//rtmp://host[:port]/appName[/instanceName]
+
+//nc.connect("http://localhost";);
+nc.connect("rtmp://localhost/oflaDemo");
+
+//Declare a Streaming Object called NetStream
+var ns = new NetStream(nc);
+ns.setBufferTime(10);
+
+// Attach de stream to the video
+// ns.attachVideo();
+
+//Push Play on the movie
+// NewStream.attachAudio(Microphone.get());
+// NewStream.attachVideo(Camera.get()); 
+
+// this is a url variable passed in the object call
+//ns.publish(stream);
+ns.play("DarkKnight.flv");
+
+note(dumpObject(ns));
+
+           

=== added file 'testsuite/network.all/network.exp'
--- a/testsuite/network.all/network.exp 1970-01-01 00:00:00 +0000
+++ b/testsuite/network.all/network.exp 2009-04-05 21:04:55 +0000
@@ -0,0 +1,281 @@
+# Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+load_lib "dejagnu.exp"
+
+# If tracing has been enabled at the top level, then turn it on here
+# too.
+if $tracelevel {
+    strace $tracelevel
+}
+
+# After these many seconds of execution the test script is aborted with a 
failure.
+# This is to handle deadlocks. We don't reset the timeout when a match is
+# found to avoid hanging in case of a testcase sending matches in an infinite 
loops.
+# (not unlikely as it seems, think about flash movies...)
+#
+# Expressed in seconds.
+#
+set timeout 100
+set file all
+set params ""
+
+# specify a default name and port for the RTMPT (AMF over HTTP) tests
+set http_hostname ""
+set http_portnum ""
+set http_dead false
+
+# specify a default name and port for the RTMP  tests
+set rtmp_hostname ""
+set rtmp_portnum ""
+set rtmp_dead false
+
+#
+# These are lists of hostname and port combinations 'probed'
+# to see if there is a service for that connection. Later each
+# is probed to see if there is a functioning service for that
+# port on the specified host
+#
+
+array set http_targets {
+    {0} {localhost    4080}
+    {1} {localhost    5080}
+    {2} {gnashdev.org 5080}
+    {3} {gnashdev.org 4080}
+}
+
+array set rtmp_targets {
+    {0} {localhost    1935}
+    {1} {localhost    5935}
+    {2} {gnashdev.org 1935}
+    {3} {gnashdev.org 5935}
+}
+
+#
+# Probe a hostname:port usig netcat to see if there is a service available
+#
+proc probe { host port } {
+    verbose "Trying to probe $host:$port to see if there is an available 
service"
+    global server_dead 
+    spawn -noecho nc -zv $host $port
+    set nid $spawn_id
+    global timeout
+
+    expect {
+       "$host * open" {
+           verbose "Got probe response, $host is alive on port $port..." 2
+           set targets(host.name) $host
+           set targets(host.port) $port
+       }
+       "Connection to *port * succeeded" {
+           verbose "Got probe response, $host is alive on port $port..." 2
+           set targets(host.name) $host
+           set targets(host.port) $port
+       }
+       "packets transmitted, 1 received" {
+           verbose "Got probe response, $host is alive on port $port..." 2
+       }
+       eof {
+           verbose "Probe all done, no service..." 2
+           return false
+       }
+       timeout {
+           verbose "Probe still running after ${timeout} seconds, killing it 
(deadlock?)" 2
+           catch close
+           return false
+       }
+    }
+
+    return true
+}
+
+
+proc checkhosts { targets } {
+    global http_hostname
+    global http_portnum
+    global rtmp_hostname
+    global rtmp_portnum
+
+    # Make sure we can access the resource on the specified host, which won't 
always
+    # be default.
+    foreach {host port} targets {
+       if { [probe $host $port] != true } {
+           verbose "$x is Dead!"
+       }
+    }
+}
+
+# See if the specified hosts are alive
+#checkhosts [array get http_targets]
+#checkhosts rtmp_targets
+foreach {index target} [array get http_targets] {
+    set host [lindex $target 0]
+    set port [lindex $target 1]
+     if { [probe $host $port] == true } {
+       set http_hostname $host
+       set http_portnum $port
+       verbose "$host:$port has HTTP service"
+       break
+     } else {
+       verbose "$host:$port has no HTTP service attached!"
+     }
+}
+
+# Make sure somebody responded, or we can't run the tests
+if {[string length $http_hostname] == 0} {
+    perror "No HTTP servers appear to be alive"
+    set http_dead true
+    exit
+}
+
+foreach {index target} [array get rtmp_targets] {
+    set host [lindex $target 0]
+    set port [lindex $target 1]
+     if { [probe $host $port] == true } {
+       set rtmp_hostname $host
+       set rtmp_portnum $port
+       verbose "$host:$port has RTMP service"
+       break
+     } else {
+       verbose "$host:$port has no RTMP service attached!"
+     }
+}
+if {[string length $rtmp_hostname] == 0} {
+    perror "No RTMP servers appear to be alive"
+    set rtmp_dead true
+    exit
+}
+
+global env
+set env(LANG) en_US.UTF-8
+set env(LANGUAGE) en_US.UTF-8
+set env(LC_ALL) en_US.UTF-8
+
+# Look fo rthe gprocess utility we in this build tree
+set gproc [lookfor_file $objdir utilities/gprocessor]
+set goptions "-vv"
+verbose "Starting gprocessor \"$gproc $goptions\" for testing"
+
+set test_targets(http.swf) [list $http_hostname $http_portnum]
+set test_targets(rtmp.swf) [list $rtmp_hostname $rtmp_portnum]
+
+# testcases is set by the Makefile in the site.exp data file.
+foreach file $testcases {
+
+    verbose "Running test $file"
+
+    # spawn the executable and look for the DejaGnu output messages from the
+    # test case.
+
+    # this version of the call allows use of 'wait' to check return code
+    # -open [open "|cmd" "r"] doesn't work for that
+  
+    set host [lindex $test_targets($file) 0]
+    set port [lindex $test_targets($file) 1]
+    set params "-P flashVars=\"hostname=$host,port=$port\""
+
+    # Ignore SIGHUP or we'd get a lot of them on Debian stable
+    verbose "Starting gprocessor $gproc $goptions $file $params for testing"
+    spawn -noecho -ignore SIGHUP $gproc $goptions $file $params
+
+    expect {
+       -re "^\[^\n]*NOTE:\[^\n]*\n" {
+           regsub ".*NOTE: " $expect_out(0,string) "" output
+           set output [string range $output 0 end-2]
+           verbose "${file} $output" 
+            # notes tipically come from the test runner, so we'll trust it to 
mean 
+            # things are someone not too bad...
+           # -continue_timer
+           exp_continue
+       }
+       -re "^\[^\n]*XPASSED:\[^\n]*\n" {
+           regsub ".*XPASSED: " $expect_out(0,string) "" output
+           set output [string range $output 0 end-2]
+           xpass "${file}: $output"
+           exp_continue -continue_timer
+       }
+       -re "^\[^\n]*PASSED:\[^\n]*\n" {
+           regsub ".*PASSED: " $expect_out(0,string) "" output
+           set output [string range $output 0 end-2]
+           pass "${file}: $output"
+           exp_continue -continue_timer
+       }
+       -re "^\[^\n]*XFAILED:\[^\n]*\n" {
+           regsub ".*XFAILED: " $expect_out(0,string) "" output
+           set output [string range $output 0 end-2] 
+           xfail "${file}: $output"
+           exp_continue -continue_timer
+       }
+       -re "^\[^\n]*FAILED:\[^\n]*\n" {
+           regsub ".*FAILED: " $expect_out(0,string) "" output
+           set output [string range $output 0 end-2] 
+           fail "${file}: $output"
+           exp_continue -continue_timer
+       }
+       -re "^\[^\n]*UNTESTED:\[^\n]*\n" {
+           regsub ".*UNTESTED: " $expect_out(0,string) "" output
+           set output [string range $output 0 end-2]
+           untested "${file}: $output"
+           exp_continue -continue_timer
+       }
+       -re "^\[^\n]*UNRESOLVED:\[^\n]*\n" {
+           regsub ".*UNRESOLVED: " $expect_out(0,string) "" output
+           set output [string range $output 0 end-2]
+           unresolved "${file}: $output"
+           exp_continue -continue_timer
+       }
+       -re "^\[^\n]*\n" {
+            # just remove non-matching lines!
+            exp_continue -continue_timer
+       }
+       eof {
+           #       unresolved "${file} died prematurely"
+           #       catch close
+           #       return "${file} died prematurely"
+       }
+       timeout {
+               fail "Test case ${file} still running after ${timeout} seconds, 
killing it (deadlock?)"
+               catch close
+               continue;
+       }
+   }
+
+       # wait for the process to coplete to
+       # check return code
+       set retcode [wait]
+
+       # debugging
+       #set i 0; foreach j $retcode { print "${file} wait($i) $j"; incr i }
+
+       # This snippet catches segfaults and aborts.
+       # Would also catch SIGHUP, but we're ignoring them
+       # as on Debian Stable we unexpectedly get them for no apparent reason
+       #
+       if { [ llength $retcode ] > 5 } {
+               fail "${file} died prematurely ([lindex $retcode 6])"
+       }
+
+       # This snippet catches non-zero returns
+       if { [ lindex $retcode 3 ] != 0 } {
+               fail "${file} exited with non-zero code ([lindex $retcode 3])"
+       }
+
+
+    # force a close of the executable to be safe.
+#    catch close
+}
+
+

=== added file 'testsuite/network.all/remoting.README'
--- a/testsuite/network.all/remoting.README     1970-01-01 00:00:00 +0000
+++ b/testsuite/network.all/remoting.README     2009-04-01 02:49:29 +0000
@@ -0,0 +1,51 @@
+Test for remoting trough NetConnection and http.
+
+SERVER
+------
+
+The server part of the test is a PHP file.
+There's one copy available at
+http://www.gnashdev.org/testcases/remoting.php
+
+If you want to test offline you can copy remoting.php
+somewhere in your web server directories and specify 
+the base url at configure time, for example:
+
+ $ ./configure --enable-http-testsuite=http://localhost/gnashtests/
+ $ cp remoting.php /var/www/gnashtests/
+
+Note that in order for the php file to work you might need to 
+add the following line to your .htaccess file:
+
+  php_flag always_populate_raw_post_data on in place
+
+Also, if you run the client (remote.swf) from a different domain
+then the one the server is on, you'll need a crossdomain.xml file
+on the web root of the server.
+
+The most open version of a crossdomain.xml only contains this line:
+
+ <cross-domain-policy> <allow-access-from domain="*" /> </cross-domain-policy>
+
+CLIENT
+------
+
+The client part is an SWF, compiled by Ming from remoting.as.
+The SWF will embed the url to the remoting.php file.
+This is for convenience to allow testing it with the proprietary
+player to verify it expects the correct behaviour.
+
+The embedded url is set at configure time (--enable-http-testsuite)
+but can be overridden by a query string, for example:
+
+    $ gnash -v remoting.swf?url=remoting.php # relative url
+
+The generated remoting.swf is set to have "network" sandbox so
+you'll be able to run it from the filesystem and have it access
+network resources (as long as crossdomain.xml file is in place).
+
+Note that the proprietary player doesn't let you specify a query
+string for a filesystem-loaded file, so use --enable-http-testsuite
+to specify the embedded (default) url.
+
+

=== added file 'testsuite/network.all/rtmp.as'
--- a/testsuite/network.all/rtmp.as     1970-01-01 00:00:00 +0000
+++ b/testsuite/network.all/rtmp.as     2009-04-01 22:54:07 +0000
@@ -0,0 +1,544 @@
+// This test relies on a default deploy of red5 on localhost
+//
+// Build with:
+//     makeswf -n network -o red5test.swf ../Dejagnu.swf red5test.as 
../actionscript.all/dejagnu_so_fini.as
+// Run with:
+//     firefox red5test.swf
+// Or:
+//     gnash red5test.swf
+//
+//
+
+#define info _root.note
+#define note _root.note
+#define fail_check _root.fail
+#define pass_check  _root.pass
+#define xfail_check _root.xfail
+#define xpass_check _root.xpass
+
+note("SWF" + OUTPUT_VERSION + " - " + System.capabilities.version + "\n");
+rcsid="red5test.as - <bzr revno here>";
+
+#include "../actionscript.all/check.as"
+#include "../actionscript.all/utils.as"
+#include "../actionscript.all/dejagnu.as"
+
+stop();
+
+endOfTest = function()
+{
+       //note("END OF TEST");
+//        check_totals(9);
+    totals();
+    play();
+};
+
+// -P FlashVars='hostname=localhost,rtmptport5080=rtmpport=1935'
+if (hostname == undefined) {
+    hostname="localhost";
+    note("No hostname specified, defaulting to "+hostname);
+}
+
+if (rtmptport == undefined) {
+    rtmptport = 5080;
+    note("No RTMPT port specified, defaulting to "+rtmptport);
+}
+
+if (rtmpport == undefined) {
+    rtmpport = 1935;
+    note("No RTMP port specified, defaulting to "+rtmpport);
+}
+
+nc.statuses = new Array();
+nc.onStatus = function()
+{
+    note('NetConnection.onStatus called with args: ');
+};
+
+function ResultHandler() {
+    this.onResult = function(result) {
+        note('default onResult called with args: '+dumpObject(arguments));
+    };
+//     this.onCustom = function(result) {
+//         note('default onCustom called with args: '+dumpObject(arguments));
+//     };
+//     this.onDebugEvents = function(result) {
+//         note('default onDebugEvents called with args: 
'+dumpObject(arguments));
+//     };
+//     this.onStatus = function(result) {
+//     note("default onStatus called with args: "+dumpObject(arguments));
+//     };
+};
+
+//
+// do the same thing for RTMP
+//
+ncrtmp = new NetConnection;
+ncrtmp.statuses = new Array();
+ncrtmp.onStatus = function()
+{
+    note('NetConnection.onStatus called with args: '+dumpObject(arguments));
+    
+//     lastStatusArgs = ncrtmp.statuses[ncrtmp.statuses.length-1];
+//     if ((lastStatusArgs[0].level == "status") && (lastStatusArgs[0].code == 
"NetConnection.Connect.Success")) {
+//         pass("RTMP connection - status Success");
+//     } else {
+//         fail("RTMP connection - status Success");
+//     }
+};
+
+rtmpuri = "rtmp://"+hostname+":"+rtmpport+"/echo";
+note("Connecting to "+rtmpuri);
+ncrtmp.connect(rtmpuri);
+
+// The network connection is not opened at connect() time, but when
+// the first call() is made.
+if (ncrtmp.isConnected == false) {
+    pass("RTMP connection - isConnected");
+} else {
+    fail("RTMP connection - isConnected");
+}
+
+ncrtmp.onResult = function()
+{
+    note('NetConnection.onResult called with args: '+dumpObject(arguments));
+    if (nc.isConnected == true) { // now it is connected
+        pass("HTTP connection - status isConnected");
+    } else {
+        fail("HTTP connection - status isConnected");
+    }
+    if ((lastStatusArgs[0].level == "status") && (lastStatusArgs[0].code == 
"NetConnection.Connect.Success")) {
+        pass("HTTP connection - status Success");
+    } else {
+        fail("HTTP connection - status Success");
+    }
+};
+
+o=new ResultHandler();
+ncrtmp.onResult = function()
+{
+    note("Got a result back from the  RTMP server.");
+    
+    // now it is connected
+    if ((ncrtmp.isConnected == true) && (ncrtmp.statuses.length == 1)) {
+        pass("RTMP connection - result");
+    } else {
+        fail("RTMP connection - result");        
+    }
+};
+
+// This call starts the actual network connection
+result1=false;;
+o.onResult = function()
+{
+    note("Got a null result back from the RTMP server."+dumpObject(arguments));
+    note(arguments[0]);
+    if (arguments.length == 1) {
+       if (arguments[0] == null) {
+           result1=true;
+       }
+    }
+};
+ncrtmp.call("echo", o, null);
+
+// The network connection is not opened at connect() time, but should
+// be now that we've made a ::call().
+if (ncrtmp.isConnected == true) {
+    pass("RTMP connection - isConnected");
+} else {
+    fail("RTMP connection - isConnected");
+}
+
+// // Empty String
+// result3=false;
+// tstr = new String();
+// o=new ResultHandler();
+// o.onResult = function()
+// {
+//     note("Got a string result back from the RTMP 
server."+dumpObject(arguments));
+//     if (arguments.length == 1) {
+//     if (arguments[0].length == 0) {
+//         result3 = true;
+//     }
+//     }
+// };
+// ncrtmp.call("echo", o, tstr);
+
+// Hello World!
+result4=false;
+tstr2 = "Hello World!";
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a string result back from the RTMP 
server."+dumpObject(arguments));
+//     note("ARG4 is: " +dumpObject(arguments[0]));
+    str = arguments[0].toString();
+    if (arguments.length == 1) {
+       if ((arguments[0].length == 12)
+           && (arguments[0].toString() == "Hello World!")) {
+           result4 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, tstr2);
+
+// test1,test2,test3,test4
+
+// Number 0
+result5=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical 0 result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == 0) {
+           result5 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, 0);
+
+// Number 1
+result6=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical 1 result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == 1) {
+           result6 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, 1);
+
+// Number -1
+result7=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical -1 result back from the RTMP 
server."+dumpObject(arguments));
+    if ((arguments.length == 1)) {
+       note("FIXME: "+arguments[0].to_number());
+       result7 = true;
+    }
+};
+ncrtmp.call("echo", o, -1);
+
+// Number 256
+result8=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical 256 result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == 256) {
+           result8 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, 256);
+
+// Number -256
+result9=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical -256 result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == -256) {
+           result9 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, -256);
+
+// Number 65536
+result10=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical 65536 result back from the  
RTMPserver."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == 65536) {
+           result10 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, 65536);
+
+// Number -65536
+result11=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical -65536 result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == -65536) {
+           result11 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, -65536);
+
+// 1.5
+result12=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical 1.5 result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == 1.5) {
+           result12 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, 1.5);
+
+// -1.5
+result13=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical -1.5 result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == -1.5) {
+           result13 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, -1.5);
+
+// Number NaN
+result14=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical NaN result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == NaN) {
+           result14 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, NaN);
+
+// Number Infinity
+result15=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got an numerical infinity result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == infinity) {
+           result15 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, infinity);
+
+// Number -Infinity
+result16=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a numerical -infinity result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0] == -infinity) {
+           result16 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, -infinity);
+
+// o=new ResultHandler();
+// o.onResult = function()
+// {
+//     note("Got a result back from the server.");
+//     check_equals(arguments.toString(), '1,two,true,4,5,6');
+//     endOfTest();
+// };
+// ncrtmp.call("echo", o, 1, 'two', true, [4,5,6]);
+
+// o=new ResultHandler();
+// o.onResult = function()
+// {
+//     note("Got a result back from the server.");
+//     check_equals(arguments.toString(), '1,2,3');
+// };
+// ncrtmp.call("echo", o, 1, 2, 3);
+
+
+// Test empty array
+tar = new Array();
+result17=false;
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got an empty array result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0].length == 0) {
+           result17 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, tar);
+
+// Test array with only one item
+result18=false;
+tar = new Array();
+tar.push(1);
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a single item array result back from the RTMP 
server."+dumpObject(arguments));
+    if (arguments.length == 1) {
+       if (arguments[0][0] == 1) {
+           result18 = true;
+       }
+    }
+};
+ncrtmp.call("echo", o, tar);
+
+// Test array with multiple items
+result19=false;
+tar = new Array();
+tar.push(1);
+tar.push(2);
+tar.push(3);
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got an 3 item array result back from the RTMP 
server."+dumpObject(arguments));
+    if ((arguments.length == 1) && (arguments[0].length == 3)) {
+       if ((arguments[0][0] == 1) && (arguments[0][1] == 2) && 
(arguments[0][2] == 3))  {
+           result19 = true;
+       }
+    }
+//    note(arguments[0].toString());
+//    check_equals(arguments[0].toString(), "1.2.3");
+};
+ncrtmp.call("echo", o, tar);
+
+// Test sparse array
+result20=false;
+tar2 = new Array();
+tar2.push(1);
+tar2.push();
+tar2.push();
+tar2.push();
+tar2.push(5);
+o=new ResultHandler();
+o.onResult = function()
+{
+    note("Got a sparse result back from the RTMP 
server."+dumpObject(arguments));
+    if ((arguments.length == 1) && (arguments[0].length == 2)) {
+       if ((arguments[0][0] == 1) && (arguments[0][1] == 5))  {
+           result20 = true;
+       }   
+    }
+//    check_equals(arguments.toString(), "1..,,5");
+};
+ncrtmp.call("echo", o, tar2);
+
+if (result1) {
+    pass("RTMP: Echo NULL Object");
+} else {
+    fail("RTMP: Echo NULL Object");
+}
+
+if (result3) {
+    pass("RTMP: Echo empty String");
+} else {
+    fail("RTMP: Echo empty String");
+}
+
+if (result4) {
+    pass("RTMP: Echo short String");
+} else {
+    fail("RTMP: Echo short String");
+}
+
+if (result5) {
+    pass("RTMP: Echo Number 0");
+} else {
+    fail("RTMP: Echo Number 0");
+}
+
+if (result6) {
+    pass("RTMP: Echo Number 1");
+} else {
+    fail("RTMP: Echo Number 1");
+}
+
+if (result7) {
+    pass("RTMP: Echo Number -1");
+} else {
+    fail("RTMP: Echo Number -1");
+}
+if (result8) {
+    pass("RTMP: Echo Number 256");
+} else {
+    fail("RTMP: Echo Number 256");
+}
+if (result9) {
+    pass("RTMP: Echo Number -256");
+} else {
+    fail("RTMP: Echo Number -256");
+}
+if (result10) {
+    pass("RTMP: Echo Number 65536");
+} else {
+    fail("RTMP: Echo Number 65536");
+}
+if (result11) {
+    pass("RTMP: Echo Number -65536");
+} else {
+    fail("RTMP: Echo Number -65536");
+}
+if (result12) {
+    pass("RTMP: Echo Number 1.5");
+} else {
+    fail("RTMP: Echo Number 1.5");
+}
+if (result13) {
+    pass("RTMP: Echo Number -1.5");
+} else {
+    fail("RTMP: Echo Number -1.5");
+}
+if (result14) {
+    pass("RTMP: Echo Number NaN");
+} else {
+    fail("RTMP: Echo Number NaN");
+}
+if (result15) {
+    pass("RTMP: Echo Number Infinity");
+} else {
+    fail("RTMP: Echo Number Infinity");
+}
+if (result16) {
+    pass("RTMP: Echo Number -Infinity");
+} else {
+    fail("RTMP: Echo Number -Infinity");
+}
+
+if (result17) {
+    pass("RTMP: Echo empty array");
+} else {
+    fail("RTMP: Echo empty array");
+}
+if (result18) {
+    pass("RTMP: Echo 1 item array");
+} else {
+    fail("RTMP: Echo 1 item array");
+}
+if (result19) {
+    pass("RTMP: Echo 3 item array");
+} else {
+    fail("RTMP: Echo 3 item array");
+}
+if (result20) {
+    pass("RTMP: Echo sparse array");
+} else {
+    fail("RTMP: Echo sparse array");
+}


reply via email to

[Prev in Thread] Current Thread [Next in Thread]