2006-06-30 16:42:12 -04:00
|
|
|
# Copyright (c) 2005 Zed A. Shaw
|
|
|
|
# You can redistribute it and/or modify it under the same terms as Ruby.
|
|
|
|
#
|
|
|
|
# Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
|
|
|
|
# for more information.
|
2006-05-21 10:46:42 -04:00
|
|
|
|
2006-03-06 20:44:24 -05:00
|
|
|
require 'mongrel'
|
|
|
|
|
|
|
|
|
|
|
|
module Mongrel
|
|
|
|
# Support for the Camping micro framework at http://camping.rubyforge.org
|
|
|
|
# This implements the unusually long Postamble that Camping usually
|
|
|
|
# needs and shrinks it down to just a single line or two.
|
|
|
|
#
|
|
|
|
# Your Postamble would now be:
|
|
|
|
#
|
|
|
|
# Mongrel::Camping::start("0.0.0.0",3001,"/tepee",Tepee).join
|
|
|
|
#
|
|
|
|
# If you wish to get fancier than this then you can use the
|
|
|
|
# Camping::CampingHandler directly instead and do your own
|
|
|
|
# wiring:
|
|
|
|
#
|
|
|
|
# h = Mongrel::HttpServer.new(server, port)
|
|
|
|
# h.register(uri, CampingHandler.new(Tepee))
|
|
|
|
# h.register("/favicon.ico", Mongrel::Error404Handler.new(""))
|
|
|
|
#
|
|
|
|
# I add the /favicon.ico since camping apps typically don't
|
|
|
|
# have them and it's just annoying anyway.
|
|
|
|
module Camping
|
|
|
|
|
|
|
|
# This is a specialized handler for Camping applications
|
|
|
|
# that has them process the request and then translates
|
|
|
|
# the results into something the Mongrel::HttpResponse
|
|
|
|
# needs.
|
|
|
|
class CampingHandler < Mongrel::HttpHandler
|
2006-10-05 00:27:44 -04:00
|
|
|
attr_reader :files
|
|
|
|
attr_reader :guard
|
|
|
|
@@file_only_methods = ["GET","HEAD"]
|
|
|
|
|
2006-03-06 20:44:24 -05:00
|
|
|
def initialize(klass)
|
2006-10-05 00:27:44 -04:00
|
|
|
@files = Mongrel::DirHandler.new("/",false)
|
|
|
|
@guard = Sync.new
|
2006-03-06 20:44:24 -05:00
|
|
|
@klass = klass
|
|
|
|
end
|
|
|
|
|
|
|
|
def process(request, response)
|
2006-10-05 00:27:44 -04:00
|
|
|
if response.socket.closed?
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
controller = nil
|
|
|
|
@guard.synchronize(:EX) {
|
|
|
|
controller = @klass.run(request.body, request.params)
|
|
|
|
}
|
|
|
|
|
2006-04-10 20:17:19 -04:00
|
|
|
sendfile, clength = nil
|
2006-10-05 00:27:44 -04:00
|
|
|
get_or_head = @@file_only_methods.include? request.params[Mongrel::Const::REQUEST_METHOD]
|
|
|
|
|
2006-04-10 20:17:19 -04:00
|
|
|
response.status = controller.status
|
|
|
|
controller.headers.each do |k, v|
|
|
|
|
if k =~ /^X-SENDFILE$/i
|
|
|
|
sendfile = v
|
|
|
|
elsif k =~ /^CONTENT-LENGTH$/i
|
|
|
|
clength = v.to_i
|
|
|
|
else
|
|
|
|
[*v].each do |vi|
|
|
|
|
response.header[k] = vi
|
2006-03-06 20:44:24 -05:00
|
|
|
end
|
|
|
|
end
|
2006-04-10 20:17:19 -04:00
|
|
|
end
|
2006-04-10 20:00:52 -04:00
|
|
|
|
2006-04-10 20:17:19 -04:00
|
|
|
if sendfile
|
2006-10-05 00:27:44 -04:00
|
|
|
request.params[Mongrel::Const::PATH_INFO] = sendfile
|
|
|
|
@files.process(request, response)
|
2006-04-10 20:17:19 -04:00
|
|
|
elsif controller.body.respond_to? :read
|
2006-04-10 23:24:53 -04:00
|
|
|
response.send_status(clength)
|
|
|
|
response.send_header
|
2006-04-10 20:17:19 -04:00
|
|
|
while chunk = controller.body.read(16384)
|
|
|
|
response.write(chunk)
|
|
|
|
end
|
|
|
|
if controller.body.respond_to? :close
|
|
|
|
controller.body.close
|
2006-04-10 14:56:16 -04:00
|
|
|
end
|
2006-04-10 20:17:19 -04:00
|
|
|
else
|
2006-05-14 02:56:50 -04:00
|
|
|
body = controller.body.to_s
|
|
|
|
response.send_status(body.length)
|
2006-04-10 23:24:53 -04:00
|
|
|
response.send_header
|
2006-05-14 02:56:50 -04:00
|
|
|
response.write(body)
|
2006-03-06 20:44:24 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# This is a convenience method that wires up a CampingHandler
|
|
|
|
# for your application on a given port and uri. It's pretty
|
|
|
|
# much all you need for a camping application to work right.
|
|
|
|
#
|
2006-03-09 01:11:21 -05:00
|
|
|
# It returns the Mongrel::HttpServer which you should either
|
2006-03-06 20:44:24 -05:00
|
|
|
# join or somehow manage. The thread is running when
|
|
|
|
# returned.
|
2006-03-09 01:11:21 -05:00
|
|
|
|
2006-03-06 20:44:24 -05:00
|
|
|
def Camping.start(server, port, uri, klass)
|
|
|
|
h = Mongrel::HttpServer.new(server, port)
|
|
|
|
h.register(uri, CampingHandler.new(klass))
|
|
|
|
h.register("/favicon.ico", Mongrel::Error404Handler.new(""))
|
2006-03-09 01:11:21 -05:00
|
|
|
h.run
|
|
|
|
return h
|
2006-03-06 20:44:24 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|