### Home Classes Methods

### In Files

- lib/phusion_passenger/rack/thread_handler_extension.rb

### Methods

- #process_request

### Class/Module Index

Quicksearch

- PhusionPassenger
- PhusionPassenger::AbstractInstaller
- PhusionPassenger::AbstractInstaller::Abort
- PhusionPassenger::AbstractInstaller::CommandError
- PhusionPassenger::AdminTools
- PhusionPassenger::AdminTools::MemoryStats
- PhusionPassenger::AdminTools::MemoryStats::Process
- PhusionPassenger::AdminTools::ServerInstance
- PhusionPassenger::AdminTools::ServerInstance::CorruptedDirectoryError
- PhusionPassenger::AdminTools::ServerInstance::GenerationsAbsentError
- PhusionPassenger::AdminTools::ServerInstance::Group
- PhusionPassenger::AdminTools::ServerInstance::Process
- PhusionPassenger::AdminTools::ServerInstance::RoleDeniedError
- PhusionPassenger::AdminTools::ServerInstance::StaleDirectoryError
- PhusionPassenger::AdminTools::ServerInstance::Stats
- PhusionPassenger::AdminTools::ServerInstance::UnsupportedGenerationStructureVersionError
- PhusionPassenger::AnalyticsLogger
- PhusionPassenger::AnalyticsLogger::Connection
- PhusionPassenger::AnalyticsLogger::Lock
- PhusionPassenger::AnalyticsLogger::Log
- PhusionPassenger::ClassicRails
- PhusionPassenger::ClassicRails::CGIFixed
- PhusionPassenger::ClassicRails::ThreadHandlerExtension
- PhusionPassenger::ConsoleTextTemplate
- PhusionPassenger::DebugLogging
- PhusionPassenger::LoaderSharedHelpers
- PhusionPassenger::MessageChannel
- PhusionPassenger::MessageChannel::InvalidHashError
- PhusionPassenger::MessageClient
- PhusionPassenger::NativeSupportLoader
- PhusionPassenger::Packaging
- PhusionPassenger::PlatformInfo
- PhusionPassenger::PlatformInfo::Depcheck
- PhusionPassenger::PlatformInfo::Depcheck::ConsoleRunner
- PhusionPassenger::PlatformInfo::Depcheck::Dependency
- PhusionPassenger::PlatformInfo::RuntimeError
- PhusionPassenger::Plugin
- PhusionPassenger::PreloaderSharedHelpers
- PhusionPassenger::Rack
- PhusionPassenger::Rack::OutOfBandGc
- PhusionPassenger::Rack::ThreadHandlerExtension
- PhusionPassenger::Rails3Extensions
- PhusionPassenger::Rails3Extensions::AnalyticsLogging
- PhusionPassenger::Rails3Extensions::AnalyticsLogging::ACExtension
- PhusionPassenger::Rails3Extensions::AnalyticsLogging::ASBenchmarkableExtension
- PhusionPassenger::Rails3Extensions::AnalyticsLogging::ExceptionLogger
- PhusionPassenger::RequestHandler
- PhusionPassenger::RequestHandler::ThreadHandler
- PhusionPassenger::RequestHandler::ThreadHandler::Interrupted
- PhusionPassenger::SharedConstants
- PhusionPassenger::Standalone
- PhusionPassenger::Standalone::AppFinder
- PhusionPassenger::Standalone::Command
- PhusionPassenger::Standalone::ConfigFile
- PhusionPassenger::Standalone::ConfigFile::DisallowedContextError
- PhusionPassenger::Standalone::HelpCommand
- PhusionPassenger::Standalone::Main
- PhusionPassenger::Standalone::PackageRuntimeCommand
- PhusionPassenger::Standalone::RuntimeInstaller
- PhusionPassenger::Standalone::StartCommand
- PhusionPassenger::Standalone::StatusCommand
- PhusionPassenger::Standalone::StopCommand
- PhusionPassenger::Standalone::Utils
- PhusionPassenger::Standalone::VersionCommand
- PhusionPassenger::Utils
- PhusionPassenger::Utils::AnsiColors
- PhusionPassenger::Utils::FileSystemWatcher
- PhusionPassenger::Utils::FileSystemWatcher::DirInfo
- PhusionPassenger::Utils::FileSystemWatcher::FileInfo
- PhusionPassenger::Utils::HostsFileParser
- PhusionPassenger::Utils::TeeInput
- PhusionPassenger::Utils::TmpIO
- PhusionPassenger::Utils::UnseekableSocket
- CommonLibraryBuilder
- Exception
- GC
- IO
- Object
- Signal

No matching classes.

# PhusionPassenger::Rack::ThreadHandlerExtension

### Public Instance Methods

process_request(env, connection, socket_wrapper, full_http_response) click to toggle source

    # 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

[Validate]

Generated with the Darkfish Rdoc Generator 2.