lib/roda.rb in roda-2.11.0 vs lib/roda.rb in roda-2.12.0
- old
+ new
@@ -324,10 +324,11 @@
PATH_INFO = "PATH_INFO".freeze
SCRIPT_NAME = "SCRIPT_NAME".freeze
REQUEST_METHOD = "REQUEST_METHOD".freeze
EMPTY_STRING = "".freeze
SLASH = "/".freeze
+ COLON = ":".freeze
SEGMENT = "([^\\/]+)".freeze
TERM_INSPECT = "TERM".freeze
GET_REQUEST_METHOD = 'GET'.freeze
SESSION_KEY = 'rack.session'.freeze
@@ -674,16 +675,47 @@
# Match the given string to the request path. Regexp escapes the
# string so that regexp metacharacters are not matched, and recognizes
# colon tokens for placeholders.
def _match_string(str)
- consume(self.class.cached_matcher(str){Regexp.escape(str).gsub(/:(\w+)/){|m| _match_symbol_regexp($1)}})
+ if str.index(COLON)
+ consume(self.class.cached_matcher(str){Regexp.escape(str).gsub(/:(\w+)/){|m| _match_symbol_regexp($1)}})
+ else
+ rp = @remaining_path
+ if rp.start_with?("/#{str}")
+ last = str.length + 1
+ case rp[last]
+ when SLASH
+ @remaining_path = rp[last, rp.length]
+ when nil
+ @remaining_path = EMPTY_STRING
+ when Integer
+ # :nocov:
+ # Ruby 1.8 support
+ if rp[last].chr == SLASH
+ @remaining_path = rp[last, rp.length]
+ end
+ # :nocov:
+ end
+ end
+ end
end
# Match the given symbol if any segment matches.
def _match_symbol(sym)
- consume(self.class.cached_matcher(sym){_match_symbol_regexp(sym)})
+ rp = @remaining_path
+ if rp[0, 1] == SLASH
+ if last = rp.index('/', 1)
+ if last > 1
+ @captures << rp[1, last-1]
+ @remaining_path = rp[last, rp.length]
+ end
+ elsif rp.length > 1
+ @captures << rp[1,rp.length]
+ @remaining_path = EMPTY_STRING
+ end
+ end
end
# The regular expression to use for matching symbols. By default, any non-empty
# segment matches.
def _match_symbol_regexp(s)
@@ -758,28 +790,30 @@
path = @remaining_path
# For every block, we make sure to reset captures so that
# nesting matchers won't mess with each other's captures.
@captures.clear
- return unless match_all(args)
- block_result(yield(*captures))
- throw :halt, response.finish
- ensure
- @remaining_path = path
+ if match_all(args)
+ block_result(yield(*captures))
+ throw :halt, response.finish
+ else
+ @remaining_path = path
+ false
+ end
end
# Attempt to match the argument to the given request, handling
# common ruby types.
def match(matcher)
case matcher
when String
_match_string(matcher)
- when Regexp
- _match_regexp(matcher)
when Symbol
_match_symbol(matcher)
when TERM
empty_path?
+ when Regexp
+ _match_regexp(matcher)
when Hash
_match_hash(matcher)
when Array
_match_array(matcher)
when Proc