Class: Rack::Handler::Mongrel

Inherits:
Mongrel::HttpHandler
  • Object
show all
Defined in:
lib/rack/handler/mongrel.rb

Direct Known Subclasses

EventedMongrel, SwiftipliedMongrel

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app) ⇒ Mongrel

Returns a new instance of Mongrel.



37
38
39
# File 'lib/rack/handler/mongrel.rb', line 37

def initialize(app)
  @app = Rack::Chunked.new(Rack::ContentLength.new(app))
end

Class Method Details

.run(app, options = {}) {|server| ... } ⇒ Object

Yields:

  • (server)


9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/rack/handler/mongrel.rb', line 9

def self.run(app, options={})
  server = ::Mongrel::HttpServer.new(options[:Host] || '0.0.0.0',
                                     options[:Port] || 8080)
  # Acts like Rack::URLMap, utilizing Mongrel's own path finding methods.
  # Use is similar to #run, replacing the app argument with a hash of 
  # { path=>app, ... } or an instance of Rack::URLMap.
  if options[:map]
    if app.is_a? Hash
      app.each do |path, appl|
        path = '/'+path unless path[0] == ?/
        server.register(path, Rack::Handler::Mongrel.new(appl))
      end
    elsif app.is_a? URLMap
      app.instance_variable_get(:@mapping).each do |(host, path, appl)|
       next if !host.nil? && !options[:Host].nil? && options[:Host] != host
       path = '/'+path unless path[0] == ?/
       server.register(path, Rack::Handler::Mongrel.new(appl))
      end
    else
      raise ArgumentError, "first argument should be a Hash or URLMap"
    end
  else
    server.register('/', Rack::Handler::Mongrel.new(app))
  end
  yield server  if block_given?
  server.run.join
end

Instance Method Details

#process(request, response) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/rack/handler/mongrel.rb', line 41

def process(request, response)
  env = {}.replace(request.params)
  env.delete "HTTP_CONTENT_TYPE"
  env.delete "HTTP_CONTENT_LENGTH"

  env["SCRIPT_NAME"] = ""  if env["SCRIPT_NAME"] == "/"

  rack_input = request.body || StringIO.new('')
  rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)

  env.update({"rack.version" => [1,0],
               "rack.input" => request.body || StringIO.new(""),
               "rack.errors" => $stderr,

               "rack.multithread" => true,
               "rack.multiprocess" => false, # ???
               "rack.run_once" => false,

               "rack.url_scheme" => "http",
             })
  env["QUERY_STRING"] ||= ""
  env.delete "PATH_INFO"  if env["PATH_INFO"] == ""

  status, headers, body = @app.call(env)

  begin
    response.status = status.to_i
    response.send_status(nil)

    headers.each { |k, vs|
      vs.split("\n").each { |v|
        response.header[k] = v
      }
    }
    response.send_header

    body.each { |part|
      response.write part
      response.socket.flush
    }
  ensure
    body.close  if body.respond_to? :close
  end
end