Use Addressable::URI to parse weird URIs

This commit is contained in:
Rémy Coutable 2013-03-11 22:47:05 +01:00
Родитель 671a3115b6
Коммит 2f3bfa76c4
3 изменённых файлов: 34 добавлений и 16 удалений

Просмотреть файл

@ -1,4 +1,5 @@
require 'rack/ssl-enforcer/constraint'
require 'addressable/uri'
module Rack
@ -76,9 +77,10 @@ module Rack
end
def modify_location_and_redirect
location = "#{current_scheme}://#{@request.host}#{@request.fullpath}"
location = Addressable::URI.unencode("#{current_scheme}://#{@request.host}#{@request.fullpath}")
location = replace_scheme(location, @scheme)
location = replace_host(location, @options[:redirect_to])
redirect_to(location)
end
@ -93,8 +95,8 @@ module Rack
def destination_host
if @options[:redirect_to]
host_parts = URI.split(@options[:redirect_to])
host_parts[2] || host_parts[5]
host = Addressable::URI.parse(@options[:redirect_to])
host.host || host.path
end
end
@ -133,24 +135,27 @@ module Rack
end
end
def replace_scheme(uri, scheme)
return uri if not scheme_mismatch?
def replace_scheme(uri_string, scheme)
return uri_string if not scheme_mismatch?
port = adjust_port_to(scheme)
uri_parts = URI.split(uri)
uri_parts[3] = port unless port.nil?
uri_parts[0] = scheme
URI::HTTP.new(*uri_parts).to_s
uri = Addressable::URI.parse(uri_string)
uri.port = port unless port.nil?
uri.scheme = scheme
uri.to_s
end
def replace_host(uri, host)
return uri unless host_mismatch?
def replace_host(uri_string, host_string)
return uri_string unless host_mismatch?
host_parts = URI.split(host)
new_host = host_parts[2] || host_parts[5]
uri_parts = URI.split(uri)
uri_parts[2] = new_host
URI::HTTPS.new(*uri_parts).to_s
host = Addressable::URI.parse(host_string)
new_host = host.host || host.path
uri = Addressable::URI.parse(uri_string)
uri.host = new_host
uri.to_s
end
def adjust_port_to(scheme)

Просмотреть файл

@ -15,6 +15,8 @@ Gem::Specification.new do |s|
s.required_rubygems_version = ">= 1.3.6"
s.rubyforge_project = "rack-ssl-enforcer"
s.add_dependency "addressable", "~> 2.3"
s.add_development_dependency "bundler", "~> 1.0"
s.add_development_dependency "test-unit", "~> 2.3"
s.add_development_dependency "shoulda", "~> 2.11.3"

Просмотреть файл

@ -1,7 +1,18 @@
# coding: utf-8
require 'helper'
class TestRackSslEnforcer < Test::Unit::TestCase
context 'weird URI' do
setup { mock_app }
should 'redirect to HTTPS and keep params' do
get URI.encode('http://www.example.org/store/events/539?__utmz=(direct)|whatever')
assert_equal 301, last_response.status
assert_equal 'https://www.example.org/store/events/539?__utmz=(direct)|whatever', last_response.location
end
end
context 'no options' do
setup { mock_app }