module Puma::Request
def handle_request(client, requests)
-
(Boolean, :async)
-
Parameters:
-
requests
(Integer
) -- -
client
(Puma::Client
) --
def handle_request(client, requests) env = client.env io_buffer = client.io_buffer socket = client.io # io may be a MiniSSL::Socket app_body = nil return false if closed_socket?(socket) if client.http_content_length_limit_exceeded return prepare_response(413, {}, ["Payload Too Large"], requests, client) end normalize_env env, client env[PUMA_SOCKET] = socket if env[HTTPS_KEY] && socket.peercert env[PUMA_PEERCERT] = socket.peercert end env[HIJACK_P] = true env[HIJACK] = client env[RACK_INPUT] = client.body env[RACK_URL_SCHEME] ||= default_server_port(env) == PORT_443 ? HTTPS : HTTP if @early_hints env[EARLY_HINTS] = lambda { |headers| begin unless (str = str_early_hints headers).empty? fast_write_str socket, "HTTP/1.1 103 Early Hints\r\n#{str}\r\n" end rescue ConnectionError => e @log_writer.debug_error e # noop, if we lost the socket we just won't send the early hints end } end req_env_post_parse env # A rack extension. If the app writes #call'ables to this # array, we will invoke them when the request is done. # env[RACK_AFTER_REPLY] ||= [] begin if @supported_http_methods == :any || @supported_http_methods.key?(env[REQUEST_METHOD]) status, headers, app_body = @thread_pool.with_force_shutdown do @app.call(env) end else @log_writer.log "Unsupported HTTP method used: #{env[REQUEST_METHOD]}" status, headers, app_body = [501, {}, ["#{env[REQUEST_METHOD]} method is not supported"]] end # app_body needs to always be closed, hold value in case lowlevel_error # is called res_body = app_body # full hijack, app called env['rack.hijack'] return :async if client.hijacked status = status.to_i if status == -1 unless headers.empty? and res_body == [] raise "async response must have empty headers and body" end return :async end rescue ThreadPool::ForceShutdown => e @log_writer.unknown_error e, client, "Rack app" @log_writer.log "Detected force shutdown of a thread" status, headers, res_body = lowlevel_error(e, env, 503) rescue Exception => e @log_writer.unknown_error e, client, "Rack app" status, headers, res_body = lowlevel_error(e, env, 500) end prepare_response(status, headers, res_body, requests, client) ensure io_buffer.reset uncork_socket client.io app_body.close if app_body.respond_to? :close client.tempfile&.unlink after_reply = env[RACK_AFTER_REPLY] || [] begin after_reply.each { |o| o.call } rescue StandardError => e @log_writer.debug_error e end unless after_reply.empty? end