diff options
Diffstat (limited to 'actionpack/lib')
-rw-r--r-- | actionpack/lib/action_controller.rb | 1 | ||||
-rw-r--r-- | actionpack/lib/action_controller/base.rb | 1 | ||||
-rw-r--r-- | actionpack/lib/action_controller/metal/etag_with_flash.rb | 16 | ||||
-rw-r--r-- | actionpack/lib/action_controller/test_case.rb | 9 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/http/url.rb | 86 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/middleware/ssl.rb | 10 |
6 files changed, 56 insertions, 67 deletions
diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index fc86a907b3..50f20aa789 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -23,6 +23,7 @@ module ActionController autoload :Cookies autoload :DataStreaming autoload :EtagWithTemplateDigest + autoload :EtagWithFlash autoload :Flash autoload :ForceSSL autoload :Head diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 68a526eccb..ca8066cd82 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -213,6 +213,7 @@ module ActionController Renderers::All, ConditionalGet, EtagWithTemplateDigest, + EtagWithFlash, Caching, MimeResponds, ImplicitRender, diff --git a/actionpack/lib/action_controller/metal/etag_with_flash.rb b/actionpack/lib/action_controller/metal/etag_with_flash.rb new file mode 100644 index 0000000000..474d75f02e --- /dev/null +++ b/actionpack/lib/action_controller/metal/etag_with_flash.rb @@ -0,0 +1,16 @@ +module ActionController + # When you're using the flash, it's generally used as a conditional on the view. + # This means the content of the view depends on the flash. Which in turn means + # that the etag for a response should be computed with the content of the flash + # in mind. This does that by including the content of the flash as a component + # in the etag that's generated for a response. + module EtagWithFlash + extend ActiveSupport::Concern + + include ActionController::ConditionalGet + + included do + etag { flash unless flash.empty? } + end + end +end diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 83c32136dd..11a6cf8e15 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -449,6 +449,8 @@ module ActionController # - +session+: A hash of parameters to store in the session. This may be +nil+. # - +flash+: A hash of parameters to store in the flash. This may be +nil+. # - +format+: Request format. Defaults to +nil+. Can be string or symbol. + # - +as+: Content type. Defaults to +nil+. Must be a symbol that corresponds + # to a mime type. # # Example calling +create+ action and sending two params: # @@ -469,7 +471,7 @@ module ActionController check_required_ivars if kwarg_request?(args) - parameters, session, body, flash, http_method, format, xhr = args[0].values_at(:params, :session, :body, :flash, :method, :format, :xhr) + parameters, session, body, flash, http_method, format, xhr, as = args[0].values_at(:params, :session, :body, :flash, :method, :format, :xhr, :as) else http_method, parameters, session, flash = args format = nil @@ -514,6 +516,11 @@ module ActionController @request.set_header "REQUEST_METHOD", http_method + if as + @request.content_type = Mime[as].to_s + format ||= as + end + parameters = parameters.symbolize_keys generated_extras = @routes.generate_extras(parameters.merge(controller: controller_class_name, action: action.to_s)) diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index e85ea90b94..06ffa983d1 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -192,11 +192,7 @@ module ActionDispatch # Returns the complete URL used for this request. # - # class Request < Rack::Request - # include ActionDispatch::Http::URL - # end - # - # req = Request.new 'HTTP_HOST' => 'example.com' + # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com' # req.url # => "http://example.com" def url protocol + host_with_port + fullpath @@ -204,14 +200,10 @@ module ActionDispatch # Returns 'https://' if this is an SSL request and 'http://' otherwise. # - # class Request < Rack::Request - # include ActionDispatch::Http::URL - # end - # - # req = Request.new 'HTTP_HOST' => 'example.com' + # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com' # req.protocol # => "http://" # - # req = Request.new 'HTTP_HOST' => 'example.com', 'HTTPS' => 'on' + # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com', 'HTTPS' => 'on' # req.protocol # => "https://" def protocol @protocol ||= ssl? ? "https://" : "http://" @@ -219,17 +211,13 @@ module ActionDispatch # Returns the \host and port for this request, such as "example.com:8080". # - # class Request < Rack::Request - # include ActionDispatch::Http::URL - # end - # - # req = Request.new 'HTTP_HOST' => 'example.com' + # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com' # req.raw_host_with_port # => "example.com" # - # req = Request.new 'HTTP_HOST' => 'example.com:80' + # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80' # req.raw_host_with_port # => "example.com:80" # - # req = Request.new 'HTTP_HOST' => 'example.com:8080' + # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080' # req.raw_host_with_port # => "example.com:8080" def raw_host_with_port if forwarded = x_forwarded_host.presence @@ -241,11 +229,7 @@ module ActionDispatch # Returns the host for this request, such as "example.com". # - # class Request < Rack::Request - # include ActionDispatch::Http::URL - # end - # - # req = Request.new 'HTTP_HOST' => 'example.com:8080' + # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080' # req.host # => "example.com" def host raw_host_with_port.sub(/:\d+$/, "".freeze) @@ -255,17 +239,13 @@ module ActionDispatch # "example.com:8080". Port is only included if it is not a default port # (80 or 443) # - # class Request < Rack::Request - # include ActionDispatch::Http::URL - # end - # - # req = Request.new 'HTTP_HOST' => 'example.com' + # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com' # req.host_with_port # => "example.com" # - # req = Request.new 'HTTP_HOST' => 'example.com:80' + # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80' # req.host_with_port # => "example.com" # - # req = Request.new 'HTTP_HOST' => 'example.com:8080' + # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080' # req.host_with_port # => "example.com:8080" def host_with_port "#{host}#{port_string}" @@ -273,14 +253,10 @@ module ActionDispatch # Returns the port number of this request as an integer. # - # class Request < Rack::Request - # include ActionDispatch::Http::URL - # end - # - # req = Request.new 'HTTP_HOST' => 'example.com' + # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com' # req.port # => 80 # - # req = Request.new 'HTTP_HOST' => 'example.com:8080' + # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080' # req.port # => 8080 def port @port ||= begin @@ -294,11 +270,7 @@ module ActionDispatch # Returns the standard \port number for this request's protocol. # - # class Request < Rack::Request - # include ActionDispatch::Http::URL - # end - # - # req = Request.new 'HTTP_HOST' => 'example.com:8080' + # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080' # req.standard_port # => 80 def standard_port case protocol @@ -309,14 +281,10 @@ module ActionDispatch # Returns whether this request is using the standard port # - # class Request < Rack::Request - # include ActionDispatch::Http::URL - # end - # - # req = Request.new 'HTTP_HOST' => 'example.com:80' + # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80' # req.standard_port? # => true # - # req = Request.new 'HTTP_HOST' => 'example.com:8080' + # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080' # req.standard_port? # => false def standard_port? port == standard_port @@ -325,14 +293,10 @@ module ActionDispatch # Returns a number \port suffix like 8080 if the \port number of this request # is not the default HTTP \port 80 or HTTPS \port 443. # - # class Request < Rack::Request - # include ActionDispatch::Http::URL - # end - # - # req = Request.new 'HTTP_HOST' => 'example.com:80' + # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80' # req.optional_port # => nil # - # req = Request.new 'HTTP_HOST' => 'example.com:8080' + # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080' # req.optional_port # => 8080 def optional_port standard_port? ? nil : port @@ -341,14 +305,10 @@ module ActionDispatch # Returns a string \port suffix, including colon, like ":8080" if the \port # number of this request is not the default HTTP \port 80 or HTTPS \port 443. # - # class Request < Rack::Request - # include ActionDispatch::Http::URL - # end - # - # req = Request.new 'HTTP_HOST' => 'example.com:80' + # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80' # req.port_string # => "" # - # req = Request.new 'HTTP_HOST' => 'example.com:8080' + # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080' # req.port_string # => ":8080" def port_string standard_port? ? "" : ":#{port}" @@ -356,14 +316,10 @@ module ActionDispatch # Returns the requested port, such as 8080, based on SERVER_PORT # - # class Request < Rack::Request - # include ActionDispatch::Http::URL - # end - # - # req = Request.new 'SERVER_PORT' => '80' + # req = ActionDispatch::Request.new 'SERVER_PORT' => '80' # req.server_port # => 80 # - # req = Request.new 'SERVER_PORT' => '8080' + # req = ActionDispatch::Request.new 'SERVER_PORT' => '8080' # req.server_port # => 8080 def server_port get_header("SERVER_PORT").to_i diff --git a/actionpack/lib/action_dispatch/middleware/ssl.rb b/actionpack/lib/action_dispatch/middleware/ssl.rb index 0b81d0ad43..992daab3aa 100644 --- a/actionpack/lib/action_dispatch/middleware/ssl.rb +++ b/actionpack/lib/action_dispatch/middleware/ssl.rb @@ -133,12 +133,20 @@ module ActionDispatch end def redirect_to_https(request) - [ @redirect.fetch(:status, 301), + [ @redirect.fetch(:status, redirection_status(request)), { "Content-Type" => "text/html", "Location" => https_location_for(request) }, @redirect.fetch(:body, []) ] end + def redirection_status(request) + if request.get? || request.head? + 301 # Issue a permanent redirect via a GET request. + else + 307 # Issue a fresh request redirect to preserve the HTTP method. + end + end + def https_location_for(request) host = @redirect[:host] || request.host port = @redirect[:port] || request.port |