This repository has been archived by the owner on Feb 24, 2021. It is now read-only.
forked from chopmo/rack-ssl
/
ssl.rb
55 lines (49 loc) · 1.36 KB
/
ssl.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
require 'rack'
require 'rack/request'
module Rack
class SSL
def initialize(app)
@app = app
end
def call(env)
if scheme(env) == 'https'
status, headers, body = @app.call(env)
headers = hsts_headers.merge(headers)
flag_cookies_as_secure!(headers)
[status, headers, body]
else
redirect_to_https(env)
end
end
private
# Fixed in rack >= 1.3
def scheme(env)
if env['HTTPS'] == 'on'
'https'
elsif env['HTTP_X_FORWARDED_PROTO']
env['HTTP_X_FORWARDED_PROTO'].split(',')[0]
else
env['rack.url_scheme']
end
end
def redirect_to_https(env)
req = Request.new(env)
location = req.url.sub(/^http:/, 'https:')
[301, hsts_headers.merge({'Content-Type' => "text/html", 'Location' => location}), []]
end
# http://tools.ietf.org/html/draft-hodges-strict-transport-sec-02
def hsts_headers
{ 'Strict-Transport-Security' => "max-age=16070400; includeSubDomains" }
end
def flag_cookies_as_secure!(headers)
cookies = headers['Set-Cookie'].split("\n")
headers['Set-Cookie'] = cookies.map { |cookie|
if cookie !~ / secure;/
"#{cookie}; secure"
else
cookie
end
}.join("\n")
end
end
end