# File: README
[ "README", "lib/asp/server.rb", "lib/asp/application.rb", "lib/asp/request.rb", "lib/asp/response.rb", "lib/asp/session.rb", nil].each do
README / Wed Mar 01 12:37:22 CET 2006



Ruby-ASP provides an Active Server Pages port to the Apache Web Server with Ruby scripting only, and enables developing of dynamic web applications with session management and embedded Ruby code.


Copyright (C) 2003, 2004, 2005 Gregoire Lejeune <gregoire dot lejeune at free dot fr>

Ruby/ASP is freely distributable according to the terms of the GNU General Public License (see the file ‘COPYING’).

This program is distributed without any warranty. See the file ‘COPYING’ for details.


Last version

Old versions

CVS access

The CVS repository is available at rubyforge.org. You can browse it or access it via anonymous access :

        cvs -d :pserver:anonymous@rubyforge.org:/var/cvs/ruby-asp login
        cvs -d :pserver:anonymous@rubyforge.org:/var/cvs/ruby-asp checkout ruby-asp

See this page for more informations



Ruby/Asp require Ruby/XSLT, mod_ruby and (of course) Ruby ;)

Note: if you can’t install mod_ruby, you can use Ruby/ASP in a CGI mode. For more details, see CGI section.


Install Ruby/Asp like this:

        $ tar zxvf ruby-asp_x.y.z.tar.gz
        $ cd ruby-asp
        $ ruby install.rb config
        $ ruby install.rb setup
        # ruby install.rb install

Use Ruby/Asp

Add these lines to httpd.conf or in a .htaccess file

        RubySetEnv Global /var/www/global-asa
        RubyRequire apache/aspruby-run
        <Files ~ (.asp)>
          SetHandler ruby-object
          RubyHandler Apache::AspRun.instance


Global : Global is the nerve center of a Ruby/Asp application, in which the global.asa may reside defining the web application’s event handlers.

MailHost : The mail host is the smtp server that the below Mail config directives will use when sending their emails. Default : localhost.

MailPort : SMTP port. Default : 25.

MailErrorsFrom : Default NONE, set this to specify the default mail address placed in the From: mail header for server errors.

MailErrorsTo : No default, if set, ASP server errors, error code 500, that result while compiling or running scripts under Ruby/Asp will automatically be emailed to the email address set for this config.

ErrorFile : URI for error redirection.

StateDir : State files for ASP application go to this directory. Default : /tmp


Ruby/ASP "CGI mode" has been developped for "mod_ruby-less" architectures !

Standalone CGI Mode, without mod_ruby

As of version 0.2.8, Ruby/ASP scripts may be run as standalone CGI scripts without mod_ruby being loaded into Apache. Work to date has been done with mod_cgi scripts under Apache on a Unix and Win32 platforms.


First install Ruby/Asp, see Install section for more details. Then copy the ruby-asp.rb script in your cgi-bin directory :

        $ cp /usr/bin/ruby-asp.rb /path/to/cgi-bin/ruby-asp.cgi

or create a symblink :

        $ ln -s /usr/bin/ruby-asp.rb /path/to/cgi-bin/ruby-asp.cgi

Add these lines to httpd.conf or in a .htaccess file

        AddType application/x-httpd-asp-cgi .asp
        Action application/x-httpd-asp-cgi /cgi-bin/ruby-asp.cgi

The ruby-asp.rb script is a cgi wrapper that sets up the Ruby/ASP environment in lieu of the normal mod_ruby handler request. Because there is no Apache::Table object available under mod_cgi, the ruby-asp.rb script will load a asp.conf file that may define a hash Config of data.

