class Rack::RelativeRedirect
Rack::RelativeRedirect
is a simple middleware that converts relative paths in redirects in absolute urls, so they conform to RFC2616. It allows the user to specify the absolute path to use (with a sensible default), and handles relative paths (those that don't start with a slash) as well.
Constants
- DEFAULT_ABSOLUTE_PROC
The default proc used if a block is not provided to .new Just uses the url scheme of the request and the server name.
- SCHEME_MAP
Public Class Methods
Initialize a new RelativeRedirect
object with the given arguments. Arguments:
-
app : The next middleware in the chain. This is always called.
-
&block : If provided, it is called with the environment and the response from the next middleware. It should return a string representing the scheme and server name (such as 'example.org').
# File lib/rack/contrib/relative_redirect.rb 24 def initialize(app, &block) 25 @app = app 26 @absolute_proc = block || DEFAULT_ABSOLUTE_PROC 27 end
Public Instance Methods
Call the next middleware with the environment. If the request was a redirect (response status 301, 302, or 303), and the location header does not start with an http or https url scheme, call the block provided by new and use that to make the Location header an absolute url. If the Location does not start with a slash, make location relative to the path requested.
# File lib/rack/contrib/relative_redirect.rb 34 def call(env) 35 status, headers, body = @app.call(env) 36 headers = Rack::Utils::HeaderHash.new(headers) 37 38 if [301,302,303, 307,308].include?(status) and loc = headers['Location'] and !%r{\Ahttps?://}o.match(loc) 39 absolute = @absolute_proc.call(env, [status, headers, body]) 40 headers['Location'] = if %r{\A/}.match(loc) 41 "#{absolute}#{loc}" 42 else 43 "#{absolute}#{File.dirname(Rack::Utils.unescape(env['PATH_INFO']))}/#{loc}" 44 end 45 end 46 47 [status, headers, body] 48 end