Class: Falcon::Adapters::Response

Inherits:
Protocol::HTTP::Response
  • Object
show all
Defined in:
lib/falcon/adapters/response.rb

Constant Summary collapse

IGNORE_HEADERS =
Middleware::Proxy::HOP_HEADERS

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(status, headers, body, protocol = nil) ⇒ Response

Returns a new instance of Response.



86
87
88
# File 'lib/falcon/adapters/response.rb', line 86

def initialize(status, headers, body, protocol = nil)
  super(nil, status, headers, body, protocol)
end

Class Method Details

.wrap(status, headers, body, request = nil) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/falcon/adapters/response.rb', line 55

def self.wrap(status, headers, body, request = nil)
  headers, meta = wrap_headers(headers)
  
  if block = meta['rack.hijack']
    body = Async::HTTP::Body::Hijack.wrap(request, &block)
  else
    ignored = headers.extract(IGNORE_HEADERS)
    
    unless ignored.empty?
      Async.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 = meta['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

Append a list of newline encoded headers.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/falcon/adapters/response.rb', line 36

def self.wrap_headers(fields)
  headers = ::Protocol::HTTP::Headers.new
  meta = {}
  
  fields.each do |key, value|
    key = key.downcase
    
    if key.start_with?('rack.')
      meta[key] = value
    else
      value.to_s.split("\n").each do |part|
        headers.add(key, part)
      end
    end
  end
  
  return headers, meta
end