Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Redirect http to https

  • Loading branch information...
commit 7ff810021746a9976eb19aa49fd62691a4da055f 0 parents
@josh josh authored
Showing with 98 additions and 0 deletions.
  1. +22 −0 LICENSE
  2. +7 −0 Rakefile
  3. +36 −0 lib/rack/ssl.rb
  4. +33 −0 test/test_ssl.rb
22 LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2010 Joshua Peek
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
7 Rakefile
@@ -0,0 +1,7 @@
+require 'rake/testtask'
+
+task :default => :test
+
+Rake::TestTask.new do |t|
+ t.warning = true
+end
36 lib/rack/ssl.rb
@@ -0,0 +1,36 @@
+require 'rack'
+require 'rack/request'
+
+module Rack
+ class SSL
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ if scheme(env) == 'https'
+ @app.call(env)
+ else
+ redirect_to_https(env)
+ end
+ end
+
+ private
+ # Fixed in rack >= 1.3
+ def scheme(env)
+ if env['HTTPS'] == 'on'
+ 'https'
+ elsif env['HTTP_X_FORWARDED_PROTO']
+ env['HTTP_X_FORWARDED_PROTO'].split(',')[0]
+ else
+ env['rack.url_scheme']
+ end
+ end
+
+ def redirect_to_https(env)
+ req = Request.new(env)
+ location = req.url.sub(/^http:/, 'https:')
+ [301, {'Content-Type' => "text/html", 'Location' => location}, []]
+ end
+ end
+end
33 test/test_ssl.rb
@@ -0,0 +1,33 @@
+require 'rack/ssl'
+
+require 'test/unit'
+require 'rack/test'
+
+class TestSSL < Test::Unit::TestCase
+ include Rack::Test::Methods
+
+ def default_app
+ Rack::SSL.new(lambda { |env| [200, {"Content-Type" => "text/html"}, ["OK"]] })
+ end
+
+ def app
+ @app ||= default_app
+ end
+ attr_writer :app
+
+ def test_allows_https_url
+ get "https://example.org/path?key=value"
+ assert last_response.ok?
+ end
+
+ def test_allows_https_proxy_header_url
+ get "http://example.org/path?key=value", {}, 'HTTP_X_FORWARDED_PROTO' => "https"
+ assert last_response.ok?
+ end
+
+ def test_redirects_http_to_https
+ get "http://example.org/path?key=value"
+ assert last_response.redirect?
+ assert_equal "https://example.org/path?key=value", last_response.headers['Location']
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.