1 # Donated by Florian Gross
19 def initialize(type
= "query", table
= nil, stdin = nil)
20 @env_table, @stdin = table
, stdin
22 if defined?(MOD_RUBY
) && !ENV.key
?("GATEWAY_INTERFACE")
23 Apache
.request
.setup_cgi_env
28 if defined?(CGI_PARAMS
)
29 warn
"do not use CGI_PARAMS and CGI_COOKIES"
30 @params = CGI_PARAMS
.dup
31 @cookies = CGI_COOKIES
.dup
33 initialize_query() # set @params, @cookies
40 # A custom dispatch servlet for use with WEBrick. It dispatches requests
41 # (using the Rails Dispatcher) to the appropriate controller/action. By default,
42 # it restricts WEBrick to a managing a single Rails request at a time, but you
43 # can change this behavior by setting ActionController::Base.allow_concurrency
45 class DispatchServlet
< WEBrick
::HTTPServlet::AbstractServlet
46 # Start the WEBrick server with the given options, mounting the
47 # DispatchServlet at <tt>/</tt>.
48 def self.dispatch(options
= {})
49 Socket
.do_not_reverse_lookup
= true # patch for OS X
51 params
= { :Port => options
[:port].to_i
,
52 :ServerType => options
[:server_type],
53 :BindAddress => options
[:ip] }
54 params
[:MimeTypes] = options
[:mime_types] if options
[:mime_types]
56 server
= WEBrick
::HTTPServer.new(params
)
57 server
.mount('/', DispatchServlet
, options
)
59 trap("INT") { server
.shutdown
}
63 def initialize(server
, options
) #:nodoc:
64 @server_options = options
65 @file_handler = WEBrick
::HTTPServlet::FileHandler.new(server
, options
[:server_root])
66 # Change to the RAILS_ROOT, since Webrick::Daemon.start does a Dir::cwd("/")
67 # OPTIONS['working_directory'] is an absolute path of the RAILS_ROOT, set in railties/lib/commands/servers/webrick.rb
68 Dir
.chdir(OPTIONS
['working_directory']) if defined?(OPTIONS
) && File
.directory
?(OPTIONS
['working_directory'])
72 def service(req
, res
) #:nodoc:
73 unless handle_file(req
, res
)
74 unless handle_dispatch(req
, res
)
75 raise WEBrick
::HTTPStatus::NotFound, "`#{req.path}' not found."
80 def handle_file(req
, res
) #:nodoc:
85 # Add .html if the last path piece has no . in it
86 path
<< '.html' if path
!= '/' && (%r
{(^
|/)[^
./]+$
} =~ path
)
87 path
.gsub
!('+', ' ') # Unescape + since FileHandler doesn't do so.
89 req
.instance_variable_set(:@path_info, path
) # Set the modified path...
91 @file_handler.send(:service, req
, res
)
93 rescue HTTPStatus
::PartialContent, HTTPStatus
::NotModified => err
101 def handle_dispatch(req
, res
, origin
= nil) #:nodoc:
104 CGI
.new("query", create_env_table(req
, origin
), StringIO
.new(req
.body
|| "")),
105 ActionController
::CgiRequest::DEFAULT_SESSION_OPTIONS,
109 header
, body
= extract_header_and_body(data)
112 assign_status(res
, header
)
113 res
.cookies
.concat(header
.delete('set-cookie') || [])
114 header
.each
{ |key
, val
| res
[key
] = val
.join(", ") }
124 def create_env_table(req
, origin
)
125 env = req
.meta_vars
.clone
126 env.delete
"SCRIPT_NAME"
127 env["QUERY_STRING"] = req
.request_uri
.query
128 env["REQUEST_URI"] = origin
if origin
132 def extract_header_and_body(data)
136 raw_header
, body
= *data.split(/^[\xd\xa]{2}/on
, 2)
137 header
= WEBrick
::HTTPUtils::parse_header(raw_header
)
142 def set_charset(header
)
143 ct
= header
["content-type"]
144 if ct
.any
? { |x
| x
=~
/^text\// } && ! ct.any? { |x| x =~ /charset
=/ }
145 ch
= @server_options[:charset] || "UTF-8"
146 ct
.find
{ |x
| x
=~
/^text\// } << ("; charset=" + ch
)
150 def assign_status(res
, header
)
151 if /^(\d+)/ =~ header
['status'][0]
153 header
.delete('status')