rack-ssl-enforcer 0.2.7 → 0.2.8

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.
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,297 +1,300 @@
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
+ # 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
+ # And ignore based on blocks
92
+ config.middleware.use Rack::SslEnforcer, :ignore => lambda { |request| request.env["HTTP_X_IGNORE_SSL_ENFORCEMENT"] == "magic" }
93
+ ```
94
+
95
+ ### Method constraints
96
+
97
+ 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:
98
+
99
+ ```ruby
100
+ # constraint as a String
101
+ config.middleware.use Rack::SslEnforcer, :only_methods => 'POST'
102
+ # Please note that, for instance, GET requests would be accessible via SSL and non-SSL connection here
103
+
104
+ config.middleware.use Rack::SslEnforcer, :except_methods => ['GET', 'HEAD']
105
+ ```
106
+
107
+ Note: The `:hosts` constraint takes precedence over the `:path` constraint. Please see the tests for examples.
108
+
109
+
110
+ ### Environment constraints
111
+
112
+ You can enforce SSL connections only for certain environments with `:only_environments` or prevent certain environments from being forced to SSL with `:except_environments`.
113
+ Environment constraints may be a `String`, a `Regex` or an array of `String` or `Regex` (possibly mixed), as shown in the following examples:
114
+
115
+ ```ruby
116
+ config.middleware.use Rack::SslEnforcer, :except_environments => 'development'
117
+
118
+ config.middleware.use Rack::SslEnforcer, :except_environments => /^[0-9a-f]+_local$/i
119
+
120
+ config.middleware.use Rack::SslEnforcer, :only_environments => ['production', /^QA/]
121
+ ```
122
+
123
+ Note: The `:environments` constraint requires one the following environment variables to be set: `RACK_ENV`, `RAILS_ENV`, `ENV`.
124
+
125
+ ### User agent constraints
126
+
127
+ 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`.
128
+ User agent constraints may be a `String`, a `Regex` or an array of `String` or `Regex` (possibly mixed), as shown in the following examples:
129
+
130
+ ```ruby
131
+ config.middleware.use Rack::SslEnforcer, :except_agents => 'Googlebot'
132
+
133
+ config.middleware.use Rack::SslEnforcer, :except_agents => /[Googlebot|bingbot]/
134
+
135
+ config.middleware.use Rack::SslEnforcer, :only_agents => ['test-secu-bot', /custom-crawler[0-9a-f]/]
136
+ ```
137
+
138
+ ### Force-redirection to non-SSL connection if constraint is not matched
139
+
140
+ Use the `:strict` option to force non-SSL connection for all requests not matching the constraints you set. Examples:
141
+
142
+ ```ruby
143
+ config.middleware.use Rack::SslEnforcer, :only => ["/login", /\.xml$/], :strict => true
144
+ # https://example.com/demo would be redirected to http://example.com/demo
145
+
146
+ config.middleware.use Rack::SslEnforcer, :except_hosts => 'demo.example.com', :strict => true
147
+ # https://demo.example.com would be redirected to http://demo.example.com
148
+ ```
149
+
150
+ ### Automatic method constraints
151
+
152
+ 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.
153
+
154
+ ```ruby
155
+ config.middleware.use Rack::SslEnforcer, :only => [%r{^/users/}], :mixed => true
156
+ ```
157
+
158
+ The above will allow you to POST/PUT from the secure/non-secure URLs keeping the original schema.
159
+
160
+ ### HTTP Strict Transport Security (HSTS)
161
+
162
+ To set HSTS expiry and subdomain inclusion (defaults respectively to `one year` and `true`).
163
+
164
+ ```ruby
165
+ config.middleware.use Rack::SslEnforcer, :hsts => { :expires => 500, :subdomains => false }
166
+ config.middleware.use Rack::SslEnforcer, :hsts => true # equivalent to { :expires => 31536000, :subdomains => true }
167
+ ```
168
+ Please note that the strict option disables HSTS.
169
+
170
+ ### Redirect to specific URL (e.g. if you're using a proxy)
171
+
172
+ You might need the `:redirect_to` option if the requested URL can't be determined.
173
+
174
+ ```ruby
175
+ config.middleware.use Rack::SslEnforcer, :redirect_to => 'https://example.org'
176
+ ```
177
+
178
+ ### Redirect with specific HTTP status code
179
+
180
+ By default it redirects with HTTP status code 301(Moved Permanently). Sometimes you might need to redirect with different HTTP status code:
181
+
182
+ ```ruby
183
+ config.middleware.use Rack::SslEnforcer, :redirect_code => 302
184
+ ```
185
+
186
+ ### Custom HTTP port
187
+
188
+ If you're using a different port than the default (80) for HTTP, you can specify it with the `:http_port` option:
189
+
190
+ ```ruby
191
+ config.middleware.use Rack::SslEnforcer, :http_port => 8080
192
+ ```
193
+
194
+ ### Custom HTTPS port
195
+
196
+ If you're using a different port than the default (443) for HTTPS, you can specify it with the `:https_port` option:
197
+
198
+ ```ruby
199
+ config.middleware.use Rack::SslEnforcer, :https_port => 444
200
+ ```
201
+
202
+ ### Secure cookies disabling
203
+
204
+ Finally you might want to share a cookie based session between HTTP and HTTPS.
205
+ This is not possible by default with Rack::SslEnforcer for [security reasons](http://en.wikipedia.org/wiki/HTTP_cookie#Cookie_theft_and_session_hijacking).
206
+
207
+ 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:
208
+
209
+ ```ruby
210
+ config.middleware.use Rack::SslEnforcer, :only => "/login", :force_secure_cookies => false
211
+ ```
212
+
213
+ But be aware that if you do so, you have to make sure that the content of you cookie is encoded.
214
+ 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).
215
+
216
+ ### Running code before redirect
217
+
218
+ 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:
219
+
220
+
221
+ ```ruby
222
+ config.middleware.use Rack::SslEnforcer, :only => '/login', :before_redirect => Proc.new { |request|
223
+ #keep flash on redirect
224
+ request.session[:flash].keep if !request.session.nil? && request.session.key?('flash') && !request.session['flash'].empty?
225
+ }
226
+ ```
227
+
228
+ ### Custom or empty response body
229
+
230
+ The default response body is:
231
+
232
+ ```html
233
+ <html><body>You are being <a href="https://www.example.org/">redirected</a>.</body></html>
234
+ ```
235
+
236
+ To supply a custom message, provide a string as `:redirect_html`:
237
+
238
+ ```ruby
239
+ config.middleware.use Rack::SslEnforcer, :redirect_html => 'Redirecting!'
240
+ ```
241
+
242
+ To supply a series of responses for Rack to chunk, provide a [permissable Rack body object](http://rack.rubyforge.org/doc/SPEC.html):
243
+
244
+ ```ruby
245
+ config.middleware.use Rack::SslEnforcer, :redirect_html => ['<html>','<body>','Hello!','</body>','</html>']
246
+ ```
247
+
248
+ To supply an empty response body, provide :redirect_html as false:
249
+
250
+ ```ruby
251
+ config.middleware.use Rack::SslEnforcer, :redirect_html => false
252
+ ```
253
+
254
+ ## Deployment
255
+
256
+ 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.
257
+
258
+ 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.
259
+
260
+ ### Nginx
261
+
262
+ In the `location` block for your app's SSL configuration, include the following proxy header configuration:
263
+
264
+ `proxy_set_header X-Forwarded-Proto https;`
265
+
266
+ ### Passenger
267
+
268
+ Or, if you're using mod_rails/passenger (which will ignore the proxy_xxx directives):
269
+
270
+ `passenger_set_cgi_param HTTP_X_FORWARDED_PROTO https;`
271
+
272
+ If you're sharing a single `server` block for http AND https access you can add:
273
+
274
+ `passenger_set_cgi_param HTTP_X_FORWARDED_PROTO $scheme;`
275
+
276
+ This makes sure that Rack::SslEnforcer knows it's being accessed over SSL. Just restart Nginx for these changes to take effect.
277
+
278
+ ## TODO
279
+
280
+ * Cleanup tests
281
+
282
+ #### Contributors
283
+
284
+ [https://github.com/tobmatth/rack-ssl-enforcer/graphs/contributors](https://github.com/tobmatth/rack-ssl-enforcer/graphs/contributors)
285
+
286
+ ## Credits
287
+
288
+ Flagging cookies as secure functionality and HSTS support is greatly inspired by [Joshua Peek's Rack::SSL](https://github.com/josh/rack-ssl).
289
+
290
+ ## Note on Patches / Pull Requests
291
+
292
+ * Fork the project.
293
+ * Code your feature addition or bug fix.
294
+ * **Add tests for it.** This is important so we don't break it in a future version unintentionally.
295
+ * 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.
296
+ * Send a pull request. Bonus points for topic branches.
297
+
298
+ ## Copyright
299
+
300
+ Copyright (c) 2010-2013 Tobias Matthies. See [LICENSE](https://github.com/tobmatth/rack-ssl-enforcer/blob/master/LICENSE) for details.