module Locomotive::Steam module Middlewares # If an old URL has been found among the site url_redirections hash, # perform a 310 redirection to the new URL. # It is highly useful when the site existed before but was ran by another system. # # See the specs (spec/unit/middlewares/url_redirection_spec.rb) for more details. # class UrlRedirection < ThreadSafe include Helpers def _call if url = redirect_url emit_event redirect_to url end end protected def requested_url request.env['locomotive.path'] || request.fullpath end def emit_event ActiveSupport::Notifications.instrument('steam.serve.url_redirection', { site_id: site._id, url: requested_url }) end def redirect_url return false if site.url_redirections.nil? || site.url_redirections.size == 0 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 end end