Ruby and the Web Server

 
   

Ruby Way
By Hal Fulton
Slots : 1.0
Table of Contents
 


Oh, what a tangled web we weave…!

Sir Walter Scott

Various tools and libraries are available for the Ruby Web developer; standalone Web servers, tools that process and/or generate HTML and XML, and server add-ons and CGI libraries. Most of these are written in pure Ruby, although some have been written as extensions, usually for the sake of speed.

We can't cover everything here. However, we will present a good overview of Ruby and Web development.

Self-Contained Web Servers

Some developers in the Ruby community have implemented Web servers in Ruby. Of course, a fair question would be: Why would we be concerned with writing a new Web server? Aren't there plenty of good ones in existence, such as Apache?

There are several situations in which you might actually want your own proprietary Web server. The first is to handle Web pages in a specialized way, such as sacrificing functionality for speed.

Second, you might also want to experiment with the behavior of the server and its interaction with external code such as CGIs. You might want to play with your own ideas for creating an application server or a server-side development environment. We all know that Ruby is a fun language for software experimentation.

Third, you might want to embed a Web server inside another application. This possibility is sometimes exploited by developers who want to expose the functionality of a software system to the outside world; the HTTP protocol is well-defined and simple, and Web browsers that serve as clients are everywhere. This trick can even be used as a remote debugging tool, assuming that the system updates its internal state frequently and makes it available to the embedded server.

With these ideas in mind, let's look at what is available in the Ruby arena as far as Web servers are concerned. The Ruby Application Archive has at least four such entries.

The first is httpd by Michel van de Ven. This is a basic server that supports CGI; it is a good introduction to the functionality of a Web server. It is also an illustration of the power of Ruby because the entire piece of code is barely 250 lines. The license is GPL, so you can not only learn from the code, but you can actually re-use it, subject to certain restrictions.

Another server is Michael Neumann's httpserv. This is a multi-threaded server that can handle CGI and is known to work under both Unix and Windows. This server also integrates with the IOWA package (see the RAA), and includes a slightly modified iowa.cgi file.

Another interesting piece of code is wwwd, by Kengo Nakajima. This is billed by the author as "the fastest Web server in the world." It takes an interesting approach to achieve this speed. First, all the files are stored in memory, making disk accesses unnecessary. Second, because the overhead of threading and forking would become significant, it doesn't do any forking or use threads. A downside is that it doesn't support CGI (although you can get a similar effect by using Ruby scripts). Overall, it is designed for Web sites that are very small but heavily accessed.

There is also wwwsrv by Yoshinori Toki. This is a new package at the time of this writing, and has no English documentation. But it does already have usable CGI and SSI features, and it looks promising in general.

Using Embedded Ruby

First of all, let's dispel any confusion over terminology. We're not talking about embedding a Ruby interpreter in an electronic device like a TV or a toaster. We're talking about embedding Ruby code inside text.

Second of all, we'll note that there is more than one scheme for embedding Ruby code in text files. Here we only discuss the most common tool, which is eruby (created by Shugo Maeda).

Why do we mention such a tool in connection with the Web? Obviously, it's because the most common form of text in which we'll embed Ruby code is HTML (or XML).

Having said that, it's conceivable that there might be other uses for eruby. Perhaps it could be used in an old-fashioned text-based adventure game; or in some kind of mail-merge utility; or as part of a cron job to create a customized message-of-the-day file (/etc/motd) every night at midnight. Don't let your creativity be constrained by our lack of imagination. Feel free to dig up new and interesting uses for eruby, and share them with the rest of us. Most of the examples we give here are very generic (and thus are very contrived); they don't have much to do with HTML specifically.

The eruby utility is simply a filter or preprocessor. A special notation is used to delimit Ruby code, expressions, and comments; all other text is simply passed through "as is."

The symbols are used to mark the pieces of text that will be treated specially. There are three forms of this notation, varying in the first character inside the "tag."

If it is an equal sign (=), the tag is treated as a Ruby expression that is evaluated; the resulting value is inserted at the current location in the text file. Here is a sample text file:

 

 This is <%= "ylno".reverse %> a test. Do <%= "NOT".downcase %> be alarmed. 

Assuming that the file for this example is called myfile.txt, we can filter it in this way:

 

 eruby myfile.txt 

The output, by default written to standard output, will look like this:

 

 This is only a test. Do not be alarmed. 

We can also use the character # to indicate a comment:

 

 Life <%# so we've heard %> is but a dream. 

As you'd expect, the comment is ignored. The preceding line will produce this line of output:

 

 Life  is but a dream. 

