Initializing a servlet in WEBRick

I am writing a web application where all the requests are served by the
same object, which needs initialization. This is being done this way:

<<initialize some stuff from the command line parameters>>
<<initialize the driver of the application from that stuff>>
server.mount_proc(path) { |req, res| driver.process(req, res) }

That seems to work fine, but I wonder if the driver could be a subclass
of HTTPServlet::AbstractServlet so that one would just say

server.mount(path, DriverServlet)

and have one instance serving all the pages and initialized as needed. I
have tried to figure it out from the sources but don’t see how would it
work.

– fxn

Hi,

In message 200309071203.04502.fxn@hashref.com,

I am writing a web application where all the requests are served by the
same object, which needs initialization. This is being done this way:

<<initialize some stuff from the command line parameters>>
<<initialize the driver of the application from that stuff>>
server.mount_proc(path) { |req, res| driver.process(req, res) }

That seems to work fine, but I wonder if the driver could be a subclass
of HTTPServlet::AbstractServlet so that one would just say

server.mount(path, DriverServlet)

and have one instance serving all the pages and initialized as needed. I
have tried to figure it out from the sources but don’t see how would it
work.

If it’s explained simply, servelets are activated in the
following sequence:

<< accept connection and receive HTTP request >>
<< find a ServletClass associated with path of URL >>

the third and more arguments of mount() will be passed to options.

servlet = ServletClass.get_instance(server, *options)
servlet.service(req, res)

<< send response >>

If it can respond to get_instance and service, any kind of
object can be mounted as a servelet.

AbstractServlet::get_instance just calls new() and instance
of servelet will be created for every request. Conversely
singleton servelet can be up by overriding of get_instance.

The following sample implements get_instance as a instance
method and initialize a servlet out of server before it’s
started.

require ‘webrick’

class AccessCounter < WEBrick::HTTPServlet::AbstractServlet
def initialize(server)
@mutex = Mutex.new # service should be MT-safe
@count = 0
end
def get_instance(server)
self # always returns same instance
end
def service(req, res)
@mutex.synchronize{ super }
end
def do_GET(req, res)
res.body = “@count=#{@count+=1}
res[‘content-type’] = “text/html”
end
end

svr = WEBrick::HTTPServer.new(:Port => 10080)
counter = AccessCounter.new(svr)
svr.mount(“/”, counter)
svr.start

···

`Xavier Noria fxn@hashref.com’ wrote:


gotoyuzo

<< cut >>

That’s very helpful, thank you very much GOTOU.

The code shouldn’t depend on the implementation of WEBrick however, do
you think we can rely on the outlined sequence

<< accept connection and receive HTTP request >>
<< find a ServletClass associated with path of URL >>

the third and more arguments of mount() will be passed to options.

servlet = ServletClass.get_instance(server, *options)
servlet.service(req, res)

<< send response >>

?

– fxn

PS: I am sorry for the typo in the subject.

···

On Sunday 07 September 2003 15:43, GOTOU Yuuzou wrote:

If it’s explained simply, servelets are activated in the
following sequence:

<< accept connection and receive HTTP request >>
<< find a ServletClass associated with path of URL >>

the third and more arguments of mount() will be passed to

options. servlet = ServletClass.get_instance(server, *options)
servlet.service(req, res)

<< send response >>

If it can respond to get_instance and service, any kind of
object can be mounted as a servelet.

In message 200309071717.08089.fxn@hashref.com,

If it can respond to get_instance and service, any kind of
object can be mounted as a servelet.

<< cut >>

That’s very helpful, thank you very much GOTOU.

The code shouldn’t depend on the implementation of WEBrick however, do
you think we can rely on the outlined sequence

<< accept connection and receive HTTP request >>
<< find a ServletClass associated with path of URL >>

the third and more arguments of mount() will be passed to options.

servlet = ServletClass.get_instance(server, *options)
servlet.service(req, res)

<< send response >>

Yes, requirement of get_instance and service is the spec
of WEBrick::HTTPServer. I guess it will not be changed.

at least in Ruby-1.8…

By the way, the code of servlet activation is described in
HTTPServer#service. We can rewrite it to build specific
purpose server or realize another idea about uri-to-service
mapping.

require “webrick”
class NotFoundServer < WEBrick::HTTPServer
def service(req, res)
# returns 404 against every request.
raise WEBrick::HTTPStatus::NotFound
end
end
NotFoundServer.new(:Port=>10080).start

···

`Xavier Noria fxn@hashref.com’ wrote:

On Sunday 07 September 2003 15:43, GOTOU Yuuzou wrote:


gotoyuzo