Repository: rails/rails
File: actionpack/lib/action_controller/metal/redirecting.rb (Ruby)

Code before:
    #     different to the current host, defaults to true.
    #
    #
    # All other options that can be passed to #redirect_to are accepted as options,
    # and the behavior is identical.
    def redirect_back_or_to(fallback_location, allow_other_host: _allow_other_host, **options)
      if request.referer && (allow_other_host || _url_host_allowed?(request.referer))
        redirect_to request.referer, allow_other_host: allow_other_host, **options
      else
        # The method level `allow_other_host` doesn't apply in the fallback case, omit
        # and let the `redirect_to` handling take over.
        redirect_to fallback_location, **options
      end
    end

    def _compute_redirect_to_location(request, options) # :nodoc:
      case options
      # The scheme name consist of a letter followed by any combination of letters,
      # digits, and the plus ("+"), period ("."), or hyphen ("-") characters; and is
      # terminated by a colon (":"). See
      # https://tools.ietf.org/html/rfc3986#section-3.1 The protocol relative scheme
      # starts with a double slash "//".
      when /\A([a-z][a-z\d\-+.]*:|\/\/).*/i
        options.to_str
      when String
        if !options.start_with?("/") && !options.start_with?("?") && !options.empty?
          _handle_path_relative_redirect(options)
        end

        request.protocol + request.host_with_port + options
      when Proc
        _compute_redirect_to_location request, instance_eval(&options)
      else
        url_for(options)
      end.delete("\0\r\n")
    end
    module_function :_compute_redirect_to_location
    public :_compute_redirect_to_location

    # Verifies the passed `location` is an internal URL that's safe to redirect to
    # and returns it, or nil if not. Useful to wrap a params provided redirect URL
    # and fall back to an alternate URL to redirect to:
    #
    #     redirect_to url_from(params[:redirect_url]) || root_url
    #
    # The `location` is considered internal, and safe, if it's on the same host as
    # `request.host`:
    #
    #     # If request.host is example.com:
    #     url_from("https://example.com/profile") # => "https://example.com/profile"
    #     url_from("http://example.com/profile")  # => "http://example.com/profile"

Review comment (suggestion):
```suggestion
        if !options.start_with?("/", "?") && !options.empty?
```

Code after:
    #     different to the current host, defaults to true.
    #
    #
    # All other options that can be passed to #redirect_to are accepted as options,
    # and the behavior is identical.
    def redirect_back_or_to(fallback_location, allow_other_host: _allow_other_host, **options)
      if request.referer && (allow_other_host || _url_host_allowed?(request.referer))
        redirect_to request.referer, allow_other_host: allow_other_host, **options
      else
        # The method level `allow_other_host` doesn't apply in the fallback case, omit
        # and let the `redirect_to` handling take over.
        redirect_to fallback_location, **options
      end
    end

    def _compute_redirect_to_location(request, options) # :nodoc:
      case options
      # The scheme name consist of a letter followed by any combination of letters,
      # digits, and the plus ("+"), period ("."), or hyphen ("-") characters; and is
      # terminated by a colon (":"). See
      # https://tools.ietf.org/html/rfc3986#section-3.1 The protocol relative scheme
      # starts with a double slash "//".
      when /\A([a-z][a-z\d\-+.]*:|\/\/).*/i
        options.to_str
      when String
        if !options.start_with?("/", "?") && !options.empty?
          _handle_path_relative_redirect(options)
        end

        request.protocol + request.host_with_port + options
      when Proc
        _compute_redirect_to_location request, instance_eval(&options)
      else
        url_for(options)
      end.delete("\0\r\n")
    end
    module_function :_compute_redirect_to_location
    public :_compute_redirect_to_location

    # Verifies the passed `location` is an internal URL that's safe to redirect to
    # and returns it, or nil if not. Useful to wrap a params provided redirect URL
    # and fall back to an alternate URL to redirect to:
    #
    #     redirect_to url_from(params[:redirect_url]) || root_url
    #
    # The `location` is considered internal, and safe, if it's on the same host as
    # `request.host`:
    #
    #     # If request.host is example.com:
    #     url_from("https://example.com/profile") # => "https://example.com/profile"
    #     url_from("http://example.com/profile")  # => "http://example.com/profile"