User:Adeeshag/WEBrick

From Wikipedia, the free encyclopedia
WEBrick
Original author(s)Masayoshi Takahashi and Yuuzou Gotou
Developer(s)Ruby Community
Stable release
1.3.1 (Obsolete) / August 14, 2003 (2003-08-14)
Written inRuby
Operating systemCross-platform
Available inRuby
TypeWeb Server
Websitewww.webrick.org (Obsolete)
www.ruby-lang.org

WEBrick is a Ruby library providing simple HTTP web server services. WEBrick was primarily written by Masayoshi Takahashi and Yuuzou Gotou, with contributions from other developers via the open source model of software development. The server provides HTTP, HTTPS with authentication, setup of Servlet with Ruby code, and other features.

It is used by the Ruby on Rails and Padrino frameworks to test applications in a development environment as well as production mode. It is now part of Ruby standard library for Ruby 1.9.3, and updated with Ruby trunk. The documentation is incomplete for some modules and methods.

Features of WEBrick[edit]

Starting a HTTP server[edit]

In order to create a WEBrick HTTP server, we must first include the WEBrick library. We can use the following commands to start the WEBrick server.[1]

require 'webrick'
root = File.expand_path '~/public_html'
server = WEBrick::HTTPServer.new :Port => 8000, :DocumentRoot => root

:Port ensures that it will listen on port 8000 and root allows to serve files from the ~/public_html.

To run the server (and provide a proper shutdown hook so that it does not block the current thread), we use the following commands:

trap 'INT' do server.shutdown end
server.start

Note: "Hook" refers to a method contains a block and is used to simplify programming in order to extend the behaviour of programs. Depending on the framework, different hooks are used to perform certain functions.

Mounting Servlets[edit]

In WEBrick, we may set up a servlet so that we can service a request-URI. This can be done by creating an instance of a subclass of WEBrick::HTTPServlet::AbstractServlet. The subclass AbstractServlet enables the reuse of multiple HTTP server modules across various servers.

To avoid initializing a new servlet each request, we can reuse an existing servlet by overriding the ::get_instance in the AbstractServlet.

An example of a Servlet is shown in the code snippet below:[2]

Class SimpleServlet < WEBrick::HTTPServlet::AbstractServlet
   def do_GET request, response
      //code to handle response
   end
end

In order to mount the servlet on a server, we must specify the mount path and the class of the servlet, along with any parameters if required. An example to mount the above servlet is shown below:

server.mount '/path/' , SimpleServlet <, optional parameters>

Note: do_GET is one of the public instance methods that can be used with the AbstractServlet class

Standard Servlets[edit]

Some of the standard servlets that come with WEBrick are:

WEBrick::HTTPServlet::FileHandler[edit]

This is a useful standard servlet that is used to help serve a directory using a number of different options. If the path points to a directory, it will serve the index file. When the FileHandler receives a request, it analyzes the request path. An example to mount a servlet sign the FileHandler is:

server.mount '/directory1', WEBrick::HTTPServlet::FileHandler , '/path_to_be_served/'
  • WEBrick::HTTPServlet::DefaultFileHandler

When the FileHandler receives a request path that does not end with a .cgi or a .rhtml , then the DefaultFileHandler will be responsible to handle the request. This servlet is generally used to handle If-Modify-Since and Range HTTP/1.1RFC requests.

server.mount '/my_page.txt', WEBrick::HTTPServlet::DefaultFileHandler, '/path/to/my_page.txt'

WEBrick::HTTPServlet::CGIHandler[edit]

This is a servlet that is used to enable the use of CGI scripts or programs without having to rewrite them as WEBrick servlets. We must make sure that we install a FileHandler to that directory containing all the CGI scripts and make sure the files are of the correct format. An example is given below:

server.mount '/scripts/', WEBrick::HTTPServlet::CGIHandler, '/path/cgi_script.cgi'

WEBrick::HTTPServlet::ProcHandler[edit]

This is used to mount a proc at the specified path. If we do not require complex functionality for our servlet, we would not necessarily need to subclass the AbstractServlet , create new instances and threads for each servlet. We could make use of the ProcHandler to accept a request and response from the specified path. Let us take an example where the specified path is /proc_path/ and it only sends a response with the body:

server.mount_proc '/proc_path/' do |request, response|
   response.body = "Proc Test, Success!"
end

WEBrick::HTTPServlet::ERBHandler[edit]

This servlet is similar to the CGIHandler servlet with the main difference being that it services .rhtml files. If a directory is served by the FileHandler, i.e, if we install a Filehandler to the directory containing the .rthml files, then this handler will be automatically used. This handler supports the GET and POST methods. The ERB files are evaluated using the WEBrick::HTTPRequest and WEBrick::HTTPResponse.

Creating Custom Servlets[edit]

We can write custom servlets where we can make them perform the functions we want or in other words, what we would do when we query a request object and how we can set the response object.[3]

do_ methods[edit]

We would need to create a subclass WEBrick::HTTPServlet::AbstractServlet and then to that, add a do_GET, do_POST , do_HEAD and/or do_OPTIONS.

  • do_HEAD: just calls a do_GET , which should be provided by the user.
  • do_OPTIONS: just returns a list of all the do_ methods that are avaialable for use.
  • do_GET: returns NotFound Exception if we don't have any method defined.

