aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_dispatch')
-rw-r--r--actionpack/lib/action_dispatch/http/response.rb9
-rw-r--r--actionpack/lib/action_dispatch/middleware/show_exceptions.rb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/ssl.rb70
-rw-r--r--actionpack/lib/action_dispatch/middleware/static.rb1
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb2
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/response.rb2
6 files changed, 81 insertions, 5 deletions
diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb
index 84732085f0..078229efd2 100644
--- a/actionpack/lib/action_dispatch/http/response.rb
+++ b/actionpack/lib/action_dispatch/http/response.rb
@@ -51,12 +51,13 @@ module ActionDispatch # :nodoc:
# If a character set has been defined for this response (see charset=) then
# the character set information will also be included in the content type
# information.
- attr_accessor :charset, :content_type
+ attr_accessor :charset
+ attr_reader :content_type
CONTENT_TYPE = "Content-Type".freeze
SET_COOKIE = "Set-Cookie".freeze
LOCATION = "Location".freeze
-
+
cattr_accessor(:default_charset) { "utf-8" }
include Rack::Response::Helpers
@@ -83,6 +84,10 @@ module ActionDispatch # :nodoc:
@status = Rack::Utils.status_code(status)
end
+ def content_type=(content_type)
+ @content_type = content_type.to_s
+ end
+
# The response code of the request
def response_code
@status
diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb
index 836136eb95..ab740a0190 100644
--- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb
+++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb
@@ -9,7 +9,7 @@ module ActionDispatch
# of ShowExceptions. Everytime there is an exception, ShowExceptions will
# store the exception in env["action_dispatch.exception"], rewrite the
# PATH_INFO to the exception status code and call the rack app.
- #
+ #
# If the application returns a "X-Cascade" pass response, this middleware
# will send an empty response as result with the correct status code.
# If any exception happens inside the exceptions app, this middleware
diff --git a/actionpack/lib/action_dispatch/middleware/ssl.rb b/actionpack/lib/action_dispatch/middleware/ssl.rb
new file mode 100644
index 0000000000..9098f4e170
--- /dev/null
+++ b/actionpack/lib/action_dispatch/middleware/ssl.rb
@@ -0,0 +1,70 @@
+module ActionDispatch
+ class SSL
+ YEAR = 31536000
+
+ def self.default_hsts_options
+ { :expires => YEAR, :subdomains => false }
+ end
+
+ def initialize(app, options = {})
+ @app = app
+
+ @hsts = options.fetch(:hsts, {})
+ @hsts = {} if @hsts == true
+ @hsts = self.class.default_hsts_options.merge(@hsts) if @hsts
+
+ @host = options[:host]
+ @port = options[:port]
+ end
+
+ def call(env)
+ request = Request.new(env)
+
+ if request.ssl?
+ status, headers, body = @app.call(env)
+ headers = hsts_headers.merge(headers)
+ flag_cookies_as_secure!(headers)
+ [status, headers, body]
+ else
+ redirect_to_https(request)
+ end
+ end
+
+ private
+ def redirect_to_https(request)
+ url = URI(request.url)
+ url.scheme = "https"
+ url.host = @host if @host
+ url.port = @port if @port
+ headers = hsts_headers.merge('Content-Type' => 'text/html',
+ 'Location' => url.to_s)
+
+ [301, headers, []]
+ end
+
+ # http://tools.ietf.org/html/draft-hodges-strict-transport-sec-02
+ def hsts_headers
+ if @hsts
+ value = "max-age=#{@hsts[:expires]}"
+ value += "; includeSubDomains" if @hsts[:subdomains]
+ { 'Strict-Transport-Security' => value }
+ else
+ {}
+ end
+ end
+
+ def flag_cookies_as_secure!(headers)
+ if cookies = headers['Set-Cookie']
+ cookies = cookies.split("\n")
+
+ headers['Set-Cookie'] = cookies.map { |cookie|
+ if cookie !~ /;\s+secure(;|$)/
+ "#{cookie}; secure"
+ else
+ cookie
+ end
+ }.join("\n")
+ end
+ end
+ end
+end
diff --git a/actionpack/lib/action_dispatch/middleware/static.rb b/actionpack/lib/action_dispatch/middleware/static.rb
index 63b7422287..9073e6582d 100644
--- a/actionpack/lib/action_dispatch/middleware/static.rb
+++ b/actionpack/lib/action_dispatch/middleware/static.rb
@@ -39,6 +39,7 @@ module ActionDispatch
end
def escape_glob_chars(path)
+ path.force_encoding('binary') if path.respond_to? :force_encoding
path.gsub(/[*?{}\[\]]/, "\\\\\\&")
end
end
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index cd215034dc..cdc29fb304 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -1,6 +1,6 @@
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/object/blank'
-require 'active_support/core_ext/object/inclusion'
+require 'active_support/core_ext/enumerable'
require 'active_support/inflector'
require 'action_dispatch/routing/redirection'
diff --git a/actionpack/lib/action_dispatch/testing/assertions/response.rb b/actionpack/lib/action_dispatch/testing/assertions/response.rb
index 094cfbfc76..a5e7a8c715 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/response.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/response.rb
@@ -83,7 +83,7 @@ module ActionDispatch
refer
else
@controller.url_for(fragment)
- end.gsub(/[\r\n]/, '')
+ end.gsub(/[\0\r\n]/, '')
end
end
end