rack-secure_only 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +27 -0
- data/VERSION +1 -1
- data/lib/rack/secure_only/request.rb +38 -0
- data/lib/rack/secure_only.rb +16 -31
- data/rack-secure_only.gemspec +6 -3
- data/spec/rack/secure_only/request_spec.rb +100 -0
- data/spec/rack/secure_only_spec.rb +2 -2
- metadata +7 -4
data/README.rdoc
CHANGED
@@ -43,6 +43,33 @@ This can be disabled by setting the :use_http_x_forwarded_proto option to false.
|
|
43
43
|
|
44
44
|
This will redirect all requests to /secure to https and all requests to /notsecure to http.
|
45
45
|
|
46
|
+
=== Rack::Request
|
47
|
+
|
48
|
+
When rack-secure_only is required the Rack::Request will be extended with some convenience methods
|
49
|
+
to determine if the current request is http or https
|
50
|
+
|
51
|
+
require 'rack-secure_only'
|
52
|
+
|
53
|
+
run lambda { |env|
|
54
|
+
req = Request.new(env)
|
55
|
+
|
56
|
+
res_body = ""
|
57
|
+
|
58
|
+
if req.https?
|
59
|
+
res_body = "You just made a request on https"
|
60
|
+
elsif req.http?
|
61
|
+
res_body = "You just made a request on http"
|
62
|
+
elsif req.https?(false) # do not check the HTTP_X_FORWARDED_PROTO header
|
63
|
+
res_body = "You just made a request on a url with scheme https"
|
64
|
+
elsif req.http?(false) # do not check the HTTP_X_FORWARDED_PROTO header
|
65
|
+
res_body = "You just made a request on a url with scheme http, I did not check the HTTP_X_FORWARDED_PROTO header"
|
66
|
+
end
|
67
|
+
|
68
|
+
res_body << " and the HTTP_X_FORWARDED_PROTO header was set to" + req.forwarded_proto
|
69
|
+
|
70
|
+
[200, { 'Content-Type' => 'text/plain' }, res_body]
|
71
|
+
}
|
72
|
+
|
46
73
|
== Note on Patches/Pull Requests
|
47
74
|
|
48
75
|
* Fork the project.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "rack/request"
|
2
|
+
|
3
|
+
module Rack
|
4
|
+
|
5
|
+
# The secure_only extention add some convenience methods
|
6
|
+
# to determin if the request is a http or a https request
|
7
|
+
#
|
8
|
+
class Request
|
9
|
+
|
10
|
+
# Returns true if the current url scheme is http
|
11
|
+
# and the HTTP_X_FORWARDED_PROTO header is not set to https
|
12
|
+
#
|
13
|
+
def http?(use_forwarded_proto=true)
|
14
|
+
if use_forwarded_proto
|
15
|
+
scheme == 'http' && forwarded_proto != 'https'
|
16
|
+
else
|
17
|
+
scheme == 'http'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns true if the current url scheme is https or
|
22
|
+
# the HTTP_X_FORWARDED_PROTO header is set to https
|
23
|
+
#
|
24
|
+
def https?(use_forwarded_proto=true)
|
25
|
+
if use_forwarded_proto
|
26
|
+
scheme == 'https' || forwarded_proto == 'https'
|
27
|
+
else
|
28
|
+
scheme == 'https'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [String] the value of the HTTP_X_FORWARDED_PROTO header
|
33
|
+
#
|
34
|
+
def forwarded_proto
|
35
|
+
@env['HTTP_X_FORWARDED_PROTO']
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/rack/secure_only.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "rack"
|
2
|
+
require "rack/secure_only/request"
|
2
3
|
|
3
4
|
module Rack
|
4
5
|
|
@@ -13,45 +14,33 @@ module Rack
|
|
13
14
|
#
|
14
15
|
# @param [Hash] opts options for redirect rules
|
15
16
|
# @option opts [Boolean] :secure If set to false will redirect https to http, defaults to true
|
16
|
-
# @option opts [Fixnum]
|
17
|
+
# @option opts [Fixnum] :status_code Status code to redirect with, defaults to 301
|
17
18
|
# @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]
|
19
|
+
# @option opts [String] :redirect_to When set will use the provided url to redirect to
|
19
20
|
#
|
20
21
|
class SecureOnly
|
21
22
|
def initialize(app, opts={})
|
22
|
-
opts = { :secure => true, :status_code => 301, :redirect_to => nil, :use_http_x_forwarded_proto => true }.merge(opts)
|
23
23
|
@app = app
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
@opts = {
|
25
|
+
:secure => true,
|
26
|
+
:status_code => 301,
|
27
|
+
:redirect_to => nil,
|
28
|
+
:use_http_x_forwarded_proto => true
|
29
|
+
}.merge(opts)
|
29
30
|
end
|
30
31
|
|
31
32
|
def call(env)
|
32
33
|
should_redirect, to_path = redirect?(env)
|
33
|
-
|
34
|
+
if should_redirect
|
35
|
+
return [@opts[:status_code], { 'Content-Type' => 'text/plain', 'Location' => to_path }, ["Redirect"]]
|
36
|
+
end
|
34
37
|
@app.call(env)
|
35
38
|
end
|
36
39
|
|
37
|
-
# Returns true if the current url scheme is http
|
38
|
-
# and the HTTP_X_FORWARDED_PROTO header is not set to https
|
39
|
-
#
|
40
|
-
def on_http?(env)
|
41
|
-
( env['rack.url_scheme'] == 'http' && ( use_x_forward? ? env['HTTP_X_FORWARDED_PROTO'] != 'https' : true ) )
|
42
|
-
end
|
43
|
-
|
44
|
-
# Returns true if the current url scheme is https or
|
45
|
-
# the HTTP_X_FORWARDED_PROTO header is set to https
|
46
|
-
#
|
47
|
-
def on_https?(env)
|
48
|
-
( env['rack.url_scheme'] == 'https' || ( use_x_forward? ? env['HTTP_X_FORWARDED_PROTO'] == 'https' : false ) )
|
49
|
-
end
|
50
|
-
|
51
40
|
# Boolean accesor for :secure
|
52
41
|
#
|
53
42
|
def secure?
|
54
|
-
!!@secure
|
43
|
+
!!@opts[:secure]
|
55
44
|
end
|
56
45
|
|
57
46
|
# Inversed boolean accesor for :secure
|
@@ -64,18 +53,14 @@ module Rack
|
|
64
53
|
|
65
54
|
def redirect?(env)
|
66
55
|
req = Request.new(env)
|
67
|
-
url = @redirect_to || req.url
|
68
|
-
if secure? &&
|
56
|
+
url = @opts[:redirect_to] || req.url
|
57
|
+
if secure? && req.http?(@opts[:use_http_x_forwarded_proto])
|
69
58
|
return [true, url.gsub(/^http:/,'https:')]
|
70
|
-
elsif not_secure? &&
|
59
|
+
elsif not_secure? && req.https?(@opts[:use_http_x_forwarded_proto])
|
71
60
|
return [true, url.gsub(/^https:/,'http:')]
|
72
61
|
else
|
73
62
|
return [false, req.url]
|
74
63
|
end
|
75
64
|
end
|
76
|
-
|
77
|
-
def use_x_forward?
|
78
|
-
@use_http_x_forward
|
79
|
-
end
|
80
65
|
end
|
81
66
|
end
|
data/rack-secure_only.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{rack-secure_only}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.4.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Klaas Speller"]
|
12
|
-
s.date = %q{2010-05-
|
12
|
+
s.date = %q{2010-05-23}
|
13
13
|
s.description = %q{Redirect http to https and the other way around}
|
14
14
|
s.email = %q{klaasspeller@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -25,7 +25,9 @@ Gem::Specification.new do |s|
|
|
25
25
|
"VERSION",
|
26
26
|
"lib/rack-secure_only.rb",
|
27
27
|
"lib/rack/secure_only.rb",
|
28
|
+
"lib/rack/secure_only/request.rb",
|
28
29
|
"rack-secure_only.gemspec",
|
30
|
+
"spec/rack/secure_only/request_spec.rb",
|
29
31
|
"spec/rack/secure_only_spec.rb",
|
30
32
|
"spec/spec.opts",
|
31
33
|
"spec/spec_helper.rb"
|
@@ -36,7 +38,8 @@ Gem::Specification.new do |s|
|
|
36
38
|
s.rubygems_version = %q{1.3.6}
|
37
39
|
s.summary = %q{Redirect http to https and the other way around}
|
38
40
|
s.test_files = [
|
39
|
-
"spec/rack/
|
41
|
+
"spec/rack/secure_only/request_spec.rb",
|
42
|
+
"spec/rack/secure_only_spec.rb",
|
40
43
|
"spec/spec_helper.rb"
|
41
44
|
]
|
42
45
|
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
|
2
|
+
|
3
|
+
require "rack/secure_only/request"
|
4
|
+
require 'rack/mock'
|
5
|
+
|
6
|
+
describe Rack::Request do
|
7
|
+
describe "when rack/secure_only/request is required" do
|
8
|
+
before(:each) do
|
9
|
+
@req = Rack::Request.new(Rack::MockRequest.env_for("http://example.com/"))
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should respond to http?" do
|
13
|
+
@req.should respond_to :http?
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should respond to https?" do
|
17
|
+
@req.should respond_to :https?
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should respond to forwarded_proto" do
|
21
|
+
@req.should respond_to :forwarded_proto
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "with request http://example.com/" do
|
26
|
+
before(:each) do
|
27
|
+
@req = Rack::Request.new(Rack::MockRequest.env_for("http://example.com/"))
|
28
|
+
end
|
29
|
+
|
30
|
+
it "#http? should return true" do
|
31
|
+
@req.should be_http
|
32
|
+
end
|
33
|
+
|
34
|
+
it "#https? should return false" do
|
35
|
+
@req.should_not be_https
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "with request https://example.com/" do
|
40
|
+
before(:each) do
|
41
|
+
@req = Rack::Request.new(Rack::MockRequest.env_for("https://example.com/"))
|
42
|
+
end
|
43
|
+
|
44
|
+
it "#http? should return false" do
|
45
|
+
@req.should_not be_http
|
46
|
+
end
|
47
|
+
|
48
|
+
it "#https? should return true" do
|
49
|
+
@req.should be_https
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "with request http://example.com/ and HTTP_X_FORWARDED_PROTO set to https" do
|
54
|
+
before(:each) do
|
55
|
+
@req = Rack::Request.new(Rack::MockRequest.env_for("http://example.com/", { 'HTTP_X_FORWARDED_PROTO' => 'https' }))
|
56
|
+
end
|
57
|
+
|
58
|
+
it "#http? should return false" do
|
59
|
+
@req.should_not be_http
|
60
|
+
end
|
61
|
+
|
62
|
+
it "#https? should return true" do
|
63
|
+
@req.should be_https
|
64
|
+
end
|
65
|
+
|
66
|
+
context "and use_forwarded_proto set to false" do
|
67
|
+
it "#http? should return true" do
|
68
|
+
@req.http?(false).should == true
|
69
|
+
end
|
70
|
+
|
71
|
+
it "#https? should return false" do
|
72
|
+
@req.https?(false).should == false
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "with request https://example.com/ and HTTP_X_FORWARDED_PROTO set to https" do
|
78
|
+
before(:each) do
|
79
|
+
@req = Rack::Request.new(Rack::MockRequest.env_for("https://example.com/", { 'HTTP_X_FORWARDED_PROTO' => 'https' }))
|
80
|
+
end
|
81
|
+
|
82
|
+
it "#http? should return false" do
|
83
|
+
@req.should_not be_http
|
84
|
+
end
|
85
|
+
|
86
|
+
it "#https? should return true" do
|
87
|
+
@req.should be_https
|
88
|
+
end
|
89
|
+
|
90
|
+
context "and use_forwarded_proto set to false" do
|
91
|
+
it "#http? should return false" do
|
92
|
+
@req.http?(false).should == false
|
93
|
+
end
|
94
|
+
|
95
|
+
it "#https? should return true" do
|
96
|
+
@req.https?(false).should == true
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -37,7 +37,7 @@ describe Rack::SecureOnly do
|
|
37
37
|
|
38
38
|
describe "with HTTP_X_FORWARDED_PROTO header set to https (like with heroku ssl)" do
|
39
39
|
before(:each) do
|
40
|
-
@response = @request.get('
|
40
|
+
@response = @request.get('https://www.example.com/secure', { 'HTTP_X_FORWARDED_PROTO' => 'https' })
|
41
41
|
end
|
42
42
|
|
43
43
|
it "should do no redirect" do
|
@@ -136,7 +136,7 @@ describe Rack::SecureOnly do
|
|
136
136
|
@response = @request.get('http://www.example.com/notsecure', { 'HTTP_X_FORWARDED_PROTO' => 'https' })
|
137
137
|
end
|
138
138
|
|
139
|
-
it "should do redirect" do
|
139
|
+
it "should do no redirect" do
|
140
140
|
@response.location.should == "http://www.example.com/notsecure"
|
141
141
|
end
|
142
142
|
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 4
|
8
|
+
- 0
|
9
|
+
version: 0.4.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Klaas Speller
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-05-
|
17
|
+
date: 2010-05-23 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -77,7 +77,9 @@ files:
|
|
77
77
|
- VERSION
|
78
78
|
- lib/rack-secure_only.rb
|
79
79
|
- lib/rack/secure_only.rb
|
80
|
+
- lib/rack/secure_only/request.rb
|
80
81
|
- rack-secure_only.gemspec
|
82
|
+
- spec/rack/secure_only/request_spec.rb
|
81
83
|
- spec/rack/secure_only_spec.rb
|
82
84
|
- spec/spec.opts
|
83
85
|
- spec/spec_helper.rb
|
@@ -112,5 +114,6 @@ signing_key:
|
|
112
114
|
specification_version: 3
|
113
115
|
summary: Redirect http to https and the other way around
|
114
116
|
test_files:
|
117
|
+
- spec/rack/secure_only/request_spec.rb
|
115
118
|
- spec/rack/secure_only_spec.rb
|
116
119
|
- spec/spec_helper.rb
|