rack-secure_only 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +12 -1
- data/VERSION +1 -1
- data/lib/rack/secure_only.rb +21 -7
- data/rack-secure_only.gemspec +1 -1
- data/spec/rack/secure_only_spec.rb +46 -0
- metadata +2 -2
data/README.rdoc
CHANGED
@@ -5,9 +5,10 @@ SecureOnly will redirect to https if the request is on http.
|
|
5
5
|
When passed :secure => false it will do the opposite and redirect https to http.
|
6
6
|
|
7
7
|
The check if the current request is on https includes checking the HTTP_X_FORWARDED_PROTO header.
|
8
|
-
|
9
8
|
This means the redirect will also work on heroku.com
|
10
9
|
|
10
|
+
This can be disabled by setting the :use_http_x_forwarded_proto option to false.
|
11
|
+
|
11
12
|
== Installation
|
12
13
|
|
13
14
|
sudo gem install rack-secure_only
|
@@ -26,6 +27,16 @@ This means the redirect will also work on heroku.com
|
|
26
27
|
use Rack::SecureOnly, :secure => false
|
27
28
|
run lambda { |env| [200, { 'Content-Type' => 'text/plain' }, ["NON SECURE APP"]] }
|
28
29
|
end
|
30
|
+
|
31
|
+
map '/secure_without_http_x_forwarded_proto_check' do
|
32
|
+
use Rack::SecureOnly, :use_http_x_forwarded_proto => false
|
33
|
+
run lambda { |env| [200, { 'Content-Type' => 'text/plain' }, ["SECURE APP"]] }
|
34
|
+
end
|
35
|
+
|
36
|
+
map '/secure_with_fixed_redirect_ulr' do
|
37
|
+
use Rack::SecureOnly, :redirect_to => "https://my.site.org/login"
|
38
|
+
run lambda { |env| [200, { 'Content-Type' => 'text/plain' }, ["SECURE APP"]] }
|
39
|
+
end
|
29
40
|
end
|
30
41
|
|
31
42
|
run app
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/lib/rack/secure_only.rb
CHANGED
@@ -11,12 +11,21 @@ module Rack
|
|
11
11
|
#
|
12
12
|
# This means the redirect will also work on heroku.com
|
13
13
|
#
|
14
|
+
# @param [Hash] opts options for redirect rules
|
15
|
+
# @option opts [Boolean] :secure If set to false will redirect https to http, defaults to true
|
16
|
+
# @option opts [Fixnum] :status_code Status code to redirect with, defaults to 301
|
17
|
+
# @option opts [Boolean] :use_http_x_forwarded_proto When set to false will not check for HTTP_X_FORWARDED_PROTO header
|
18
|
+
# @option opts [String] :redirect_to When set will use the provided url to redirect to
|
19
|
+
#
|
14
20
|
class SecureOnly
|
15
21
|
def initialize(app, opts={})
|
16
|
-
opts = { :secure => true }.merge(opts)
|
22
|
+
opts = { :secure => true, :status_code => 301, :redirect_to => nil, :use_http_x_forwarded_proto => true }.merge(opts)
|
17
23
|
@app = app
|
18
|
-
|
19
|
-
@
|
24
|
+
|
25
|
+
@secure = opts[:secure]
|
26
|
+
@redirect_status_code = opts[:status_code]
|
27
|
+
@redirect_to = opts[:redirect_to]
|
28
|
+
@use_http_x_forward = !!opts[:use_http_x_forwarded_proto]
|
20
29
|
end
|
21
30
|
|
22
31
|
def call(env)
|
@@ -29,14 +38,14 @@ module Rack
|
|
29
38
|
# and the HTTP_X_FORWARDED_PROTO header is not set to https
|
30
39
|
#
|
31
40
|
def on_http?(env)
|
32
|
-
( env['rack.url_scheme'] == 'http' && env['HTTP_X_FORWARDED_PROTO'] != 'https')
|
41
|
+
( env['rack.url_scheme'] == 'http' && ( use_x_forward? ? env['HTTP_X_FORWARDED_PROTO'] != 'https' : true ) )
|
33
42
|
end
|
34
43
|
|
35
44
|
# Returns true if the current url scheme is https or
|
36
45
|
# the HTTP_X_FORWARDED_PROTO header is set to https
|
37
46
|
#
|
38
47
|
def on_https?(env)
|
39
|
-
( env['rack.url_scheme'] == 'https' || env['HTTP_X_FORWARDED_PROTO'] == 'https')
|
48
|
+
( env['rack.url_scheme'] == 'https' || ( use_x_forward? ? env['HTTP_X_FORWARDED_PROTO'] == 'https' : false ) )
|
40
49
|
end
|
41
50
|
|
42
51
|
# Boolean accesor for :secure
|
@@ -55,13 +64,18 @@ module Rack
|
|
55
64
|
|
56
65
|
def redirect?(env)
|
57
66
|
req = Request.new(env)
|
67
|
+
url = @redirect_to || req.url
|
58
68
|
if secure? && on_http?(env)
|
59
|
-
return [true,
|
69
|
+
return [true, url.gsub(/^http:/,'https:')]
|
60
70
|
elsif not_secure? && on_https?(env)
|
61
|
-
return [true,
|
71
|
+
return [true, url.gsub(/^https:/,'http:')]
|
62
72
|
else
|
63
73
|
return [false, req.url]
|
64
74
|
end
|
65
75
|
end
|
76
|
+
|
77
|
+
def use_x_forward?
|
78
|
+
@use_http_x_forward
|
79
|
+
end
|
66
80
|
end
|
67
81
|
end
|
data/rack-secure_only.gemspec
CHANGED
@@ -142,4 +142,50 @@ describe Rack::SecureOnly do
|
|
142
142
|
end
|
143
143
|
end
|
144
144
|
end
|
145
|
+
|
146
|
+
describe "configuration" do
|
147
|
+
it "should use :status_code if provided" do
|
148
|
+
app = Rack::Builder.new do
|
149
|
+
use Rack::SecureOnly, :status_code => 307
|
150
|
+
run lambda { |env| [200, { 'Content-Type' => 'text/plain' }, ["SECURE APP"]] }
|
151
|
+
end
|
152
|
+
@request = Rack::MockRequest.new(app)
|
153
|
+
@response = @request.get('http://www.example.com/')
|
154
|
+
|
155
|
+
@response.status.should == 307
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should use :redirect_to if provided" do
|
159
|
+
app = Rack::Builder.new do
|
160
|
+
use Rack::SecureOnly, :redirect_to => 'https://www.example.com/login'
|
161
|
+
run lambda { |env| [200, { 'Content-Type' => 'text/plain' }, ["SECURE APP"]] }
|
162
|
+
end
|
163
|
+
@request = Rack::MockRequest.new(app)
|
164
|
+
@response = @request.get('http://www.example.com/')
|
165
|
+
|
166
|
+
@response.location.should == 'https://www.example.com/login'
|
167
|
+
end
|
168
|
+
|
169
|
+
it "should use :redirect_to if provided with :secure => false" do
|
170
|
+
app = Rack::Builder.new do
|
171
|
+
use Rack::SecureOnly, :redirect_to => 'https://www.example.com/login', :secure => false
|
172
|
+
run lambda { |env| [200, { 'Content-Type' => 'text/plain' }, ["SECURE APP"]] }
|
173
|
+
end
|
174
|
+
@request = Rack::MockRequest.new(app)
|
175
|
+
@response = @request.get('https://www.example.com/')
|
176
|
+
|
177
|
+
@response.location.should == 'http://www.example.com/login'
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should not check HTTP_X_FORWARDED_PROTO if :use_http_x_forwarded_proto is set to false" do
|
181
|
+
app = Rack::Builder.new do
|
182
|
+
use Rack::SecureOnly, :use_http_x_forwarded_proto => false
|
183
|
+
run lambda { |env| [200, { 'Content-Type' => 'text/plain' }, ["SECURE APP"]] }
|
184
|
+
end
|
185
|
+
@request = Rack::MockRequest.new(app)
|
186
|
+
@response = @request.get('http://www.example.com/', { 'HTTP_X_FORWARDED_PROTO' => 'https' })
|
187
|
+
|
188
|
+
@response.location.should == "https://www.example.com/"
|
189
|
+
end
|
190
|
+
end
|
145
191
|
end
|