Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #8297: redirect_with_status_and_back_default.diff

File redirect_with_status_and_back_default.diff, 5.8 kB (added by codahale, 2 years ago)

Better patch, now including redirect back with default.

  • test/controller/redirect_test.rb

    old new  
    4848  def redirect_to_new_record 
    4949    redirect_to Workshop.new(5, true) 
    5050  end 
     51   
     52  def redirect_with_status 
     53    redirect_to({:action => "hello_world"}, {:status => 301}) 
     54  end 
     55   
     56  def url_redirect_with_status 
     57    redirect_to("http://www.example.com", {:status => 301}) 
     58  end 
     59   
     60  def relative_url_redirect_with_status 
     61    redirect_to("/things/stuff", {:status => :moved_permanently}) 
     62  end 
     63   
     64  def redirect_to_back_with_status 
     65    redirect_to :back, :status => :temporary_redirect 
     66  end 
     67   
     68  def redirect_to_back_with_default 
     69    redirect_to :back, :default => "http://www.example.com" 
     70  end 
    5171 
    5272  def rescue_errors(e) raise e end 
    5373     
     
    137157    get :redirect_to_new_record 
    138158    assert_equal "http://test.host/workshops", redirect_to_url 
    139159  end 
     160   
     161  def test_redirect_with_status 
     162    get :redirect_with_status 
     163    assert_response 301 
     164    assert_equal "http://test.host/redirect/hello_world", redirect_to_url 
     165  end 
     166   
     167  def test_url_redirect_with_status 
     168    get :url_redirect_with_status 
     169    assert_response 301 
     170    assert_equal "http://www.example.com", redirect_to_url 
     171  end 
     172   
     173  def test_relative_url_redirect_with_status 
     174    get :relative_url_redirect_with_status 
     175    assert_response 301 
     176    assert_equal "http://test.host/things/stuff", redirect_to_url 
     177  end 
     178   
     179  def test_redirect_to_back_with_status 
     180    @request.env["HTTP_REFERER"] = "http://www.example.com/coming/from" 
     181    get :redirect_to_back_with_status 
     182    assert_response 307 
     183    assert_equal "http://www.example.com/coming/from", redirect_to_url 
     184  end 
     185   
     186  def test_redirect_to_back_with_default 
     187    get :redirect_to_back_with_default 
     188    assert_response :redirect 
     189    assert_equal "http://www.example.com", redirect_to_url 
     190  end 
    140191end 
    141192 
    142193module ModuleTest 
  • lib/action_controller/base.rb

    old new  
    11require 'action_controller/mime_type' 
    22require 'action_controller/request' 
     3require 'action_controller/status_codes' 
    34require 'action_controller/response' 
    45require 'action_controller/routing' 
    56require 'action_controller/resources' 
    67require 'action_controller/url_rewriter' 
    7 require 'action_controller/status_codes' 
    88require 'drb' 
    99require 'set' 
    1010 
     
    10101010      #   redirect_to "/images/screenshot.jpg" 
    10111011      #   redirect_to :back 
    10121012      # 
    1013       # The redirection happens as a "302 Moved" header. 
     1013      # The redirection happens as a "302 Moved" header, unless a <tt>:status</tt> parameter is specified: 
     1014      #   redirect_to "http://www.rubyonrails.org", :status => 301 
     1015      #   redirect_to({ :controller => "posts", :action => "show", :id => @post },{ :status => 301 }) 
    10141016      # 
    10151017      # When using <tt>redirect_to :back</tt>, if there is no referrer, 
    10161018      # RedirectBackError will be raised. You may specify some fallback 
    1017       # behavior for this case by rescueing RedirectBackError. 
    1018       def redirect_to(options = {}) #:doc: 
     1019      # behavior for this case by rescuing RedirectBackError or specifying a <tt>:default</tt> parameter: 
     1020      #   redirect_to :back, :default => { :controller => "home", :action => "index" } 
     1021      def redirect_to(options = {}, redirect_options = {}) #:doc: 
    10191022        case options 
    10201023          when %r{^\w+://.*} 
    10211024            raise DoubleRenderError if performed? 
    10221025            logger.info("Redirected to #{options}") if logger 
    1023             response.redirect(options
     1026            response.redirect(options, redirect_options[:status]
    10241027            response.redirected_to = options 
    10251028            @performed_redirect = true 
    10261029 
    10271030          when String 
    1028             redirect_to(request.protocol + request.host_with_port + options
     1031            redirect_to(request.protocol + request.host_with_port + options, redirect_options
    10291032 
    10301033          when :back 
    1031             request.env["HTTP_REFERER"] ? redirect_to(request.env["HTTP_REFERER"]) : raise(RedirectBackError) 
     1034            if request.env["HTTP_REFERER"] 
     1035              redirect_to(request.env["HTTP_REFERER"], redirect_options) 
     1036            elsif redirect_options[:default] 
     1037              redirect_to(redirect_options[:default], redirect_options) 
     1038            else 
     1039              raise(RedirectBackError) 
     1040            end 
    10321041 
    10331042          else 
    1034             redirect_to(url_for(options)
     1043            redirect_to(url_for(options), redirect_options
    10351044            response.redirected_to = options 
    10361045        end 
    10371046      end 
  • lib/action_controller/response.rb

    old new  
    22 
    33module ActionController 
    44  class AbstractResponse #:nodoc: 
     5    include StatusCodes 
    56    DEFAULT_HEADERS = { "Cache-Control" => "no-cache" } 
     7    DEFAULT_REDIRECT_STATUS_CODE = 302 # Found 
    68    attr_accessor :request 
    79    attr_accessor :body, :headers, :session, :cookies, :assigns, :template, :redirected_to, :redirected_to_method_params, :layout 
    810 
     
    2830      charset.blank? ? nil : charset.strip.split("=")[1] 
    2931    end 
    3032 
    31     def redirect(to_url, permanently = false
    32       self.headers["Status"]   = "302 Found" unless headers["Status"] == "301 Moved Permanently" 
     33    def redirect(to_url, status = nil
     34      self.headers["Status"] = interpret_status(status || DEFAULT_REDIRECT_STATUS_CODE) unless headers["Status"] == "301 Moved Permanently" 
    3335      self.headers["Location"] = to_url 
    3436 
    3537      self.body = "<html><body>You are being <a href=\"#{to_url}\">redirected</a>.</body></html>"