Updated README.rdoc again
[feedcatcher.git] / vendor / rails / actionpack / lib / action_controller / vendor / rack-1.0 / rack / handler / mongrel.rb
1 require 'mongrel'
2 require 'stringio'
3 require 'rack/content_length'
4 require 'rack/chunked'
5
6 module Rack
7 module Handler
8 class Mongrel < ::Mongrel::HttpHandler
9 def self.run(app, options={})
10 server = ::Mongrel::HttpServer.new(options[:Host] || '0.0.0.0',
11 options[:Port] || 8080)
12 # Acts like Rack::URLMap, utilizing Mongrel's own path finding methods.
13 # Use is similar to #run, replacing the app argument with a hash of
14 # { path=>app, ... } or an instance of Rack::URLMap.
15 if options[:map]
16 if app.is_a? Hash
17 app.each do |path, appl|
18 path = '/'+path unless path[0] == ?/
19 server.register(path, Rack::Handler::Mongrel.new(appl))
20 end
21 elsif app.is_a? URLMap
22 app.instance_variable_get(:@mapping).each do |(host, path, appl)|
23 next if !host.nil? && !options[:Host].nil? && options[:Host] != host
24 path = '/'+path unless path[0] == ?/
25 server.register(path, Rack::Handler::Mongrel.new(appl))
26 end
27 else
28 raise ArgumentError, "first argument should be a Hash or URLMap"
29 end
30 else
31 server.register('/', Rack::Handler::Mongrel.new(app))
32 end
33 yield server if block_given?
34 server.run.join
35 end
36
37 def initialize(app)
38 @app = Rack::Chunked.new(Rack::ContentLength.new(app))
39 end
40
41 def process(request, response)
42 env = {}.replace(request.params)
43 env.delete "HTTP_CONTENT_TYPE"
44 env.delete "HTTP_CONTENT_LENGTH"
45
46 env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
47
48 env.update({"rack.version" => [0,1],
49 "rack.input" => request.body || StringIO.new(""),
50 "rack.errors" => $stderr,
51
52 "rack.multithread" => true,
53 "rack.multiprocess" => false, # ???
54 "rack.run_once" => false,
55
56 "rack.url_scheme" => "http",
57 })
58 env["QUERY_STRING"] ||= ""
59 env.delete "PATH_INFO" if env["PATH_INFO"] == ""
60
61 status, headers, body = @app.call(env)
62
63 begin
64 response.status = status.to_i
65 response.send_status(nil)
66
67 headers.each { |k, vs|
68 vs.split("\n").each { |v|
69 response.header[k] = v
70 }
71 }
72 response.send_header
73
74 body.each { |part|
75 response.write part
76 response.socket.flush
77 }
78 ensure
79 body.close if body.respond_to? :close
80 end
81 end
82 end
83 end
84 end