rack-ssl-enforcer 0.2.6 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: []