module Puma::Request

def str_headers(env, status, headers, res_body, io_buffer, force_keep_alive)

Other tags:
    Version: - 5.0.3

Returns:
  • (Hash) - resp_info

Parameters:
  • force_keep_alive (Boolean) -- 'anded' with keep_alive, based on system
  • io_buffer (Puma::IOBuffer) -- modified inn place
  • content_length (Integer, nil) -- content length if it can be determined from the
  • headers (Hash) -- the headers returned by the Rack application
  • status (Integer) -- the status returned by the Rack application
  • env (Hash) -- see Puma::Client#env, from request
def str_headers(env, status, headers, res_body, io_buffer, force_keep_alive)
  line_ending = LINE_END
  colon = COLON
  resp_info = {}
  resp_info[:no_body] = env[REQUEST_METHOD] == HEAD
  http_11 = env[SERVER_PROTOCOL] == HTTP_11
  if http_11
    resp_info[:allow_chunked] = true
    resp_info[:keep_alive] = env.fetch(HTTP_CONNECTION, "").downcase != CLOSE
    # An optimization. The most common response is 200, so we can
    # reply with the proper 200 status without having to compute
    # the response header.
    #
    if status == 200
      io_buffer << HTTP_11_200
    else
      io_buffer.append "#{HTTP_11} #{status} ", fetch_status_code(status), line_ending
      resp_info[:no_body] ||= status < 200 || STATUS_WITH_NO_ENTITY_BODY[status]
    end
  else
    resp_info[:allow_chunked] = false
    resp_info[:keep_alive] = env.fetch(HTTP_CONNECTION, "").downcase == KEEP_ALIVE
    # Same optimization as above for HTTP/1.1
    #
    if status == 200
      io_buffer << HTTP_10_200
    else
      io_buffer.append "HTTP/1.0 #{status} ",
                   fetch_status_code(status), line_ending
      resp_info[:no_body] ||= status < 200 || STATUS_WITH_NO_ENTITY_BODY[status]
    end
  end
  # regardless of what the client wants, we always close the connection
  # if running without request queueing
  resp_info[:keep_alive] &&= @queue_requests
  # see prepare_response
  resp_info[:keep_alive] &&= force_keep_alive
  resp_info[:response_hijack] = nil
  headers.each do |k, vs|
    next if illegal_header_key?(k)
    case k.downcase
    when CONTENT_LENGTH2
      next if illegal_header_value?(vs)
      # nil.to_i is 0, nil&.to_i is nil
      resp_info[:content_length] = vs&.to_i
      next
    when TRANSFER_ENCODING
      resp_info[:allow_chunked] = false
      resp_info[:content_length] = nil
      resp_info[:transfer_encoding] = vs
    when HIJACK
      resp_info[:response_hijack] = vs
      next
    when BANNED_HEADER_KEY
      next
    end
    ary = if vs.is_a?(::Array) && !vs.empty?
      vs
    elsif vs.respond_to?(:to_s) && !vs.to_s.empty?
      vs.to_s.split NEWLINE
    else
      nil
    end
    if ary
      ary.each do |v|
        next if illegal_header_value?(v)
        io_buffer.append k, colon, v, line_ending
      end
    else
      io_buffer.append k, colon, line_ending
    end
  end
  # HTTP/1.1 & 1.0 assume different defaults:
  # - HTTP 1.0 assumes the connection will be closed if not specified
  # - HTTP 1.1 assumes the connection will be kept alive if not specified.
  # Only set the header if we're doing something which is not the default
  # for this protocol version
  if http_11
    io_buffer << CONNECTION_CLOSE if !resp_info[:keep_alive]
  else
    io_buffer << CONNECTION_KEEP_ALIVE if resp_info[:keep_alive]
  end
  resp_info
end