Any other character following the percent sign will be taken as the first character of a piece of Ruby code, and its output (not its evaluated value) will be placed into the text stream. For readability, we recommend using a blank space here, though eruby does not demand it.

In this example, the tag in the first line of text does not insert any text (because it doesn't produce any output). The second line works as expected.

 

 The answer is <% "42" %>. Or rather, the answer is <% puts "42" %>. 

So the output would be:

 

 The answer is . Or rather, the answer is 42. 

The effect of the Ruby code is cumulative. For example, a variable defined in one tag can be used in a subsequent tag.

 

 <% x=3; y=4; z=5 %> Given a triangle of sides <%=x%>, <%=y%>, and <%=z%>, we know it is a right triangle because <%= x*x %> + <%= y*y %> = <%= z*z %>. 

The spaces we used inside the tags in the last line are not necessary, but they do increase readability. The output will be

 

 Given a triangle of sides 3, 4, and 5, we know it is a right triangle because 9 + 16 = 25. 

Try putting a syntax error inside a tag. You'll find that eruby has very verbose reporting; it actually prints out the generated Ruby code and tells us as precisely as it can where the error is.

What if we want to include one of the "magic" strings as a literal part of our text? You might be tempted to try a backslash to escape the characters, but this won't work. We recommend a technique like the following:

 

 There is a less-than-percent <%="<%"%> on this line and a percent-greater-than <%="%"+">"%> on this one. Here we see <%="<%="%> and <%="<%#"%> as well. 

The output then will be

 

 There is a less-than-percent <% on this line and a percent-greater-than %> on this one. Here we see <%= and <%# as well. 

Note that it's a little easier to embed an opening symbol than a closing one. This is because they can't be nested, and eruby is not smart enough to ignore a closing symbol inside a string.

Of course, eruby does have certain features that are tailored to HTML. The flag -M can be used to specify a mode of operation; the valid modes are f, c, and n, respectively.

The f mode (filter) is the default, which is why all our previous examples worked without the -Mf on the command line. The -Mc option means CGI mode; it prints all errors as HTML. The -Mn option means NPH-CGI mode ("no-parse-headers"); it outputs extra HTML headers automatically. Both CGI and NPH-CGI modes set $SAFE to be 1 for security reasons (assuming that the application is a CGI and thus may be invoked by a hostile user). The -n flag (or the equivalent noheader) will suppress CGI header output.

It's possible to set up the Apache Web server to recognize embedded Ruby pages. You do this by associating the type application/x-httpd-eruby with some extension (.rhtml being a logical choice) and defining an action that associates this type with the eruby executable. For more information, consult the Apache documentation.

Using mod_ruby

Typically when a CGI script is written in an interpreted language, an instance of the interpreter is launched with every invocation of the CGI. This can be expensive in terms of server utilization and execution time.

The Apache server solves this problem by allowing loadable modules that in effect attach themselves to the server and become part of it. Such a module is loaded dynamically as needed, and is shared by all the scripts that depend on it.

The mod_ruby package (available from the Ruby Application Archive) is such a module. Support for Apache 2.0 is not yet available, but it is in the works.

The mod_ruby package implements several Apache directives. At the present time, these are as follows:

  • RubyRequire Specifies one or more libraries needed.

  • RubyHandler Specifies a handler for ruby-object.

  • RubyPassEnv Specifies names of environment variables to pass to scripts.

  • RubySetEnv Sets environment variables.

  • RubyTimeOut Specifies a timeout value for Ruby scripts.

  • RubySafeLevel Sets the $SAFE level.

  • RubyKanjiCode Sets the Ruby character encoding.

The software also provides Ruby classes and modules for interacting with Apache. The Apache module (using module here in the Ruby sense) has a few module functions as server_version and unescape_url; it also contains the Request and Table classes.

Apache::Request is a wrapper for the request_rec data type, defining methods such as request_method, content_type, readlines, and more. The Apache::Table class is a wrapper for the table data type, defining methods such as get, add, and each.

Extensive instructions are available for compiling and installing the mod_ruby package. Refer to its accompanying documentation (or the equivalent information on the Web).

We'll also mention that there is an alternative, FastCGI, that is not tied so closely to the Web server. Refer to the section "Using FastCGI" for a discussion of the pros and cons.


   

 

 



The Ruby Way
The Ruby Way, Second Edition: Solutions and Techniques in Ruby Programming (2nd Edition)
ISBN: 0672328844
EAN: 2147483647
Year: 2000
Pages: 119
Authors: Hal Fulton

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net