UtopiaSourceUtopiaRedirectionClientRedirect

class ClientRedirect

A basic client-side redirect.

Definitions

def initialize(app, status: 307, max_age: DEFAULT_MAX_AGE)

Initialize client-side redirection behavior.

Signature

parameter app Interface(:call)

The downstream application.

parameter status Integer

The status.

parameter max_age Integer

The maximum cache age in seconds.

Implementation

def initialize(app, status: 307, max_age: DEFAULT_MAX_AGE)
	@app = app
	@status = status
	@max_age = max_age
end

def freeze

Freeze this object and its internal state.

Signature

returns self

This object.

Implementation

def freeze
	return self if frozen?
	
	@status.freeze
	@max_age.freeze
	
	super
end

def cache_control

Build the cache control header value.

Signature

returns String

The cache-control value.

Implementation

def cache_control
	# http://jacquesmattheij.com/301-redirects-a-dangerous-one-way-street
	"max-age=#{self.max_age}"
end

def make_headers(location)

Build headers for a client redirect.

Signature

parameter location String

The redirect location.

returns Hash(String, String)

The redirect headers.

Implementation

def make_headers(location)
	{
		HTTP::LOCATION => location,
		HTTP::CACHE_CONTROL => self.cache_control
	}
end

def redirect(location)

Build a redirect response for the given location.

Signature

parameter location String

The redirect location.

returns Array

The redirect response.

Implementation

def redirect(location)
	return [self.status, self.make_headers(location), []]
end

def [](path)

Resolve a normalized request path to a redirect response.

Signature

parameter path String

The normalized request path.

returns Array | false

The redirect response, or false by default.

Implementation

def [] path
	false
end

def call(env)

Redirect a normalized request path when it matches, otherwise invoke the application.

Signature

parameter env Hash

The Rack environment.

returns Array

The redirect or downstream Rack response.

Implementation

def call(env)
	# Normalize the path to remove redundant slashes, `.` and `..` segments.
	# This prevents protocol-relative redirect URLs (e.g. //evil.com/index)
	# from being generated when PATH_INFO contains a double leading slash.
	path = Path.create(env[Rack::PATH_INFO]).simplify.to_s
	
	if redirection = self[path]
		return redirection
	end
	
	return @app.call(env)
end