# File lib/phusion_passenger/rack/thread_handler_extension.rb, line 53 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 begin status, headers, body = @app.call(env) rescue => e if should_reraise_app_error?(e, socket_wrapper) raise e elsif !should_swallow_app_error?(e, socket_wrapper) # It's a good idea to catch application exceptions here because # otherwise maliciously crafted responses can crash the app, # forcing it to be respawned, and thereby effectively DoSing it. print_exception("Rack application object", e) end return false end # Application requested a full socket hijack. return true if env[RACK_HIJACK_IO] begin if full_http_response connection.write("HTTP/1.1 #{status.to_i.to_s} Whatever#{CRLF}") connection.write("Connection: close#{CRLF}") end headers_output = [ STATUS, status.to_i.to_s, CRLF ] headers.each do |key, values| if values.is_a?(String) values = values.split(NEWLINE) elsif key == RACK_HIJACK # We do not check for this key name in every loop # iteration as an optimization. next 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 hijack_callback = headers[RACK_HIJACK] # Application requested a partial socket hijack. body = nil connection.writev(headers_output) connection.flush hijacked_socket = env[RACK_HIJACK].call hijack_callback.call(hijacked_socket) return true elsif 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. connection.writev2(headers_output, body.to_a) return false elsif body.is_a?(String) headers_output << body connection.writev(headers_output) return false else connection.writev(headers_output) if body begin body.each do |s| connection.write(s) end rescue => e if should_reraise_app_error?(e, socket_wrapper) raise e elsif !should_swallow_app_error?(e, socket_wrapper) # Body objects can raise exceptions in #each. print_exception("Rack body object #each method", e) end return false end end return false end ensure body.close if body && body.respond_to?(:close) end ensure rewindable_input.close end end
Generated with the Darkfish Rdoc Generator 2.