class PhusionPassenger::Rack::RequestHandler

A request handler for Rack applications.

Public Class Methods

new(owner_pipe, app, options = {}) click to toggle source

app is the Rack application object.

# File lib/phusion_passenger/rack/request_handler.rb, line 59
def initialize(owner_pipe, app, options = {})
        super(owner_pipe, options)
        @app = app
end

Protected Instance Methods

process_request(env, input, output, full_http_response) click to toggle source

Overrided method.

# File lib/phusion_passenger/rack/request_handler.rb, line 66
def process_request(env, input, output, full_http_response)
        rewindable_input = PhusionPassenger::Utils::RewindableInput.new(input)
        begin
                env[RACK_VERSION]      = RACK_VERSION_VALUE
                env[RACK_INPUT]        = rewindable_input
                env[RACK_ERRORS]       = STDERR
                env[RACK_MULTITHREAD]  = false
                env[RACK_MULTIPROCESS] = true
                env[RACK_RUN_ONCE]     = false
                
                if env[HTTP_CONTENT_LENGTH] && env[CONTENT_LENGTH]
                        env.delete(HTTP_CONTENT_LENGTH)
                elsif env[HTTP_CONTENT_LENGTH] && !env[CONTENT_LENGTH]
                        env[CONTENT_LENGTH] = env[HTTP_CONTENT_LENGTH]
                        env.delete(HTTP_CONTENT_LENGTH)
                end
                if env[HTTP_CONTENT_TYPE] && env[CONTENT_TYPE]
                        env.delete(HTTP_CONTENT_TYPE)
                elsif env[HTTP_CONTENT_TYPE] && !env[CONTENT_TYPE]
                        env[CONTENT_TYPE] = env[HTTP_CONTENT_TYPE]
                        env.delete(HTTP_CONTENT_TYPE)
                end
                
                if env[HTTPS] == YES || env[HTTPS] == ON || env[HTTPS] == ONE
                        env[RACK_URL_SCHEME] = HTTPS_DOWNCASE
                else
                        env[RACK_URL_SCHEME] = HTTP
                end
                
                status, headers, body = @app.call(env)
                begin
                        if full_http_response
                                output.write("HTTP/1.1 #{status.to_i.to_s} Whatever#{CRLF}")
                                output.write("Connection: close#{CRLF}")
                        end
                        headers_output = [
                                STATUS, status.to_i.to_s, CRLF,
                                X_POWERED_BY, @passenger_header, CRLF
                        ]
                        headers.each do |key, values|
                                if values.is_a?(String)
                                        values = values.split(NEWLINE)
                                end
                                values.each do |value|
                                        headers_output << key
                                        headers_output << NAME_VALUE_SEPARATOR
                                        headers_output << value
                                        headers_output << CRLF
                                end
                        end
                        headers_output << CRLF
                        
                        if body.is_a?(Array)
                                # The body may be an ActionController::StringCoercion::UglyBody
                                # object instead of a real Array, even when #is_a? claims so.
                                # Call #to_a just to be sure.
                                output.writev2(headers_output, body.to_a)
                        elsif body.is_a?(String)
                                headers_output << body
                                output.writev(headers_output)
                        else
                                output.writev(headers_output)
                                if body
                                        body.each do |s|
                                                output.write(s)
                                        end
                                end
                        end
                ensure
                        body.close if body.respond_to?(:close)
                end
        ensure
                rewindable_input.close
        end
end