So, a trivial asp.conf file might look like:

        Config = {
          "StateDir"       => "/tmp/ruby_asp",
          "Global"         => "global-asa",
          "MailHost"       => "smtp"
          "MailPort"       => "25"
          "MailErrorsFrom" => "www-error@webtime-project.net"
          "MailErrorsTo"   => "greg@webtime-project.net"
          "ErrorFile"      => "error.html"

See Install section for more details on configuration.


The ASP platform allows developers to create Web Applications. In fulfillment of real software requirements, ASP allows event-triggered actions to be taken, which are defined in a global.asa file. The global.asa file resides in the Global directory, defined as a config option, and may define the following actions:

  • script_OnStart : Beginning of Script execution
  • script_OnEnd : End of Script execution
  • application_OnStart : Beginning of Application
  • application_OnEnd : End of Application
  • session_OnStart : Beginning of user Session.
  • session_OnEnd : End of user Session.

These actions must be defined in the $Global/global.asa file as subroutines, for example:

        def session_OnStart
          $Application[$Session.sessionID] = started;

Sessions are easy to understand. When visiting a page in a web application, each user has one unique $Session. This session expires, after which the user will have a new $Session upon revisiting.

A web application starts when the user visits a page in that application, and has a new $Session created. Right before the first $Session is created, the $Application is created. When the last user $Session expires, that $Application expires also. For some web applications that are always busy, the application_OnEnd event may never occur.

script_OnStart & script_OnEnd

The script events are used to run any code for all scripts in an application defined by a global.asa. Often, you would like to run the same code for every script, which you would otherwise have to add by hand, or add with a file include, but with these events, just add your code to the global.asa, and it will be run.

There is one caveat. Code in script_OnEnd is not guaranteed to be run when $Response.end() is called, since the program execution ends immediately at this event.


Triggered by the beginning of a user’s session, session_OnStart gets run when the user’s acces the $Session object for the first time.

The session_OnStart is particularly useful for caching database data, and avoids having the caching handled by clumsy code inserted into each script being executed.


Triggered by a user session ending, session_OnEnd can be useful for cleaning up and analyzing user data accumulated during a session.

Sessions end when the session timeout expires. The timing of the session_OnEnd occur immediately after the session times out.

Thus I would not put anything mission-critical in the session_OnEnd, just stuff that would be nice to run whenever it gets run.



This event marks the beginning of an ASP application, and is run just before the session_OnStart of the first Session of an application. This event is useful to load up $Application with data that will be used in all user sessions.



The end of the application is marked by this event, which is run after the last user session has timed out for a given ASP application.

Custom Tags with XMLSubsMatch

Before XML, there was the need to make HTML markup smarter. Ruby/ASP gives you the ability to have a Ruby subroutine handle the execution of any predefined tag, taking the tag descriptors, and the text contained between, as block of the subroutine. This custom tag technology can be used to extend a web developer’s abilities to add dynamic pieces without having to visibly use <% %> style code entries.

So, lets say that you have a table that you want to insert for an employee with contact info and the like, you could set up a tag like:

        <my:new-employee name="Jane" last="Doe" phone="555-2222">
          Jane Doe has been here since 1998.

Any colons, ’:’, in the XML custom tag will turn into ’::’, a Ruby module separator, so the my:employee tag would translate to the my::employee subroutine, or the employee subroutine in the my module. Any dash "-" will also be translated to an underscore "_", as dash is not valid in the names of Ruby subroutines.

Then you would create the my::employee subroutine in the my ruby module or whereever like so:

        module My
          def My::test( h )
            print "<B>In My::Test</B><BR>"
            yield if block_given?
            h.each_pair { |k,v|
              print "#{k} => #{v}<BR>"

Though XML purists would not like this custom tag technology to be related to XML, the reality is that a careful site engineer could render full XML documents with this technology, applying all the correct styles that one might otherwise do with XSLT.

Custom tags defined in this way can be used as XML tags are defined with both a body and without as it


and just

        <my:new-employee />

These tags are very powerful in that they can also enclose normal ASP logic, like:

          <!-- normal ASP logic -->
          <% birthday = Time::new %>
          <!-- ASP inserts -->
          This employee has been online for <%= Integer(rand()*600)+1 %>
          seconds, and was born near <%= birthday %>.

For an example of this custom XML tagging in action, please check out the tests/subsmatch.asp script.


Ruby/ASP support SSI since version 0.4.0 by using the Ruby/SSI module.