Protocol::HTTPSourceProtocolHTTPResponse

class Response

Represents an HTTP response which can be used both server and client-side.

require 'protocol/http'

# Long form:
Protocol::HTTP::Response.new("http/1.1", 200, Protocol::HTTP::Headers[["content-type", "text/html"]], Protocol::HTTP::Body::Buffered.wrap("Hello, World!"))

# Short form:
Protocol::HTTP::Response[200, {"content-type" => "text/html"}, ["Hello, World!"]]

Definitions

def initialize(version = nil, status = 200, headers = Headers.new, body = nil, protocol = nil)

Create a new response.

Signature

parameter version String | Nil

The HTTP version, e.g. "HTTP/1.1". If nil, the version may be provided by the server sending the response.

parameter status Integer

The HTTP status code, e.g. 200, 404, etc.

parameter headers Hash

The headers, e.g. {"content-type" => "text/html"}, etc.

parameter body Body::Readable

The body, e.g. "Hello, World!", etc.

parameter protocol String | Array(String)

The protocol, e.g. "websocket", etc.

Implementation

def initialize(version = nil, status = 200, headers = Headers.new, body = nil, protocol = nil)
	@version = version
	@status = status
	@headers = headers
	@body = body
	@protocol = protocol
end

attr_accessor :version

Signature

attribute String | Nil

The HTTP version, usually one of "HTTP/1.1", "HTTP/2", etc.

attr_accessor :status

Signature

attribute Integer

The HTTP status code, e.g. 200, 404, etc.

attr_accessor :headers

Signature

attribute Hash

The headers, e.g. {"content-type" => "text/html"}, etc.

attr_accessor :body

Signature

attribute Body::Readable

The body, e.g. "Hello, World!", etc.

attr_accessor :protocol

Signature

attribute String | Array(String) | Nil

The protocol, e.g. "websocket", etc.

def peer

A response that is generated by a client, may choose to include the peer (address) associated with the response. It should be implemented by a sub-class.

Signature

returns Peer | Nil

The peer (address) associated with the response.

Implementation

def peer
	nil
end

def hijack?

Whether the response is considered a hijack: the connection has been taken over by the application and the server should not send any more data.

Implementation

def hijack?
	false
end

def continue?

Whether the status is 100 (continue).

Implementation

def continue?
	@status == 100
end

def informational?

Whether the status is considered informational.

Implementation

def informational?
	@status and @status >= 100 && @status < 200
end

def final?

Whether the status is considered final. Note that 101 is considered final.

Implementation

def final?
	# 101 is effectively a final status.
	@status and @status >= 200 || @status == 101
end

def ok?

Whether the status is 200 (ok).

Implementation

def ok?
	@status == 200
end

def success?

Whether the status is considered successful.

Implementation

def success?
	@status and @status >= 200 && @status < 300
end

def partial?

Whether the status is 206 (partial content).

Implementation

def partial?
	@status == 206
end

def redirection?

Whether the status is considered a redirection.

Implementation

def redirection?
	@status and @status >= 300 && @status < 400
end

def not_modified?

Whether the status is 304 (not modified).

Implementation

def not_modified?
	@status == 304
end

def preserve_method?

Whether the status is 307 (temporary redirect) and should preserve the method of the request when following the redirect.

Implementation

def preserve_method?
	@status == 307 || @status == 308
end

def failure?

Whether the status is considered a failure.

Implementation

def failure?
	@status and @status >= 400 && @status < 600
end

def bad_request?

Whether the status is 400 (bad request).

Implementation

def bad_request?
	@status == 400
end

def internal_server_error?

Whether the status is 500 (internal server error).

Implementation

def internal_server_error?
	@status == 500
end

def self.[](status, _headers = nil, _body = nil, headers: _headers, body: _body, protocol: nil)

A short-cut method which exposes the main response variables that you'd typically care about. It follows the same order as the Rack response tuple, but also includes the protocol.

	Response[200, {"content-type" => "text/html"}, ["Hello, World!"]]

Signature

parameter status Integer

The HTTP status code, e.g. 200, 404, etc.

parameter headers Hash

The headers, e.g. {"content-type" => "text/html"}, etc.

parameter body String | Array(String) | Body::Readable

The body, e.g. "Hello, World!", etc. See Protocol::HTTP::Body::Buffered.wrap for more information about .

Implementation

def self.[](status, _headers = nil, _body = nil, headers: _headers, body: _body, protocol: nil)
	body = Body::Buffered.wrap(body)
	headers = Headers[headers]
	
	self.new(nil, status, headers, body, protocol)
end

def self.for_exception(exception)

Create a response for the given exception.

Signature

parameter exception Exception

The exception to generate the response for.

Implementation

def self.for_exception(exception)
	Response[500, Headers["content-type" => "text/plain"], ["#{exception.class}: #{exception.message}"]]
end

def as_json(...)

Convert the response to a hash suitable for serialization.

Signature

returns Hash

The response as a hash.

Implementation

def as_json(...)
	{
		version: @version,
		status: @status,
		headers: @headers&.as_json,
		body: @body&.as_json,
		protocol: @protocol
	}
end

def to_json(...)

Convert the response to JSON.

Signature

returns String

The response as JSON.

Implementation

def to_json(...)
	as_json.to_json(...)
end

def to_s

Summarise the response as a string.

Signature

returns String

The response as a string.

Implementation

def to_s
	"#{@status} #{@version}"
end

def to_ary

Implicit conversion to an array.

Signature

returns Array

The response as an array, e.g. [status, headers, body].

Implementation

def to_ary
	return @status, @headers, @body
end