We can customize what a do_ method should do. WEBrick will call the custom do_ method with two parameters: request and response objects.[4] Example code:

 class GreetingServlet < HTTPServlet::AbstractServlet
   def do_GET(request, response)
    if req.query[’name’]
     resp.body = "#{@options[0]} #{req.query[’name’]}. #{@options[1]}"
     raise HTTPStatus::OK
    else
     raise HTTPStatus::PreconditionFailed.new("missing attribute: ’name’")
    end
   end
   alias do_POST, do_GET    # let’s accept POST request too.
 end
 start_webrick {|server| server.mount(’/greet’, GreetingServlet, ’Hi’, ’Are you having a nice day?’) }


Response[edit]

For every request, we can respond in one of two ways. We can:

  • Raise a HTTPStatus exception which would show an HTML filled page with a backtrace.
  • Provide a custom error page which involves:
    1. Manually setting a response body and status; OR
    2. Extend the HTTPResponse object with the set_error method which will create an error page and enable backtrace (optionally), in the event of an error.

Virtual Host[edit]

A virtual host allows to host multiple domain names on a server. WEBrick can act as a virtual host for multiple host names. Once you have created the listening host you can add multiple hosts that do not listen and can act as virtual hosts. Sample code snippet is given below:

server = WEBrick::HTTPServer.new # ... 
vhost = WEBrick::HTTPServer.new :ServerName => 'vhost.example',
                               :DoNotListen => true, # ... 
vhost.mount '/', ...
server.virtual_host vhost

vhost is the virtual host server defined and mounted in the above code snippet.

Note: If :DocumentRoot is not provided and servlets or procs are not mounted on the main server you will receive a 404 error message for all the URL’s.

Proxy Server[edit]

Proxy servers are intermediary servers between client and requested information hosted on other servers.

You can create a simple proxy server with the below code snippet:

require 'webrick'
require 'webrick/httpproxy'
proxy = WEBrick::HTTPProxyServer.new Port: 8000

Logging[edit]

WEBrick allows us to log both server operations and user access.

Server Operations[edit]

The operations done at server can logged through the log class available in WEBrick. Sample code :

file_log = File.open '/abc/log/server_operations.log', 'a+'
log = WEBrick::Log.new file_log

file_log is a File object defined with the name of the log file to be used as the parameter. The mode used for opening the file is a+ which allows to read and write in append mode. We assigned log as a new object of Log class in WEBrick and have passed file_log as the parameter.

User Access[edit]

Access log is used to log user requests for all the files they have requested from the website. As user logs are more likely to be accessed they are treated specially. Sample code for the log:-

user_log = [
 [file_log, WEBrick::AccessLog::COMBINED_LOG_FORMAT],
 ]
server = WEBrick::HTTPServer.new :Logger => log, :AccessLog => user_log

HTTP Authentication[edit]

HTTP authentication is supported by two mechanisms: basic and digest. Digest authentication communicates credentials in an encrypted format. Hash functions are used for the purpose. Basic authentication uses an unencrypted encoding. To implement authentication in WEBrick you will require a database and an authenticator.[5]

config = { :Realm => 'DigestAuth example realm' }
htpasswd = WEBrick::HTTPAuth::Htpasswd.new 'my_password_file'
htpasswd.auth_type = WEBrick::HTTPAuth::DigestAuth
htpasswd.set_passwd config[:Realm], 'username', 'password'
htpasswd.flush

Htpasswd database is used above a with a DigestAuth authenticator. Different access is provided to different groups using :Realm.

Authenticator is created using the database.

config[:UserDB] = htpasswd
digest_auth = WEBrick::HTTPAuth::DigestAuth.new config

Request call is authenticated with a request and response object in a servlet:

def do_GET req, res
  @authenticator.authenticate req, res
end

Basic Authentication[edit]

BasicAuth is the class used for basic Authentication. A sample example for authentication is provided below:

config = { :Realm => 'BasicAuth example realm' }
htpasswd = WEBrick::HTTPAuth::Htpasswd.new 'my_password_file'
htpasswd.set_passwd config[:Realm], 'username', 'password'
htpasswd.flush
config[:UserDB] = htpasswd
basic_auth = WEBrick::HTTPAuth::BasicAuth.new config

Digest Authentication[edit]

DigestAuth class is used for digest authentication. Sample code is provided below:

config = { :Realm => 'DigestAuth example realm' }
htdigest = WEBrick::HTTPAuth::Htdigest.new 'my_password_file'
htdigest.set_passwd config[:Realm], 'username', 'password'
htdigest.flush
config[:UserDB] = htdigest
digest_auth = WEBrick::HTTPAuth::DigestAuth.new config

Conclusion[edit]

WEBrick is a HTTPserver toolkit which can be configured in three different ways i.e. HTTPS server, proxy server and virtual host server. It provides us with tools for maintaining logs .It supports both user access and server operations logging. It also provides tool for authentication. Both basic and digest authentication is supported by WEBrick. Servlets are provided in WEBrick that can handle ERB pages, CGI scripts and Ruby blocks. Also WEBrick server can use any number of servlets or WEBrick servers. Despite the features WEBrick is generally used for development and not as a production web server as it not designed to handle heavy load.

References[edit]

External links[edit]

Category:Free web server software Category:Ruby (programming language) Category:Web server software for Linux