class PhusionPassenger::RequestHandler::ThreadHandler
def accept_and_process_next_request(socket_wrapper, channel, buffer)
def accept_and_process_next_request(socket_wrapper, channel, buffer) @stats_mutex.synchronize do @interruptable = true end if @last_connection connection = @last_connection channel.io = connection @last_connection = nil headers = parse_request(connection, channel, buffer) else connection = socket_wrapper.wrap(@server_socket.accept) end @stats_mutex.synchronize do @interruptable = false @iteration += 1 end trace(3, "Accepted new request on socket #{@socket_name}") if !headers # New socket accepted, instead of keeping-alive an old one channel.io = connection headers = parse_request(connection, channel, buffer) end if headers prepare_request(connection, headers) begin if headers[REQUEST_METHOD] == GET process_request(headers, connection, socket_wrapper, @protocol == :http) elsif headers[REQUEST_METHOD] == PING process_ping(headers, connection) elsif headers[REQUEST_METHOD] == OOBW process_oobw(headers, connection) else process_request(headers, connection, socket_wrapper, @protocol == :http) end rescue Exception has_error = true raise ensure if headers[RACK_HIJACK_IO] socket_wrapper = nil connection = nil channel = nil end finalize_request(connection, headers, has_error) trace(3, "Request done.") end else trace(2, "No headers parsed; disconnecting client.") end rescue Interrupted raise rescue => e if socket_wrapper && socket_wrapper.source_of_exception?(e) # EPIPE is harmless, it just means that the client closed the connection. # Other errors might indicate a problem so we print them, but they're # probably not bad enough to warrant stopping the request handler. if !e.is_a?(Errno::EPIPE) print_exception("Passenger RequestHandler's client socket", e) end else if headers PhusionPassenger.log_request_exception(headers, e) end raise e if should_reraise_error?(e) end ensure # Close connection if keep-alive not possible if connection && !connection.closed? && !@last_connection # The 'close_write' here prevents forked child # processes from unintentionally keeping the # connection open. begin connection.close_write rescue SystemCallError, IOError end begin connection.close rescue SystemCallError end end end