| 1 | # == About camping/webrick.rb |
|---|
| 2 | # |
|---|
| 3 | # For many who have Ruby installed, Camping and WEBrick is a great option. |
|---|
| 4 | # It's definitely the easiest configuration, however some performance is sacrificed. |
|---|
| 5 | # For better speed, check out Mongrel at http://mongrel.rubyforge.org/, which comes |
|---|
| 6 | # with Camping hooks and is supported by the Camping Tool. |
|---|
| 7 | require 'camping' |
|---|
| 8 | require 'webrick/httpservlet/abstract.rb' |
|---|
| 9 | |
|---|
| 10 | module WEBrick |
|---|
| 11 | # WEBrick::CampingHandler is a very simple handle for hosting Camping apps in |
|---|
| 12 | # a WEBrick server. It's used much like any other WEBrick handler. |
|---|
| 13 | # |
|---|
| 14 | # == Mounting a Camping App |
|---|
| 15 | # |
|---|
| 16 | # Assuming Camping.goes(:Blog), the Blog application can be mounted alongside |
|---|
| 17 | # other WEBrick mounts. |
|---|
| 18 | # |
|---|
| 19 | # s = WEBrick::HTTPServer.new(:BindAddress => host, :Port => port) |
|---|
| 20 | # s.mount "/blog", WEBrick::CampingHandler, Blog |
|---|
| 21 | # s.mount_proc("/") { ... } |
|---|
| 22 | # |
|---|
| 23 | # == How Does it Compare? |
|---|
| 24 | # |
|---|
| 25 | # Compared to other handlers, WEBrick is well-equipped in terms of features. |
|---|
| 26 | # |
|---|
| 27 | # * The <tt>X-Sendfile</tt> header is supported, along with etags and |
|---|
| 28 | # modification time headers for the file served. Since this handler |
|---|
| 29 | # is a subclass of WEBrick::HTTPServlet::DefaultFileHandler, all of its |
|---|
| 30 | # logic is used. |
|---|
| 31 | # * IO is streaming up and down. When you upload a file, it is streamed to |
|---|
| 32 | # the server's filesystem. When you download a file, it is streamed to |
|---|
| 33 | # your browser. |
|---|
| 34 | # |
|---|
| 35 | # While WEBrick is a bit slower than Mongrel and FastCGI options, it's |
|---|
| 36 | # a decent choice, for sure! |
|---|
| 37 | class CampingHandler < WEBrick::HTTPServlet::DefaultFileHandler |
|---|
| 38 | # Creates a CampingHandler, which answers for the application within +klass+. |
|---|
| 39 | def initialize(server, klass) |
|---|
| 40 | super(server, klass) |
|---|
| 41 | @klass = klass |
|---|
| 42 | end |
|---|
| 43 | # Handler for WEBrick requests (also aliased as do_POST). |
|---|
| 44 | def service(req, resp) |
|---|
| 45 | controller = @klass.run((req.body && StringIO.new(req.body)) || StringIO.new(), req.meta_vars) |
|---|
| 46 | resp.status = controller.status |
|---|
| 47 | @local_path = nil |
|---|
| 48 | controller.headers.each do |k, v| |
|---|
| 49 | if k =~ /^X-SENDFILE$/i |
|---|
| 50 | @local_path = v |
|---|
| 51 | else |
|---|
| 52 | [*v].each do |vi| |
|---|
| 53 | resp[k] = vi |
|---|
| 54 | end |
|---|
| 55 | end |
|---|
| 56 | end |
|---|
| 57 | |
|---|
| 58 | if @local_path |
|---|
| 59 | do_GET(req, resp) |
|---|
| 60 | elsif controller.body.kind_of?(IO) |
|---|
| 61 | resp.chunked = true |
|---|
| 62 | resp.body = controller.body |
|---|
| 63 | else |
|---|
| 64 | resp.body = controller.body.to_s |
|---|
| 65 | end |
|---|
| 66 | end |
|---|
| 67 | end |
|---|
| 68 | end |
|---|