rack-ssl-enforcer 0.2.6 → 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 19f0acb60b5cc81e0f314272653283ae86b78274
4
+ data.tar.gz: 837d1adfe73260634e2eb8d10d157aa03b32aefd
5
+ SHA512:
6
+ metadata.gz: ec0fe6c85a980f63ff9ab0cd3659e7d86a2ea819ef15d31d9763f419bf5d9f09edc5e39dd1dd03203f5c873adcf87fbe0763b100cdc32dbedbd8f0197621f2da
7
+ data.tar.gz: 8685bd5a1534e785a1bed177042238362c19f668ee09b85318b5f5829b8bd14db473b71d8d50040e8e2ea24c534ea31900a2fda20e17259543a4ad28302fad2d
data/LICENSE CHANGED
@@ -1,20 +1,20 @@
1
- Copyright (c) 2009-2012 Tobias Matthies
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ Copyright (c) 2009-2012 Tobias Matthies
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,272 +1,297 @@
1
- # Rack::SslEnforcer [![Build Status](https://travis-ci.org/tobmatth/rack-ssl-enforcer.png?branch=master)](https://travis-ci.org/tobmatth/rack-ssl-enforcer)
2
-
3
- Rack::SslEnforcer is a simple Rack middleware to enforce SSL connections. As of Version 0.2.0, Rack::SslEnforcer marks
4
- Cookies as secure by default (HSTS must be set manually).
5
-
6
- Tested against Ruby 1.8.7, 1.9.2, 1.9.3, ruby-head, REE and the latest versions of Rubinius & JRuby.
7
-
8
- ## Installation
9
-
10
- The simplest way to install Rack::SslEnforcer is to use [Bundler](http://gembundler.com).
11
-
12
- Add Rack::SslEnforcer to your `Gemfile`:
13
-
14
- ```ruby
15
- gem 'rack-ssl-enforcer'
16
- ```
17
-
18
- ### Installing on Sinatra / Padrino application
19
-
20
- In order for Rack::SslEnforcer to properly work it has to be at the top
21
- of the Rack Middleware.
22
-
23
- Using `enable :session` will place Rack::Session::Cookie before Rack::Ssl::Enforcer
24
- and will prevent Rack::Ssl::Enforcer from marking cookies as secure.
25
-
26
- To fix this issue do not use `enable :sessions` instead add the
27
- Rack::Session::Cookie middleware after Rack::Ssl::Enforcer.
28
-
29
- Eg:
30
-
31
- ```ruby
32
- use Rack::SslEnforcer
33
- set :session_secret, 'asdfa2342923422f1adc05c837fa234230e3594b93824b00e930ab0fb94b'
34
-
35
- #Enable sinatra sessions
36
- use Rack::Session::Cookie, :key => '_rack_session',
37
- :path => '/',
38
- :expire_after => 2592000, # In seconds
39
- :secret => settings.session_secret
40
- ```
41
-
42
- ## Basic Usage
43
-
44
- If you don't use Bundler, be sure to require Rack::SslEnforcer manually before actually using the middleware:
45
-
46
- ```ruby
47
- require 'rack/ssl-enforcer'
48
- use Rack::SslEnforcer
49
- ```
50
-
51
- To use Rack::SslEnforcer in your Rails application, add the following line to your application config file (`config/application.rb` for Rails 3, `config/environment.rb` for Rails 2):
52
-
53
- ```ruby
54
- config.middleware.use Rack::SslEnforcer
55
- ```
56
-
57
- If all you want is SSL for your whole application, you are done! Otherwise, you can specify some options described below.
58
-
59
- ## Options
60
-
61
- ### Host constraints
62
-
63
- You can enforce SSL connections only for certain hosts with `:only_hosts`, or prevent certain hosts from being forced to SSL with `:except_hosts`. Constraints can be a `String`, a `Regex` or an array of `String` or `Regex` (possibly mixed), as shown in the following examples:
64
-
65
- ```ruby
66
- config.middleware.use Rack::SslEnforcer, :only_hosts => 'api.example.com'
67
- # Please note that, for instance, both http://help.example.com/demo and https://help.example.com/demo would be accessible here
68
-
69
- config.middleware.use Rack::SslEnforcer, :except_hosts => /[help|blog]\.example\.com$/
70
-
71
- config.middleware.use Rack::SslEnforcer, :only_hosts => [/[secure|admin]\.example\.org$/, 'api.example.com']
72
- ```
73
-
74
- ### Path constraints
75
-
76
- You can enforce SSL connections only for certain paths with `:only`, prevent certain paths from being forced to SSL with `:except`, or - if you don't care how certain paths are accessed - ignore them with `:ignore`. Constraints can be a `String`, a `Regex` or an array of `String` or `Regex` (possibly mixed), as shown in the following examples:
77
-
78
- ```ruby
79
- config.middleware.use Rack::SslEnforcer, :only => '/login'
80
- # Please note that, for instance, both http://example.com/demo and https://example.com/demo would be accessible here
81
-
82
- config.middleware.use Rack::SslEnforcer, :only => %r{^/admin/}
83
-
84
- config.middleware.use Rack::SslEnforcer, :except => ['/demo', %r{^/public/}]
85
-
86
- config.middleware.use Rack::SslEnforcer, :ignore => '/assets'
87
-
88
- # You can also combine multiple constraints
89
- config.middleware.use Rack::SslEnforcer, :only => '/cart', :ignore => %r{/assets}, :strict => true
90
- ```
91
-
92
- ### Method constraints
93
-
94
- You can enforce SSL connections only for certain HTTP methods with `:only_methods`, or prevent certain HTTP methods from being forced to SSL with `:except_methods`. Constraints can be a `String` or an array of `String`, as shown in the following examples:
95
-
96
- ```ruby
97
- # constraint as a String
98
- config.middleware.use Rack::SslEnforcer, :only_methods => 'POST'
99
- # Please note that, for instance, GET requests would be accessible via SSL and non-SSL connection here
100
-
101
- config.middleware.use Rack::SslEnforcer, :except_methods => ['GET', 'HEAD']
102
- ```
103
-
104
- Note: The `:hosts` constraint takes precedence over the `:path` constraint. Please see the tests for examples.
105
-
106
-
107
- ### Environment constraints
108
-
109
- You can enforce SSL connections only for certain environments with `:only_environments` or prevent certain environments from being forced to SSL with `:except_environments`.
110
- Environment constraints may be a `String`, a `Regex` or an array of `String` or `Regex` (possibly mixed), as shown in the following examples:
111
-
112
- ```ruby
113
- config.middleware.use Rack::SslEnforcer, :except_environments => 'development'
114
-
115
- config.middleware.use Rack::SslEnforcer, :except_environments => /^[0-9a-f]+_local$/i
116
-
117
- config.middleware.use Rack::SslEnforcer, :only_environments => ['production', /^QA/]
118
- ```
119
-
120
- Note: The `:environments` constraint requires one the following environment variables to be set: `RACK_ENV`, `RAILS_ENV`, `ENV`.
121
-
122
- ### User agent constraints
123
-
124
- You can enforce SSL connections only for certain user agents with `:only_agents` or prevent certain user agents from being forced to SSL with `:except_agents`.
125
- User agent constraints may be a `String`, a `Regex` or an array of `String` or `Regex` (possibly mixed), as shown in the following examples:
126
-
127
- ```ruby
128
- config.middleware.use Rack::SslEnforcer, :except_agents => 'Googlebot'
129
-
130
- config.middleware.use Rack::SslEnforcer, :except_agents => /[Googlebot|bingbot]/
131
-
132
- config.middleware.use Rack::SslEnforcer, :only_agents => ['test-secu-bot', /custom-crawler[0-9a-f]/]
133
- ```
134
-
135
- ### Force-redirection to non-SSL connection if constraint is not matched
136
-
137
- Use the `:strict` option to force non-SSL connection for all requests not matching the constraints you set. Examples:
138
-
139
- ```ruby
140
- config.middleware.use Rack::SslEnforcer, :only => ["/login", /\.xml$/], :strict => true
141
- # https://example.com/demo would be redirected to http://example.com/demo
142
-
143
- config.middleware.use Rack::SslEnforcer, :except_hosts => 'demo.example.com', :strict => true
144
- # https://demo.example.com would be redirected to http://demo.example.com
145
- ```
146
-
147
- ### Automatic method constraints
148
-
149
- In the case where you have matching URLs with different HTTP methods – for instance Rails RESTful routes: `GET /users`, `POST /users`, `GET /user/:id` and `PUT /user/:id` – you may need to force POST and PUT requests to SSL connection but redirect to non-SSL connection on GET.
150
-
151
- ```ruby
152
- config.middleware.use Rack::SslEnforcer, :only => [%r{^/users/}], :mixed => true
153
- ```
154
-
155
- The above will allow you to POST/PUT from the secure/non-secure URLs keeping the original schema.
156
-
157
- ### HTTP Strict Transport Security (HSTS)
158
-
159
- To set HSTS expiry and subdomain inclusion (defaults respectively to `one year` and `true`).
160
-
161
- ```ruby
162
- config.middleware.use Rack::SslEnforcer, :hsts => { :expires => 500, :subdomains => false }
163
- config.middleware.use Rack::SslEnforcer, :hsts => true # equivalent to { :expires => 31536000, :subdomains => true }
164
- ```
165
- Please note that the strict option disables HSTS.
166
-
167
- ### Redirect to specific URL (e.g. if you're using a proxy)
168
-
169
- You might need the `:redirect_to` option if the requested URL can't be determined.
170
-
171
- ```ruby
172
- config.middleware.use Rack::SslEnforcer, :redirect_to => 'https://example.org'
173
- ```
174
-
175
- ### Redirect with specific HTTP status code
176
-
177
- By default it redirects with HTTP status code 301(Moved Permanently). Sometimes you might need to redirect with different HTTP status code:
178
-
179
- ```ruby
180
- config.middleware.use Rack::SslEnforcer, :redirect_code => 302
181
- ```
182
-
183
- ### Custom HTTP port
184
-
185
- If you're using a different port than the default (80) for HTTP, you can specify it with the `:http_port` option:
186
-
187
- ```ruby
188
- config.middleware.use Rack::SslEnforcer, :http_port => 8080
189
- ```
190
-
191
- ### Custom HTTPS port
192
-
193
- If you're using a different port than the default (443) for HTTPS, you can specify it with the `:https_port` option:
194
-
195
- ```ruby
196
- config.middleware.use Rack::SslEnforcer, :https_port => 444
197
- ```
198
-
199
- ### Secure cookies disabling
200
-
201
- Finally you might want to share a cookie based session between HTTP and HTTPS.
202
- This is not possible by default with Rack::SslEnforcer for [security reasons](http://en.wikipedia.org/wiki/HTTP_cookie#Cookie_theft_and_session_hijacking).
203
-
204
- Nevertheless, you can set the `:force_secure_cookies` option to `false` in order to be able to share a cookie based session between HTTP and HTTPS:
205
-
206
- ```ruby
207
- config.middleware.use Rack::SslEnforcer, :only => "/login", :force_secure_cookies => false
208
- ```
209
-
210
- But be aware that if you do so, you have to make sure that the content of you cookie is encoded.
211
- This can be done using a coder with [Rack::Session::Cookie](https://github.com/rack/rack/blob/master/lib/rack/session/cookie.rb#L28-42).
212
-
213
- ### Running code before redirect
214
-
215
- You may want to run some code before rack-ssl-enforcer forces a redirect. This code could do something like log that a redirect was done, or if this is used in a Rails app, keeping the flash when redirecting:
216
-
217
-
218
- ```ruby
219
- config.middleware.use Rack::SslEnforcer, :only => '/login', :before_redirect => Proc.new {
220
- #keep flash on redirect
221
- @request.session[:flash].keep if !@request.session.nil? && @request.session.key?('flash') && !@request.session['flash'].empty?
222
- }
223
- ```
224
-
225
-
226
- ## Deployment
227
-
228
- If you run your application behind a proxy (e.g. Nginx) you may need to do some configuration on that side. If you don't you may experience an infinite redirect loop.
229
-
230
- The reason this happens is that Rack::SslEnforcer can't detect if you are running SSL or not. The solution is to have your front-end server send extra headers for Rack::SslEnforcer to identify the request protocol.
231
-
232
- ### Nginx
233
-
234
- In the `location` block for your app's SSL configuration, include the following proxy header configuration:
235
-
236
- `proxy_set_header X-Forwarded-Proto https;`
237
-
238
- ### Passenger
239
-
240
- Or, if you're using mod_rails/passenger (which will ignore the proxy_xxx directives):
241
-
242
- `passenger_set_cgi_param HTTP_X_FORWARDED_PROTO https;`
243
-
244
- If you're sharing a single `server` block for http AND https access you can add:
245
-
246
- `passenger_set_cgi_param HTTP_X_FORWARDED_PROTO $scheme;`
247
-
248
- This makes sure that Rack::SslEnforcer knows it's being accessed over SSL. Just restart Nginx for these changes to take effect.
249
-
250
- ## TODO
251
-
252
- * Cleanup tests
253
-
254
- #### Contributors
255
-
256
- [https://github.com/tobmatth/rack-ssl-enforcer/graphs/contributors](https://github.com/tobmatth/rack-ssl-enforcer/graphs/contributors)
257
-
258
- ## Credits
259
-
260
- Flagging cookies as secure functionality and HSTS support is greatly inspired by [Joshua Peek's Rack::SSL](https://github.com/josh/rack-ssl).
261
-
262
- ## Note on Patches / Pull Requests
263
-
264
- * Fork the project.
265
- * Code your feature addition or bug fix.
266
- * **Add tests for it.** This is important so we don't break it in a future version unintentionally.
267
- * Commit, do not mess with Rakefile or version number. If you want to have your own version, that's fine but bump version in a commit by itself so we can ignore it when merging.
268
- * Send a pull request. Bonus points for topic branches.
269
-
270
- ## Copyright
271
-
272
- Copyright (c) 2010-2013 Tobias Matthies. See [LICENSE](https://github.com/tobmatth/rack-ssl-enforcer/blob/master/LICENSE) for details.
1
+ # Rack::SslEnforcer [![Build Status](https://travis-ci.org/tobmatth/rack-ssl-enforcer.png?branch=master)](https://travis-ci.org/tobmatth/rack-ssl-enforcer)
2
+
3
+ Rack::SslEnforcer is a simple Rack middleware to enforce SSL connections. As of Version 0.2.0, Rack::SslEnforcer marks
4
+ Cookies as secure by default (HSTS must be set manually).
5
+
6
+ Tested against Ruby 1.8.7, 1.9.2, 1.9.3, 2.0.0, 2.1.0, ruby-head, REE and the latest versions of Rubinius & JRuby.
7
+
8
+ ## Installation
9
+
10
+ The simplest way to install Rack::SslEnforcer is to use [Bundler](http://gembundler.com).
11
+
12
+ Add Rack::SslEnforcer to your `Gemfile`:
13
+
14
+ ```ruby
15
+ gem 'rack-ssl-enforcer'
16
+ ```
17
+
18
+ ### Installing on Sinatra / Padrino application
19
+
20
+ In order for Rack::SslEnforcer to properly work it has to be at the top
21
+ of the Rack Middleware.
22
+
23
+ Using `enable :session` will place Rack::Session::Cookie before Rack::Ssl::Enforcer
24
+ and will prevent Rack::Ssl::Enforcer from marking cookies as secure.
25
+
26
+ To fix this issue do not use `enable :sessions` instead add the
27
+ Rack::Session::Cookie middleware after Rack::Ssl::Enforcer.
28
+
29
+ Eg:
30
+
31
+ ```ruby
32
+ use Rack::SslEnforcer
33
+ set :session_secret, 'asdfa2342923422f1adc05c837fa234230e3594b93824b00e930ab0fb94b'
34
+
35
+ #Enable sinatra sessions
36
+ use Rack::Session::Cookie, :key => '_rack_session',
37
+ :path => '/',
38
+ :expire_after => 2592000, # In seconds
39
+ :secret => settings.session_secret
40
+ ```
41
+
42
+ ## Basic Usage
43
+
44
+ If you don't use Bundler, be sure to require Rack::SslEnforcer manually before actually using the middleware:
45
+
46
+ ```ruby
47
+ require 'rack/ssl-enforcer'
48
+ use Rack::SslEnforcer
49
+ ```
50
+
51
+ To use Rack::SslEnforcer in your Rails application, add the following line to your application config file (`config/application.rb` for Rails 3 and above, `config/environment.rb` for Rails 2):
52
+
53
+ ```ruby
54
+ config.middleware.use Rack::SslEnforcer
55
+ ```
56
+
57
+ If all you want is SSL for your whole application, you are done! Otherwise, you can specify some options described below.
58
+
59
+ ## Options
60
+
61
+ ### Host constraints
62
+
63
+ You can enforce SSL connections only for certain hosts with `:only_hosts`, or prevent certain hosts from being forced to SSL with `:except_hosts`. Constraints can be a `String`, a `Regex` or an array of `String` or `Regex` (possibly mixed), as shown in the following examples:
64
+
65
+ ```ruby
66
+ config.middleware.use Rack::SslEnforcer, :only_hosts => 'api.example.com'
67
+ # Please note that, for instance, both http://help.example.com/demo and https://help.example.com/demo would be accessible here
68
+
69
+ config.middleware.use Rack::SslEnforcer, :except_hosts => /[help|blog]\.example\.com$/
70
+
71
+ config.middleware.use Rack::SslEnforcer, :only_hosts => [/[secure|admin]\.example\.org$/, 'api.example.com']
72
+ ```
73
+
74
+ ### Path constraints
75
+
76
+ You can enforce SSL connections only for certain paths with `:only`, prevent certain paths from being forced to SSL with `:except`, or - if you don't care how certain paths are accessed - ignore them with `:ignore`. Constraints can be a `String`, a `Regex` or an array of `String` or `Regex` (possibly mixed), as shown in the following examples:
77
+
78
+ ```ruby
79
+ config.middleware.use Rack::SslEnforcer, :only => '/login'
80
+ # Please note that, for instance, both http://example.com/demo and https://example.com/demo would be accessible here
81
+
82
+ config.middleware.use Rack::SslEnforcer, :only => %r{^/admin/}
83
+
84
+ config.middleware.use Rack::SslEnforcer, :except => ['/demo', %r{^/public/}]
85
+
86
+ config.middleware.use Rack::SslEnforcer, :ignore => '/assets'
87
+
88
+ # You can also combine multiple constraints
89
+ config.middleware.use Rack::SslEnforcer, :only => '/cart', :ignore => %r{/assets}, :strict => true
90
+ ```
91
+
92
+ ### Method constraints
93
+
94
+ You can enforce SSL connections only for certain HTTP methods with `:only_methods`, or prevent certain HTTP methods from being forced to SSL with `:except_methods`. Constraints can be a `String` or an array of `String`, as shown in the following examples:
95
+
96
+ ```ruby
97
+ # constraint as a String
98
+ config.middleware.use Rack::SslEnforcer, :only_methods => 'POST'
99
+ # Please note that, for instance, GET requests would be accessible via SSL and non-SSL connection here
100
+
101
+ config.middleware.use Rack::SslEnforcer, :except_methods => ['GET', 'HEAD']
102
+ ```
103
+
104
+ Note: The `:hosts` constraint takes precedence over the `:path` constraint. Please see the tests for examples.
105
+
106
+
107
+ ### Environment constraints
108
+
109
+ You can enforce SSL connections only for certain environments with `:only_environments` or prevent certain environments from being forced to SSL with `:except_environments`.
110
+ Environment constraints may be a `String`, a `Regex` or an array of `String` or `Regex` (possibly mixed), as shown in the following examples:
111
+
112
+ ```ruby
113
+ config.middleware.use Rack::SslEnforcer, :except_environments => 'development'
114
+
115
+ config.middleware.use Rack::SslEnforcer, :except_environments => /^[0-9a-f]+_local$/i
116
+
117
+ config.middleware.use Rack::SslEnforcer, :only_environments => ['production', /^QA/]
118
+ ```
119
+
120
+ Note: The `:environments` constraint requires one the following environment variables to be set: `RACK_ENV`, `RAILS_ENV`, `ENV`.
121
+
122
+ ### User agent constraints
123
+
124
+ You can enforce SSL connections only for certain user agents with `:only_agents` or prevent certain user agents from being forced to SSL with `:except_agents`.
125
+ User agent constraints may be a `String`, a `Regex` or an array of `String` or `Regex` (possibly mixed), as shown in the following examples:
126
+
127
+ ```ruby
128
+ config.middleware.use Rack::SslEnforcer, :except_agents => 'Googlebot'
129
+
130
+ config.middleware.use Rack::SslEnforcer, :except_agents => /[Googlebot|bingbot]/
131
+
132
+ config.middleware.use Rack::SslEnforcer, :only_agents => ['test-secu-bot', /custom-crawler[0-9a-f]/]
133
+ ```
134
+
135
+ ### Force-redirection to non-SSL connection if constraint is not matched
136
+
137
+ Use the `:strict` option to force non-SSL connection for all requests not matching the constraints you set. Examples:
138
+
139
+ ```ruby
140
+ config.middleware.use Rack::SslEnforcer, :only => ["/login", /\.xml$/], :strict => true
141
+ # https://example.com/demo would be redirected to http://example.com/demo
142
+
143
+ config.middleware.use Rack::SslEnforcer, :except_hosts => 'demo.example.com', :strict => true
144
+ # https://demo.example.com would be redirected to http://demo.example.com
145
+ ```
146
+
147
+ ### Automatic method constraints
148
+
149
+ In the case where you have matching URLs with different HTTP methods – for instance Rails RESTful routes: `GET /users`, `POST /users`, `GET /user/:id` and `PUT /user/:id` – you may need to force POST and PUT requests to SSL connection but redirect to non-SSL connection on GET.
150
+
151
+ ```ruby
152
+ config.middleware.use Rack::SslEnforcer, :only => [%r{^/users/}], :mixed => true
153
+ ```
154
+
155
+ The above will allow you to POST/PUT from the secure/non-secure URLs keeping the original schema.
156
+
157
+ ### HTTP Strict Transport Security (HSTS)
158
+
159
+ To set HSTS expiry and subdomain inclusion (defaults respectively to `one year` and `true`).
160
+
161
+ ```ruby
162
+ config.middleware.use Rack::SslEnforcer, :hsts => { :expires => 500, :subdomains => false }
163
+ config.middleware.use Rack::SslEnforcer, :hsts => true # equivalent to { :expires => 31536000, :subdomains => true }
164
+ ```
165
+ Please note that the strict option disables HSTS.
166
+
167
+ ### Redirect to specific URL (e.g. if you're using a proxy)
168
+
169
+ You might need the `:redirect_to` option if the requested URL can't be determined.
170
+
171
+ ```ruby
172
+ config.middleware.use Rack::SslEnforcer, :redirect_to => 'https://example.org'
173
+ ```
174
+
175
+ ### Redirect with specific HTTP status code
176
+
177
+ By default it redirects with HTTP status code 301(Moved Permanently). Sometimes you might need to redirect with different HTTP status code:
178
+
179
+ ```ruby
180
+ config.middleware.use Rack::SslEnforcer, :redirect_code => 302
181
+ ```
182
+
183
+ ### Custom HTTP port
184
+
185
+ If you're using a different port than the default (80) for HTTP, you can specify it with the `:http_port` option:
186
+
187
+ ```ruby
188
+ config.middleware.use Rack::SslEnforcer, :http_port => 8080
189
+ ```
190
+
191
+ ### Custom HTTPS port
192
+
193
+ If you're using a different port than the default (443) for HTTPS, you can specify it with the `:https_port` option:
194
+
195
+ ```ruby
196
+ config.middleware.use Rack::SslEnforcer, :https_port => 444
197
+ ```
198
+
199
+ ### Secure cookies disabling
200
+
201
+ Finally you might want to share a cookie based session between HTTP and HTTPS.
202
+ This is not possible by default with Rack::SslEnforcer for [security reasons](http://en.wikipedia.org/wiki/HTTP_cookie#Cookie_theft_and_session_hijacking).
203
+
204
+ Nevertheless, you can set the `:force_secure_cookies` option to `false` in order to be able to share a cookie based session between HTTP and HTTPS:
205
+
206
+ ```ruby
207
+ config.middleware.use Rack::SslEnforcer, :only => "/login", :force_secure_cookies => false
208
+ ```
209
+
210
+ But be aware that if you do so, you have to make sure that the content of you cookie is encoded.
211
+ This can be done using a coder with [Rack::Session::Cookie](https://github.com/rack/rack/blob/master/lib/rack/session/cookie.rb#L28-42).
212
+
213
+ ### Running code before redirect
214
+
215
+ You may want to run some code before rack-ssl-enforcer forces a redirect. This code could do something like log that a redirect was done, or if this is used in a Rails app, keeping the flash when redirecting:
216
+
217
+
218
+ ```ruby
219
+ config.middleware.use Rack::SslEnforcer, :only => '/login', :before_redirect => Proc.new { |request|
220
+ #keep flash on redirect
221
+ request.session[:flash].keep if !request.session.nil? && request.session.key?('flash') && !request.session['flash'].empty?
222
+ }
223
+ ```
224
+
225
+ ### Custom or empty response body
226
+
227
+ The default response body is:
228
+
229
+ ```html
230
+ <html><body>You are being <a href="https://www.example.org/">redirected</a>.</body></html>
231
+ ```
232
+
233
+ To supply a custom message, provide a string as `:redirect_html`:
234
+
235
+ ```ruby
236
+ config.middleware.use Rack::SslEnforcer, :redirect_html => 'Redirecting!'
237
+ ```
238
+
239
+ To supply a series of responses for Rack to chunk, provide a [permissable Rack body object](http://rack.rubyforge.org/doc/SPEC.html):
240
+
241
+ ```ruby
242
+ config.middleware.use Rack::SslEnforcer, :redirect_html => ['<html>','<body>','Hello!','</body>','</html>']
243
+ ```
244
+
245
+ To supply an empty response body, provide :redirect_html as false:
246
+
247
+ ```ruby
248
+ config.middleware.use Rack::SslEnforcer, :redirect_html => false
249
+ ```
250
+
251
+ ## Deployment
252
+
253
+ If you run your application behind a proxy (e.g. Nginx) you may need to do some configuration on that side. If you don't you may experience an infinite redirect loop.
254
+
255
+ The reason this happens is that Rack::SslEnforcer can't detect if you are running SSL or not. The solution is to have your front-end server send extra headers for Rack::SslEnforcer to identify the request protocol.
256
+
257
+ ### Nginx
258
+
259
+ In the `location` block for your app's SSL configuration, include the following proxy header configuration:
260
+
261
+ `proxy_set_header X-Forwarded-Proto https;`
262
+
263
+ ### Passenger
264
+
265
+ Or, if you're using mod_rails/passenger (which will ignore the proxy_xxx directives):
266
+
267
+ `passenger_set_cgi_param HTTP_X_FORWARDED_PROTO https;`
268
+
269
+ If you're sharing a single `server` block for http AND https access you can add:
270
+
271
+ `passenger_set_cgi_param HTTP_X_FORWARDED_PROTO $scheme;`
272
+
273
+ This makes sure that Rack::SslEnforcer knows it's being accessed over SSL. Just restart Nginx for these changes to take effect.
274
+
275
+ ## TODO
276
+
277
+ * Cleanup tests
278
+
279
+ #### Contributors
280
+
281
+ [https://github.com/tobmatth/rack-ssl-enforcer/graphs/contributors](https://github.com/tobmatth/rack-ssl-enforcer/graphs/contributors)
282
+
283
+ ## Credits
284
+
285
+ Flagging cookies as secure functionality and HSTS support is greatly inspired by [Joshua Peek's Rack::SSL](https://github.com/josh/rack-ssl).
286
+
287
+ ## Note on Patches / Pull Requests
288
+
289
+ * Fork the project.
290
+ * Code your feature addition or bug fix.
291
+ * **Add tests for it.** This is important so we don't break it in a future version unintentionally.
292
+ * Commit, do not mess with Rakefile or version number. If you want to have your own version, that's fine but bump version in a commit by itself so we can ignore it when merging.
293
+ * Send a pull request. Bonus points for topic branches.
294
+
295
+ ## Copyright
296
+
297
+ Copyright (c) 2010-2013 Tobias Matthies. See [LICENSE](https://github.com/tobmatth/rack-ssl-enforcer/blob/master/LICENSE) for details.
@@ -1 +1 @@
1
- require 'rack/ssl-enforcer'
1
+ require 'rack/ssl-enforcer'
@@ -1,199 +1,204 @@
1
- require 'rack/ssl-enforcer/constraint'
2
-
3
- module Rack
4
-
5
- class SslEnforcer
6
-
7
- CONSTRAINTS_BY_TYPE = {
8
- :hosts => [:only_hosts, :except_hosts],
9
- :agents => [:only_agents, :except_agents],
10
- :path => [:only, :except],
11
- :methods => [:only_methods, :except_methods],
12
- :environments => [:only_environments, :except_environments]
13
- }
14
-
15
- # Warning: If you set the option force_secure_cookies to false, make sure that your cookies
16
- # are encoded and that you understand the consequences (see documentation)
17
- def initialize(app, options={})
18
- default_options = {
19
- :redirect_to => nil,
20
- :redirect_code => nil,
21
- :strict => false,
22
- :mixed => false,
23
- :hsts => nil,
24
- :http_port => nil,
25
- :https_port => nil,
26
- :force_secure_cookies => true,
27
- :before_redirect => nil
28
- }
29
- CONSTRAINTS_BY_TYPE.values.each do |constraints|
30
- constraints.each { |constraint| default_options[constraint] = nil }
31
- end
32
-
33
- @app, @options = app, default_options.merge(options)
34
- end
35
-
36
- def call(env)
37
- @request = Rack::Request.new(env)
38
-
39
- return @app.call(env) if ignore?
40
-
41
- @scheme = if enforce_ssl?
42
- 'https'
43
- elsif enforce_non_ssl?
44
- 'http'
45
- end
46
-
47
- if redirect_required?
48
- call_before_redirect
49
- modify_location_and_redirect
50
- elsif ssl_request?
51
- status, headers, body = @app.call(env)
52
- flag_cookies_as_secure!(headers) if @options[:force_secure_cookies]
53
- set_hsts_headers!(headers) if @options[:hsts] && !@options[:strict]
54
- [status, headers, body]
55
- else
56
- @app.call(env)
57
- end
58
- end
59
-
60
- private
61
-
62
- def redirect_required?
63
- scheme_mismatch? || host_mismatch?
64
- end
65
-
66
- def ignore?
67
- if @options[:ignore]
68
- rules = [@options[:ignore]].flatten.compact
69
- rules.any? do |rule|
70
- SslEnforcerConstraint.new(:ignore, rule, @request).matches?
71
- end
72
- else
73
- false
74
- end
75
- end
76
-
77
- def scheme_mismatch?
78
- @scheme && @scheme != current_scheme
79
- end
80
-
81
- def host_mismatch?
82
- destination_host && destination_host != @request.host
83
- end
84
-
85
- def call_before_redirect
86
- @options[:before_redirect].call unless @options[:before_redirect].nil?
87
- end
88
-
89
- def modify_location_and_redirect
90
- location = "#{current_scheme}://#{@request.host}#{@request.fullpath}"
91
- location = replace_scheme(location, @scheme)
92
- location = replace_host(location, @options[:redirect_to])
93
- redirect_to(location)
94
- end
95
-
96
- def redirect_to(location)
97
- body = "<html><body>You are being <a href=\"#{location}\">redirected</a>.</body></html>"
98
- [@options[:redirect_code] || 301, { 'Content-Type' => 'text/html', 'Location' => location }, [body]]
99
- end
100
-
101
- def ssl_request?
102
- current_scheme == 'https'
103
- end
104
-
105
- def destination_host
106
- if @options[:redirect_to]
107
- host_parts = URI.split(@options[:redirect_to])
108
- host_parts[2] || host_parts[5]
109
- end
110
- end
111
-
112
- # Fixed in rack >= 1.3
113
- def current_scheme
114
- if @request.env['HTTPS'] == 'on' || @request.env['HTTP_X_SSL_REQUEST'] == 'on'
115
- 'https'
116
- elsif @request.env['HTTP_X_FORWARDED_PROTO']
117
- @request.env['HTTP_X_FORWARDED_PROTO'].split(',')[0]
118
- else
119
- @request.scheme
120
- end
121
- end
122
-
123
- def enforce_ssl_for?(keys)
124
- provided_keys = keys.select { |key| @options[key] }
125
- if provided_keys.empty?
126
- true
127
- else
128
- provided_keys.all? do |key|
129
- rules = [@options[key]].flatten.compact
130
- rules.send([:except_hosts, :except_agents, :except_environments, :except].include?(key) ? :all? : :any?) do |rule|
131
- SslEnforcerConstraint.new(key, rule, @request).matches?
132
- end
133
- end
134
- end
135
- end
136
-
137
- def enforce_non_ssl?
138
- @options[:strict] || @options[:mixed] && !(@request.request_method == 'PUT' || @request.request_method == 'POST')
139
- end
140
-
141
- def enforce_ssl?
142
- CONSTRAINTS_BY_TYPE.inject(true) do |memo, (type, keys)|
143
- memo && enforce_ssl_for?(keys)
144
- end
145
- end
146
-
147
- def replace_scheme(uri, scheme)
148
- return uri if not scheme_mismatch?
149
-
150
- port = adjust_port_to(scheme)
151
- uri_parts = URI.split(uri)
152
- uri_parts[3] = port unless port.nil?
153
- uri_parts[0] = scheme
154
- URI::HTTP.new(*uri_parts).to_s
155
- end
156
-
157
- def replace_host(uri, host)
158
- return uri unless host_mismatch?
159
-
160
- host_parts = URI.split(host)
161
- new_host = host_parts[2] || host_parts[5]
162
- uri_parts = URI.split(uri)
163
- uri_parts[2] = new_host
164
- URI::HTTPS.new(*uri_parts).to_s
165
- end
166
-
167
- def adjust_port_to(scheme)
168
- if scheme == 'https'
169
- @options[:https_port] if @options[:https_port] && @options[:https_port] != URI::HTTPS.default_port
170
- elsif scheme == 'http'
171
- @options[:http_port] if @options[:http_port] && @options[:http_port] != URI::HTTP.default_port
172
- end
173
- end
174
-
175
- # see http://en.wikipedia.org/wiki/HTTP_cookie#Cookie_theft_and_session_hijacking
176
- def flag_cookies_as_secure!(headers)
177
- if cookies = headers['Set-Cookie']
178
- # Support Rails 2.3 / Rack 1.1 arrays as headers
179
- unless cookies.is_a?(Array)
180
- cookies = cookies.split("\n")
181
- end
182
-
183
- headers['Set-Cookie'] = cookies.map do |cookie|
184
- cookie !~ /(^|;\s)secure($|;)/ ? "#{cookie}; secure" : cookie
185
- end.join("\n")
186
- end
187
- end
188
-
189
- # see http://en.wikipedia.org/wiki/Strict_Transport_Security
190
- def set_hsts_headers!(headers)
191
- opts = { :expires => 31536000, :subdomains => true }
192
- opts.merge!(@options[:hsts]) if @options[:hsts].is_a? Hash
193
- value = "max-age=#{opts[:expires]}"
194
- value += "; includeSubDomains" if opts[:subdomains]
195
- headers.merge!({ 'Strict-Transport-Security' => value })
196
- end
197
-
198
- end
199
- end
1
+ require 'rack/ssl-enforcer/constraint'
2
+
3
+ module Rack
4
+
5
+ class SslEnforcer
6
+
7
+ CONSTRAINTS_BY_TYPE = {
8
+ :hosts => [:only_hosts, :except_hosts],
9
+ :agents => [:only_agents, :except_agents],
10
+ :path => [:only, :except],
11
+ :methods => [:only_methods, :except_methods],
12
+ :environments => [:only_environments, :except_environments]
13
+ }
14
+
15
+ # Warning: If you set the option force_secure_cookies to false, make sure that your cookies
16
+ # are encoded and that you understand the consequences (see documentation)
17
+ def initialize(app, options={})
18
+ default_options = {
19
+ :redirect_to => nil,
20
+ :redirect_code => nil,
21
+ :strict => false,
22
+ :mixed => false,
23
+ :hsts => nil,
24
+ :http_port => nil,
25
+ :https_port => nil,
26
+ :force_secure_cookies => true,
27
+ :redirect_html => nil,
28
+ :before_redirect => nil
29
+ }
30
+ CONSTRAINTS_BY_TYPE.values.each do |constraints|
31
+ constraints.each { |constraint| default_options[constraint] = nil }
32
+ end
33
+
34
+ @app, @options = app, default_options.merge(options)
35
+ end
36
+
37
+ def call(env)
38
+ @request = Rack::Request.new(env)
39
+
40
+ return @app.call(env) if ignore?
41
+
42
+ @scheme = if enforce_ssl?
43
+ 'https'
44
+ elsif enforce_non_ssl?
45
+ 'http'
46
+ end
47
+
48
+ if redirect_required?
49
+ call_before_redirect
50
+ modify_location_and_redirect
51
+ elsif ssl_request?
52
+ status, headers, body = @app.call(env)
53
+ flag_cookies_as_secure!(headers) if @options[:force_secure_cookies]
54
+ set_hsts_headers!(headers) if @options[:hsts] && !@options[:strict]
55
+ [status, headers, body]
56
+ else
57
+ @app.call(env)
58
+ end
59
+ end
60
+
61
+ private
62
+
63
+ def redirect_required?
64
+ scheme_mismatch? || host_mismatch?
65
+ end
66
+
67
+ def ignore?
68
+ if @options[:ignore]
69
+ rules = [@options[:ignore]].flatten.compact
70
+ rules.any? do |rule|
71
+ SslEnforcerConstraint.new(:ignore, rule, @request).matches?
72
+ end
73
+ else
74
+ false
75
+ end
76
+ end
77
+
78
+ def scheme_mismatch?
79
+ @scheme && @scheme != current_scheme
80
+ end
81
+
82
+ def host_mismatch?
83
+ destination_host && destination_host != @request.host
84
+ end
85
+
86
+ def call_before_redirect
87
+ @options[:before_redirect].call(@request) unless @options[:before_redirect].nil?
88
+ end
89
+
90
+ def modify_location_and_redirect
91
+ location = "#{current_scheme}://#{@request.host}#{@request.fullpath}"
92
+ location = replace_scheme(location, @scheme)
93
+ location = replace_host(location, @options[:redirect_to])
94
+ redirect_to(location)
95
+ end
96
+
97
+ def redirect_to(location)
98
+ body = []
99
+ body << "<html><body>You are being <a href=\"#{location}\">redirected</a>.</body></html>" if @options[:redirect_html].nil?
100
+ body << @options[:redirect_html] if @options[:redirect_html].is_a?(String)
101
+ body = @options[:redirect_html] if @options[:redirect_html].respond_to?('each')
102
+
103
+ [@options[:redirect_code] || 301, { 'Content-Type' => 'text/html', 'Location' => location }, body]
104
+ end
105
+
106
+ def ssl_request?
107
+ current_scheme == 'https'
108
+ end
109
+
110
+ def destination_host
111
+ if @options[:redirect_to]
112
+ host_parts = URI.split(URI.encode(@options[:redirect_to]))
113
+ host_parts[2] || host_parts[5]
114
+ end
115
+ end
116
+
117
+ # Fixed in rack >= 1.3
118
+ def current_scheme
119
+ if @request.env['HTTPS'] == 'on' || @request.env['HTTP_X_SSL_REQUEST'] == 'on'
120
+ 'https'
121
+ elsif @request.env['HTTP_X_FORWARDED_PROTO']
122
+ @request.env['HTTP_X_FORWARDED_PROTO'].split(',')[0]
123
+ else
124
+ @request.scheme
125
+ end
126
+ end
127
+
128
+ def enforce_ssl_for?(keys)
129
+ provided_keys = keys.select { |key| @options[key] }
130
+ if provided_keys.empty?
131
+ true
132
+ else
133
+ provided_keys.all? do |key|
134
+ rules = [@options[key]].flatten.compact
135
+ rules.send([:except_hosts, :except_agents, :except_environments, :except].include?(key) ? :all? : :any?) do |rule|
136
+ SslEnforcerConstraint.new(key, rule, @request).matches?
137
+ end
138
+ end
139
+ end
140
+ end
141
+
142
+ def enforce_non_ssl?
143
+ @options[:strict] || @options[:mixed] && !(@request.request_method == 'PUT' || @request.request_method == 'POST')
144
+ end
145
+
146
+ def enforce_ssl?
147
+ CONSTRAINTS_BY_TYPE.inject(true) do |memo, (type, keys)|
148
+ memo && enforce_ssl_for?(keys)
149
+ end
150
+ end
151
+
152
+ def replace_scheme(uri, scheme)
153
+ return uri if not scheme_mismatch?
154
+
155
+ port = adjust_port_to(scheme)
156
+ uri_parts = URI.split(URI.encode(uri))
157
+ uri_parts[3] = port unless port.nil?
158
+ uri_parts[0] = scheme
159
+ URI::HTTP.new(*uri_parts).to_s
160
+ end
161
+
162
+ def replace_host(uri, host)
163
+ return uri unless host_mismatch?
164
+
165
+ host_parts = URI.split(URI.encode(host))
166
+ new_host = host_parts[2] || host_parts[5]
167
+ uri_parts = URI.split(URI.encode(uri))
168
+ uri_parts[2] = new_host
169
+ URI::HTTPS.new(*uri_parts).to_s
170
+ end
171
+
172
+ def adjust_port_to(scheme)
173
+ if scheme == 'https'
174
+ @options[:https_port] if @options[:https_port] && @options[:https_port] != URI::HTTPS.default_port
175
+ elsif scheme == 'http'
176
+ @options[:http_port] if @options[:http_port] && @options[:http_port] != URI::HTTP.default_port
177
+ end
178
+ end
179
+
180
+ # see http://en.wikipedia.org/wiki/HTTP_cookie#Cookie_theft_and_session_hijacking
181
+ def flag_cookies_as_secure!(headers)
182
+ if cookies = headers['Set-Cookie']
183
+ # Support Rails 2.3 / Rack 1.1 arrays as headers
184
+ unless cookies.is_a?(Array)
185
+ cookies = cookies.split("\n")
186
+ end
187
+
188
+ headers['Set-Cookie'] = cookies.map do |cookie|
189
+ cookie !~ /(^|;\s)secure($|;)/ ? "#{cookie}; secure" : cookie
190
+ end.join("\n")
191
+ end
192
+ end
193
+
194
+ # see http://en.wikipedia.org/wiki/Strict_Transport_Security
195
+ def set_hsts_headers!(headers)
196
+ opts = { :expires => 31536000, :subdomains => true }
197
+ opts.merge!(@options[:hsts]) if @options[:hsts].is_a? Hash
198
+ value = "max-age=#{opts[:expires]}"
199
+ value += "; includeSubDomains" if opts[:subdomains]
200
+ headers.merge!({ 'Strict-Transport-Security' => value })
201
+ end
202
+
203
+ end
204
+ end
@@ -1,42 +1,42 @@
1
- class SslEnforcerConstraint
2
- def initialize(name, rule, request)
3
- @name = name
4
- @rule = rule
5
- @request = request
6
- end
7
-
8
- def matches?
9
- if @rule.is_a?(String) && [:only, :except].include?(@name)
10
- result = tested_string[0, @rule.size].send(operator, @rule)
11
- else
12
- result = tested_string.send(operator, @rule)
13
- end
14
-
15
- negate_result? ? !result : result
16
- end
17
-
18
- private
19
-
20
- def negate_result?
21
- @name.to_s =~ /except/
22
- end
23
-
24
- def operator
25
- @rule.is_a?(Regexp) ? "=~" : "=="
26
- end
27
-
28
- def tested_string
29
- case @name.to_s
30
- when /hosts/
31
- @request.host
32
- when /methods/
33
- @request.request_method
34
- when /environments/
35
- ENV["RACK_ENV"] || ENV["RAILS_ENV"] || ENV["ENV"]
36
- when /agents/
37
- @request.user_agent
38
- else
39
- @request.path
40
- end
41
- end
42
- end
1
+ class SslEnforcerConstraint
2
+ def initialize(name, rule, request)
3
+ @name = name
4
+ @rule = rule
5
+ @request = request
6
+ end
7
+
8
+ def matches?
9
+ if @rule.is_a?(String) && [:only, :except].include?(@name)
10
+ result = tested_string[0, @rule.size].send(operator, @rule)
11
+ else
12
+ result = tested_string.send(operator, @rule)
13
+ end
14
+
15
+ negate_result? ? !result : result
16
+ end
17
+
18
+ private
19
+
20
+ def negate_result?
21
+ @name.to_s =~ /except/
22
+ end
23
+
24
+ def operator
25
+ @rule.is_a?(Regexp) ? "=~" : "=="
26
+ end
27
+
28
+ def tested_string
29
+ case @name.to_s
30
+ when /hosts/
31
+ @request.host
32
+ when /methods/
33
+ @request.request_method
34
+ when /environments/
35
+ ENV["RACK_ENV"] || ENV["RAILS_ENV"] || ENV["ENV"]
36
+ when /agents/
37
+ @request.user_agent
38
+ else
39
+ @request.path
40
+ end
41
+ end
42
+ end
@@ -1,5 +1,5 @@
1
- module Rack
2
- class SslEnforcer
3
- VERSION = "0.2.6"
4
- end
5
- end
1
+ module Rack
2
+ class SslEnforcer
3
+ VERSION = "0.2.7"
4
+ end
5
+ end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-ssl-enforcer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
5
- prerelease:
4
+ version: 0.2.7
6
5
  platform: ruby
7
6
  authors:
8
7
  - Tobias Matthies
@@ -10,12 +9,11 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2013-09-18 00:00:00.000000000 Z
12
+ date: 2014-05-23 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: bundler
17
16
  requirement: !ruby/object:Gem::Requirement
18
- none: false
19
17
  requirements:
20
18
  - - ~>
21
19
  - !ruby/object:Gem::Version
@@ -23,7 +21,6 @@ dependencies:
23
21
  type: :development
24
22
  prerelease: false
25
23
  version_requirements: !ruby/object:Gem::Requirement
26
- none: false
27
24
  requirements:
28
25
  - - ~>
29
26
  - !ruby/object:Gem::Version
@@ -31,7 +28,6 @@ dependencies:
31
28
  - !ruby/object:Gem::Dependency
32
29
  name: test-unit
33
30
  requirement: !ruby/object:Gem::Requirement
34
- none: false
35
31
  requirements:
36
32
  - - ~>
37
33
  - !ruby/object:Gem::Version
@@ -39,7 +35,6 @@ dependencies:
39
35
  type: :development
40
36
  prerelease: false
41
37
  version_requirements: !ruby/object:Gem::Requirement
42
- none: false
43
38
  requirements:
44
39
  - - ~>
45
40
  - !ruby/object:Gem::Version
@@ -47,7 +42,6 @@ dependencies:
47
42
  - !ruby/object:Gem::Dependency
48
43
  name: shoulda
49
44
  requirement: !ruby/object:Gem::Requirement
50
- none: false
51
45
  requirements:
52
46
  - - ~>
53
47
  - !ruby/object:Gem::Version
@@ -55,7 +49,6 @@ dependencies:
55
49
  type: :development
56
50
  prerelease: false
57
51
  version_requirements: !ruby/object:Gem::Requirement
58
- none: false
59
52
  requirements:
60
53
  - - ~>
61
54
  - !ruby/object:Gem::Version
@@ -63,7 +56,6 @@ dependencies:
63
56
  - !ruby/object:Gem::Dependency
64
57
  name: rack
65
58
  requirement: !ruby/object:Gem::Requirement
66
- none: false
67
59
  requirements:
68
60
  - - ~>
69
61
  - !ruby/object:Gem::Version
@@ -71,7 +63,6 @@ dependencies:
71
63
  type: :development
72
64
  prerelease: false
73
65
  version_requirements: !ruby/object:Gem::Requirement
74
- none: false
75
66
  requirements:
76
67
  - - ~>
77
68
  - !ruby/object:Gem::Version
@@ -79,7 +70,6 @@ dependencies:
79
70
  - !ruby/object:Gem::Dependency
80
71
  name: rack-test
81
72
  requirement: !ruby/object:Gem::Requirement
82
- none: false
83
73
  requirements:
84
74
  - - ~>
85
75
  - !ruby/object:Gem::Version
@@ -87,7 +77,6 @@ dependencies:
87
77
  type: :development
88
78
  prerelease: false
89
79
  version_requirements: !ruby/object:Gem::Requirement
90
- none: false
91
80
  requirements:
92
81
  - - ~>
93
82
  - !ruby/object:Gem::Version
@@ -108,29 +97,25 @@ files:
108
97
  - README.md
109
98
  homepage: http://github.com/tobmatth/rack-ssl-enforcer
110
99
  licenses: []
100
+ metadata: {}
111
101
  post_install_message:
112
102
  rdoc_options: []
113
103
  require_paths:
114
104
  - lib
115
105
  required_ruby_version: !ruby/object:Gem::Requirement
116
- none: false
117
106
  requirements:
118
- - - ! '>='
107
+ - - '>='
119
108
  - !ruby/object:Gem::Version
120
109
  version: '0'
121
- segments:
122
- - 0
123
- hash: 1004214355
124
110
  required_rubygems_version: !ruby/object:Gem::Requirement
125
- none: false
126
111
  requirements:
127
- - - ! '>='
112
+ - - '>='
128
113
  - !ruby/object:Gem::Version
129
114
  version: 1.3.6
130
115
  requirements: []
131
116
  rubyforge_project: rack-ssl-enforcer
132
- rubygems_version: 1.8.25
117
+ rubygems_version: 2.0.4
133
118
  signing_key:
134
- specification_version: 3
119
+ specification_version: 4
135
120
  summary: A simple Rack middleware to enforce SSL
136
121
  test_files: []