GitHub Sale: sign up for any paid plan this week and pay nothing until January 1, 2009!  [ hide ]

public
Fork of wycats/merb-core
Description: Merb Core: All you need. None you don't.
Homepage: http://www.merbivore.com
Clone URL: git://github.com/auser/merb-core.git
commit  8abb459d89ccb6061fa9dc59c380823619de1706
tree    e2308b970c53f0c54731eacc31683f0138fce10f
parent  a15b2e9aa1eb31f0a3fa7b2568f3ed25968e8433
merb-core / lib / merb-core / rack / handler / mongrel.rb
100644 76 lines (65 sloc) 2.224 kb
1
2
3
4
5
6
7
8
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
36
37
38
39
40
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
require 'mongrel'
require 'stringio'
 
class Mongrel::HttpResponse
  NO_CLOSE_STATUS_FORMAT = "HTTP/1.1 %d %s\r\n".freeze
  def send_status_no_connection_close(content_length=@body.length)
    unless @status_sent
      write(NO_CLOSE_STATUS_FORMAT % [@status, Mongrel::HTTP_STATUS_CODES[@status]])
      @status_sent = true
    end
  end
end
 
module Merb
  module Rack
    module Handler
      class Mongrel < ::Mongrel::HttpHandler
        def self.run(app, options={})
          server = ::Mongrel::HttpServer.new(options[:Host] || '0.0.0.0',
                                             options[:Port] || 8080)
          server.register('/', ::Merb::Rack::Handler::Mongrel.new(app))
          yield server if block_given?
          server.run.join
        end
  
        def initialize(app)
          @app = app
        end
  
        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"] == "/"
  
          env.update({"rack.version" => [0,1],
                       "rack.input" => request.body || StringIO.new(""),
                       "rack.errors" => STDERR,
  
                       "rack.multithread" => true,
                       "rack.multiprocess" => false, # ???
                       "rack.run_once" => false,
  
                       "rack.url_scheme" => "http",
                       "rack.streaming" => true
                     })
          env["QUERY_STRING"] ||= ""
          env.delete "PATH_INFO" if env["PATH_INFO"] == ""
  
          status, headers, body = @app.call(env)
  
          begin
            response.status = status.to_i
            headers.each { |k, vs|
              vs.each { |v|
                response.header[k] = v
              }
            }
            
            if body.respond_to?(:call)
              body.call(response)
            else
              body.each { |part|
                response.body << part
              }
            end
            response.finished
          ensure
            body.close if body.respond_to? :close
          end
        end
      end
    end
  end
end