Protocol::RackSourceProtocolRackResponse

class Response

A wrapper for a Rack response.

A Rack response consisting of [status, headers, body] includes various rack-specific elements, including:

This wrapper takes those issues into account and adapts the rack response tuple into a Protocol::HTTP::Response.

Definitions

HOP_HEADERS = [...]

HTTP hop headers which should not be passed through the proxy.

Implementation

HOP_HEADERS = [
	"connection",
	"keep-alive",
	"public",
	"proxy-authenticate",
	"transfer-encoding",
	"upgrade",
]

def self.wrap(env, status, headers, meta, body, request = nil)

Wrap a rack response.

Signature

parameter status Integer

The rack response status.

parameter headers Duck(:each)

The rack response headers.

parameter body Duck(:each, :close) | Nil

The rack response body.

parameter request Protocol::HTTP::Request

The original request.

Implementation

def self.wrap(env, status, headers, meta, body, request = nil)
	ignored = headers.extract(HOP_HEADERS)
	
	unless ignored.empty?
		Console.warn(self, "Ignoring hop headers!", ignored: ignored)
	end

	if hijack_body = meta["rack.hijack"]
		body = hijack_body
	end

	body = Body.wrap(env, status, headers, body, request&.body)

	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

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

Initialize the response wrapper.

Signature

parameter status Integer

The response status.

parameter headers Protocol::HTTP::Headers

The response headers.

parameter body Protocol::HTTP::Body

The response body.

parameter protocol String

The response protocol for upgraded requests.

Implementation

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