Sha256: 132a1a2790c1ab1f8468f4d9f79fa808f7aae735dbbd653e904f5c768bb36714

Contents?: true

Size: 1.93 KB

Versions: 40

Compression:

Stored size: 1.93 KB

Contents

require 'rack'

# 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.
class Rack::RelativeRedirect
  SCHEME_MAP = {'http'=>'80', 'https'=>'443'}
  # The default proc used if a block is not provided to .new
  # Just uses the url scheme of the request and the server name.
  DEFAULT_ABSOLUTE_PROC = proc do |env, res|
    port = env['SERVER_PORT']
    scheme = env['rack.url_scheme']
    "#{scheme}://#{env['SERVER_NAME']}#{":#{port}" unless SCHEME_MAP[scheme] == port}"
  end

  # 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 'http://example.org').
  def initialize(app, &block)
    @app = app
    @absolute_proc = block || DEFAULT_ABSOLUTE_PROC
  end

  # 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.
  def call(env)
    res = @app.call(env)
    if [301,302,303].include?(res[0]) and loc = res[1]['Location'] and !%r{\Ahttps?://}o.match(loc)
      absolute = @absolute_proc.call(env, res)
      res[1]['Location'] = if %r{\A/}.match(loc)
        "#{absolute}#{loc}"
      else
        "#{absolute}#{File.dirname(Rack::Utils.unescape(env['PATH_INFO']))}/#{loc}"
      end
    end
    res
  end
end

Version data entries

40 entries across 40 versions & 9 rubygems

Version Path
rack-contrib-1.2.0 lib/rack/contrib/relative_redirect.rb
cavalle-rack-contrib-1.0.0 lib/rack/contrib/relative_redirect.rb
rack-rack-contrib-0.9.1 lib/rack/contrib/relative_redirect.rb
rack-rack-contrib-0.9.2 lib/rack/contrib/relative_redirect.rb
tricycle-rack-contrib-0.9.3 lib/rack/contrib/relative_redirect.rb
olelo-0.9.15 lib/rack/relative_redirect.rb
olelo-0.9.14 lib/rack/relative_redirect.rb
olelo-0.9.13 lib/rack/relative_redirect.rb
olelo-0.9.12 lib/rack/relative_redirect.rb
olelo-0.9.11 lib/rack/relative_redirect.rb
olelo-0.9.10 lib/rack/relative_redirect.rb
olelo-0.9.9 lib/rack/relative_redirect.rb
olelo-0.9.8 lib/rack/relative_redirect.rb
olelo-0.9.7 lib/rack/relative_redirect.rb
olelo-0.9.6 lib/rack/relative_redirect.rb
olelo-0.9.5 lib/rack/relative_redirect.rb
olelo-0.9.4 lib/rack/relative_redirect.rb
olelo-0.9.3 lib/rack/relative_redirect.rb
olelo-0.9.2 lib/rack/relative_redirect.rb
olelo-0.9.1 lib/rack/relative_redirect.rb