Skip to content

Commit

Permalink
Allow HSTS header to be configured
Browse files Browse the repository at this point in the history
  • Loading branch information
josh committed Nov 4, 2010
1 parent 732b7a6 commit 75d94d0
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 7 deletions.
20 changes: 18 additions & 2 deletions lib/rack/ssl.rb
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
37 changes: 32 additions & 5 deletions test/test_ssl.rb
Expand Up @@ -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

Expand All @@ -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

Expand Down

0 comments on commit 75d94d0

Please sign in to comment.