rack-ssl-enforcer 0.2.7 → 0.2.8

Sign up to get free protection for your applications and to get access to all the features.
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.