A request handler for Rack applications.
Methods
Public Class methods
app is the Rack application object.
[ show source ]
# File lib/phusion_passenger/rack/request_handler.rb, line 60
60: def initialize(owner_pipe, app, options = {})
61: super(owner_pipe, options)
62: @app = app
63: end
Protected Instance methods
Overrided method.
[ show source ]
# File lib/phusion_passenger/rack/request_handler.rb, line 67
67: def process_request(env, input, output, full_http_response)
68: rewindable_input = PhusionPassenger::Utils::RewindableInput.new(input)
69: begin
70: env[RACK_VERSION] = RACK_VERSION_VALUE
71: env[RACK_INPUT] = rewindable_input
72: env[RACK_ERRORS] = STDERR
73: env[RACK_MULTITHREAD] = false
74: env[RACK_MULTIPROCESS] = true
75: env[RACK_RUN_ONCE] = false
76:
77: if env[HTTP_CONTENT_LENGTH] && env[CONTENT_LENGTH]
78: env.delete(HTTP_CONTENT_LENGTH)
79: elsif env[HTTP_CONTENT_LENGTH] && !env[CONTENT_LENGTH]
80: env[CONTENT_LENGTH] = env[HTTP_CONTENT_LENGTH]
81: env.delete(HTTP_CONTENT_LENGTH)
82: end
83: if env[HTTP_CONTENT_TYPE] && env[CONTENT_TYPE]
84: env.delete(HTTP_CONTENT_TYPE)
85: elsif env[HTTP_CONTENT_TYPE] && !env[CONTENT_TYPE]
86: env[CONTENT_TYPE] = env[HTTP_CONTENT_TYPE]
87: env.delete(HTTP_CONTENT_TYPE)
88: end
89:
90: if env[HTTPS] == YES || env[HTTPS] == ON || env[HTTPS] == ONE
91: env[RACK_URL_SCHEME] = HTTPS_DOWNCASE
92: else
93: env[RACK_URL_SCHEME] = HTTP
94: end
95:
96: status, headers, body = @app.call(env)
97: begin
98: if full_http_response
99: output.write("HTTP/1.1 #{status.to_i.to_s} Whatever#{CRLF}")
100: output.write("Connection: close#{CRLF}")
101: end
102: headers_output = [
103: STATUS, status.to_i.to_s, CRLF,
104: X_POWERED_BY, @passenger_header, CRLF
105: ]
106: headers.each do |key, values|
107: if values.is_a?(String)
108: values = values.split(NEWLINE)
109: end
110: values.each do |value|
111: headers_output << key
112: headers_output << NAME_VALUE_SEPARATOR
113: headers_output << value
114: headers_output << CRLF
115: end
116: end
117: headers_output << CRLF
118:
119: if body.is_a?(Array)
120: # The body may be an ActionController::StringCoercion::UglyBody
121: # object instead of a real Array, even when #is_a? claims so.
122: # Call #to_a just to be sure.
123: output.writev2(headers_output, body.to_a)
124: elsif body.is_a?(String)
125: headers_output << body
126: output.writev(headers_output)
127: else
128: output.writev(headers_output)
129: if body
130: body.each do |s|
131: output.write(s)
132: end
133: end
134: end
135: ensure
136: body.close if body.respond_to?(:close)
137: end
138: ensure
139: rewindable_input.close
140: end
141: end