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

new(app, &block) click to toggle source

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(env) click to toggle source

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