make site url redirections accept dynamic segments (/old_store/:product_name -> /products/:product_name)

did committed Jun 02, 2017
commit 87c853571f8a45eb606077d740a47fa3c9e25f61
Showing 2 changed files with 32 additions and 1 deletions
locomotive/steam/middlewares/url_redirection.rb b/lib/locomotive/steam/middlewares/url_redirection.rb +23 -1
@@ @@ -35,7 +35,29 @@ module Locomotive::Steam
def redirect_url
return false if site.url_redirections.nil? || site.url_redirections.size == 0
- site.url_redirections.to_h[requested_url]
+ redirections_hash = site.url_redirections.to_h
+
+ redirections_hash[requested_url] || find_dynamic_url_redirection(redirections_hash)
+ end
+
+ def find_dynamic_url_redirection(redirections_hash)
+ number_of_segments = requested_url.split('/').size
+
+ # attempt to find the first dynamic route which matches
+ redirections_hash.each do |route, redirection|
+ # a little bit of optimization
+ next unless route.include?(':') && route.split('/').size == number_of_segments
+
+ _regexp = route.gsub(/:([^\/]+)/, "(?<\\1>[^\/]+)").gsub('/', '\/')
+
+ if matches = Regexp.new(_regexp).match(requested_url)
+ matches.names.each { |n| redirection.gsub!(":#{n}", matches[n]) }
+
+ return redirection
+ end
+ end
+
+ false
end
end
spec/unit/middlewares/url_redirection_spec.rb +9 -0
@@ @@ -54,6 +54,15 @@ describe Locomotive::Steam::Middlewares::UrlRedirection do
end
+ describe 'url matching a pattern' do
+
+ let(:redirections) { [['/old_images/:file', '/images/old/:file']] }
+ let(:url) { 'http://models.example.com/old_images/cat.png' }
+
+ it { is_expected.to eq [301, '/images/old/cat.png'] }
+
+ end
+
describe 'let the parent app know about the redirection when it happens' do
let(:events) { [] }