Class: Protocol::Rack::Adapter::Generic

Inherits:
Object
  • Object
show all
Defined in:
lib/protocol/rack/adapter/generic.rb

Direct Known Subclasses

Rack2, Rack3

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app) ⇒ Generic

Initialize the rack adaptor middleware.

Raises:

  • (ArgumentError)


39
40
41
42
43
# File 'lib/protocol/rack/adapter/generic.rb', line 39

def initialize(app)
  @app = app
  
  raise ArgumentError, "App must be callable!" unless @app.respond_to?(:call)
end

Class Method Details

.wrap(app) ⇒ Object



33
34
35
# File 'lib/protocol/rack/adapter/generic.rb', line 33

def self.wrap(app)
  self.new(app)
end

Instance Method Details

#call(request) ⇒ Object

Build a rack ‘env` from the incoming request and apply it to the rack middleware.



101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/protocol/rack/adapter/generic.rb', line 101

def call(request)
  env = self.make_environment(request)
  
  status, headers, body = @app.call(env)
  
  return Response.wrap(status, headers, body, request)
rescue => exception
  Console.logger.error(self) {exception}
  
  body&.close if body.respond_to?(:close)

  return failure_response(exception)
end

#loggerObject



45
46
47
# File 'lib/protocol/rack/adapter/generic.rb', line 45

def logger
  Console.logger
end

#unwrap_headers(headers, env) ⇒ Object

Unwrap raw HTTP headers into the CGI-style expected by Rack middleware.

Rack separates multiple headers with the same key, into a single field with multiple lines.



55
56
57
58
59
60
61
62
63
64
65
# File 'lib/protocol/rack/adapter/generic.rb', line 55

def unwrap_headers(headers, env)
  headers.each do |key, value|
    http_key = "HTTP_#{key.upcase.tr('-', '_')}"
    
    if current_value = env[http_key]
      env[http_key] = "#{current_value};#{value}"
    else
      env[http_key] = value
    end
  end
end

#unwrap_request(request, env) ⇒ Object

Process the incoming request into a valid rack ‘env`.

  • Set the ‘env` and `env` based on the incoming request body.

  • Set the ‘env` header to the request authority.

  • Set the ‘env` header to the request scheme.

  • Set ‘env` to the request remote adress.



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/protocol/rack/adapter/generic.rb', line 76

def unwrap_request(request, env)
  if content_type = request.headers.delete('content-type')
    env[CGI::CONTENT_TYPE] = content_type
  end
  
  # In some situations we don't know the content length, e.g. when using chunked encoding, or when decompressing the body.
  if body = request.body and length = body.length
    env[CGI::CONTENT_LENGTH] = length.to_s
  end
  
  self.unwrap_headers(request.headers, env)
  
  # HTTP/2 prefers `:authority` over `host`, so we do this for backwards compatibility.
  env[CGI::HTTP_HOST] ||= request.authority
        
  if request.respond_to?(:remote_address)
    if remote_address = request.remote_address
      env[CGI::REMOTE_ADDR] = remote_address.ip_address if remote_address.ip?
    end
  end
end