def process_request(env, connection, socket_wrapper, full_http_response)
rewindable_input = PhusionPassenger::Utils::TeeInput.new(connection, env)
begin
env[RACK_VERSION] = RACK_VERSION_VALUE
env[RACK_INPUT] = rewindable_input
env[RACK_ERRORS] = STDERR
env[RACK_MULTITHREAD] = @request_handler.concurrency > 1
env[RACK_MULTIPROCESS] = true
env[RACK_RUN_ONCE] = false
if env[HTTPS] == YES || env[HTTPS] == ON || env[HTTPS] == ONE
env[RACK_URL_SCHEME] = HTTPS_DOWNCASE
else
env[RACK_URL_SCHEME] = HTTP
end
env[RACK_HIJACK_P] = true
env[RACK_HIJACK] = lambda do
env[RACK_HIJACK_IO] ||= begin
connection.stop_simulating_eof!
connection
end
end
env[HTTP_VERSION] = HTTP_1_1
is_head_request = env[REQUEST_METHOD] == HEAD
begin
status, headers, body = @app.call(env)
rescue => e
if !should_swallow_app_error?(e, socket_wrapper)
print_exception("Rack application object", e)
log_exception_to_union_station(env, e)
end
return false
end
if env[RACK_HIJACK_IO]
body.close if body && body.respond_to?(:close)
return true
end
if hijack_callback = headers[RACK_HIJACK]
begin
headers_output = generate_headers_array(status, headers)
headers_output << CONNECTION_CLOSE_CRLF2
connection.writev(headers_output)
connection.flush
hijacked_socket = env[RACK_HIJACK].call
hijack_callback.call(hijacked_socket)
return true
ensure
body.close if body && body.respond_to?(:close)
end
end
begin
process_body(env, connection, socket_wrapper, status.to_i, is_head_request,
headers, body)
rescue => e
if !should_swallow_app_error?(e, socket_wrapper)
print_exception("Rack response body object", e)
log_exception_to_union_station(env, e)
end
ensure
close_body(body, env, socket_wrapper)
end
false
ensure
rewindable_input.close
end
end