diff --git a/lib/route_downcaser/downcase_route_middleware.rb b/lib/route_downcaser/downcase_route_middleware.rb index 8f50573..f28daa7 100644 --- a/lib/route_downcaser/downcase_route_middleware.rb +++ b/lib/route_downcaser/downcase_route_middleware.rb @@ -20,6 +20,7 @@ def _call(env) # Downcase path_info if applicable path_info = downcased_uri(path_info) + path_info = path_info.gsub('%7E', '~') if path_info # If redirect configured, then return redirect request, if either # path_info has changed diff --git a/test/integration/route_middleware_test.rb b/test/integration/route_middleware_test.rb index 12c1f5a..b6f4c96 100644 --- a/test/integration/route_middleware_test.rb +++ b/test/integration/route_middleware_test.rb @@ -58,6 +58,15 @@ def call(env) assert_equal "/пиво", URI.decode_www_form_component(response.location) end + test "Can downcase path with tilde correctly" do + RouteDowncaser.configuration do |config| + config.redirect = true + end + get "/~Test~~test" + assert_equal 301, response.status + assert_equal "/~test~~test", URI.decode_www_form_component(response.location) + end + test "Can downcase longer unicode paths correctly" do RouteDowncaser.configuration do |config| config.redirect = true diff --git a/test/route_downcaser_test.rb b/test/route_downcaser_test.rb index 6e61cc7..48a6288 100644 --- a/test/route_downcaser_test.rb +++ b/test/route_downcaser_test.rb @@ -122,4 +122,27 @@ class MultibyteRedirectTests < ActiveSupport::TestCase assert_instance_of String, headers["Location"], "Headers must be strings" end end + + class SpecialSymbolsInPathTests < ActiveSupport::TestCase + setup do + @app = MyMockApp.new + RouteDowncaser.configuration do |config| + config.redirect = true + config.exclude_patterns = nil + end + end + + test "path with tildes" do + callenv = {"PATH_INFO" => "/~test~~test~", "REQUEST_METHOD" => "GET"} + RouteDowncaser::DowncaseRouteMiddleware.new(@app).call(callenv) + assert_equal("/~test~~test~", @app.env["PATH_INFO"]) + end + + test "path with escape tilde" do + callenv = {"PATH_INFO" => "/~test%7Etest~~", "REQUEST_METHOD" => "GET"} + status, headers, _ = *RouteDowncaser::DowncaseRouteMiddleware.new(@app).call(callenv) + assert_equal 301, status + assert_equal("/~test~test~~", headers["Location"]) + end + end end