Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Allow HSTS header to be configured

  • Loading branch information...
commit 75d94d0e0eef6634a2bc54259d8de495c9f70228 1 parent 732b7a6
@josh authored
Showing with 50 additions and 7 deletions.
  1. +18 −2 lib/rack/ssl.rb
  2. +32 −5 test/test_ssl.rb
View
20 lib/rack/ssl.rb
@@ -3,8 +3,18 @@
module Rack
class SSL
- def initialize(app)
+ YEAR = 31536000
+
+ def self.default_hsts_options
+ { :expires => YEAR, :subdomains => false }
+ end
+
+ def initialize(app, options = {})
@app = app
+
+ @hsts = options[:hsts]
+ @hsts = {} if @hsts.nil? || @hsts == true
+ @hsts = self.class.default_hsts_options.merge(@hsts) if @hsts
end
def call(env)
@@ -38,7 +48,13 @@ def redirect_to_https(env)
# http://tools.ietf.org/html/draft-hodges-strict-transport-sec-02
def hsts_headers
- { 'Strict-Transport-Security' => "max-age=16070400; includeSubDomains" }
+ 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)
View
37 test/test_ssl.rb
@@ -7,15 +7,15 @@ class TestSSL < Test::Unit::TestCase
include Rack::Test::Methods
def default_app
- Rack::SSL.new(lambda { |env|
+ lambda { |env|
headers = {'Content-Type' => "text/html"}
headers['Set-Cookie'] = "id=1; path=/\ntoken=abc; path=/; secure; HttpOnly"
[200, headers, ["OK"]]
- })
+ }
end
def app
- @app ||= default_app
+ @app ||= Rack::SSL.new(default_app)
end
attr_writer :app
@@ -36,9 +36,36 @@ def test_redirects_http_to_https
last_response.headers['Location']
end
- def test_strict_transport_security_header
+ def test_hsts_header_by_default
get "https://example.org/"
- assert_equal "max-age=16070400; includeSubDomains",
+ assert_equal "max-age=31536000",
+ last_response.headers['Strict-Transport-Security']
+ end
+
+ def test_hsts_header
+ self.app = Rack::SSL.new(default_app, :hsts => true)
+ get "https://example.org/"
+ assert_equal "max-age=31536000",
+ last_response.headers['Strict-Transport-Security']
+ end
+
+ def test_disable_hsts_header
+ self.app = Rack::SSL.new(default_app, :hsts => false)
+ get "https://example.org/"
+ assert !last_response.headers['Strict-Transport-Security']
+ end
+
+ def test_hsts_expires
+ self.app = Rack::SSL.new(default_app, :hsts => { :expires => 500 })
+ get "https://example.org/"
+ assert_equal "max-age=500",
+ last_response.headers['Strict-Transport-Security']
+ end
+
+ def test_hsts_include_subdomains
+ self.app = Rack::SSL.new(default_app, :hsts => { :subdomains => true })
+ get "https://example.org/"
+ assert_equal "max-age=31536000; includeSubDomains",
last_response.headers['Strict-Transport-Security']
end
Please sign in to comment.
Something went wrong with that request. Please try again.