Class: Falcon::Adapters::Response
- Inherits:
-
Protocol::HTTP::Response
- Object
- Protocol::HTTP::Response
- Falcon::Adapters::Response
- Defined in:
- lib/falcon/adapters/response.rb
Overview
A wrapper for a `Rack` response.
A Rack response consisting of `[status, headers, body]` includes various rack-specific elements, including:
-
A `headers` callback which bypasses normal response handling.
-
Potentially invalid content length.
-
Potentially invalid body when processing a `HEAD` request.
-
Newline-separated header values.
-
Other `rack.` specific header key/value pairs.
This wrapper takes those issues into account and adapts the rack response tuple into a Protocol::HTTP::Response.
Constant Summary collapse
- IGNORE_HEADERS =
Middleware::Proxy::HOP_HEADERS
Class Method Summary collapse
-
.wrap(status, headers, body, request = nil) ⇒ Object
Wrap a rack response.
-
.wrap_headers(fields) ⇒ Object
Process the rack response headers into into a Protocol::HTTP::Headers instance, along with any extra `rack.` metadata.
Instance Method Summary collapse
-
#initialize(status, headers, body, protocol = nil) ⇒ Response
constructor
Initialize the response wrapper.
Constructor Details
#initialize(status, headers, body, protocol = nil) ⇒ Response
Initialize the response wrapper.
108 109 110 |
# File 'lib/falcon/adapters/response.rb', line 108 def initialize(status, headers, body, protocol = nil) super(nil, status, headers, body, protocol) end |
Class Method Details
.wrap(status, headers, body, request = nil) ⇒ Object
Wrap a rack response.
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/falcon/adapters/response.rb', line 72 def self.wrap(status, headers, body, request = nil) headers, = wrap_headers(headers) if block = ['rack.hijack'] body = Async::HTTP::Body::Hijack.wrap(request, &block) else ignored = headers.extract(IGNORE_HEADERS) unless ignored.empty? Console.logger.warn("Ignoring protocol-level headers: #{ignored.inspect}") end body = Output.wrap(status, headers, body) end if request&.head? # I thought about doing this in Output.wrap, but decided the semantics are too tricky. Specifically, the various ways a rack response body can be wrapped, and the need to invoke #close at the right point. body = ::Protocol::HTTP::Body::Head.for(body) end protocol = ['rack.protocol'] # https://tools.ietf.org/html/rfc7231#section-7.4.2 # headers.add('server', "falcon/#{Falcon::VERSION}") # https://tools.ietf.org/html/rfc7231#section-7.1.1.2 # headers.add('date', Time.now.httpdate) return self.new(status, headers, body, protocol) end |
.wrap_headers(fields) ⇒ Object
Process the rack response headers into into a Protocol::HTTP::Headers instance, along with any extra `rack.` metadata.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/falcon/adapters/response.rb', line 48 def self.wrap_headers(fields) headers = ::Protocol::HTTP::Headers.new = {} fields.each do |key, value| key = key.downcase if key.start_with?('rack.') [key] = value else value.to_s.split("\n").each do |part| headers.add(key, part) end end end return headers, end |