diff options
-rw-r--r-- | actionpack/lib/action_dispatch/journey/route.rb | 54 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/mapper.rb | 11 |
2 files changed, 49 insertions, 16 deletions
diff --git a/actionpack/lib/action_dispatch/journey/route.rb b/actionpack/lib/action_dispatch/journey/route.rb index fa69ba776a..5d5fe4698d 100644 --- a/actionpack/lib/action_dispatch/journey/route.rb +++ b/actionpack/lib/action_dispatch/journey/route.rb @@ -8,9 +8,49 @@ module ActionDispatch attr_accessor :precedence - ANY = // + module VerbMatchers + VERBS = %w{ DELETE GET HEAD OPTIONS LINK PATCH POST PUT TRACE UNLINK } + VERBS.each do |v| + class_eval <<-eoc + class #{v} + def self.verb; name.split("::").last; end + def self.call(req); req.#{v.downcase}?; end + end + eoc + end + + class Unknown + attr_reader :verb + + def initialize(verb) + @verb = verb + end + + def call(request); @verb === request.request_method; end + end + + class All + def self.call(_); true; end + def self.verb; ''; end + end + + VERB_TO_CLASS = VERBS.each_with_object({ :all => All }) do |verb, hash| + klass = const_get verb + hash[verb] = klass + hash[verb.downcase] = klass + hash[verb.downcase.to_sym] = klass + end + + end + + def self.verb_matcher(verb) + VerbMatchers::VERB_TO_CLASS.fetch(verb) do + VerbMatchers::Unknown.new verb.to_s.dasherize.upcase + end + end + def self.build(name, app, path, constraints, required_defaults, defaults) - request_method_match = constraints.delete(:request_method) || ANY + request_method_match = verb_matcher(constraints.delete(:request_method)) || [] new name, app, path, constraints, required_defaults, defaults, request_method_match end @@ -121,18 +161,20 @@ module ActionDispatch end def requires_matching_verb? - @request_method_match != ANY + !@request_method_match.all? { |x| x == VerbMatchers::All } end def verb - @request_method_match + %r[^#{verbs.join('|')}$] end private + def verbs + @request_method_match.map(&:verb) + end def match_verb(request) - return true unless requires_matching_verb? - verb === request.request_method + @request_method_match.any? { |m| m.call request } end end end diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 42257ac3d7..0afe1852f2 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -178,16 +178,7 @@ module ActionDispatch private :build_conditions def request_method - # Rack-Mount requires that :request_method be a regular expression. - # :request_method represents the HTTP verb that matches this route. - # - # Here we munge values before they get sent on to rack-mount. - if @via == [:all] - // - else - verbs = @via.map { |m| m.to_s.dasherize.upcase } - %r[^#{verbs.join('|')}$] - end + @via.map { |x| Journey::Route.verb_matcher(x) } end private :request_method |