Return a (target, url_args) tuple or raise HTTPError(400/404/405).
(self, environ)
| 452 | raise RouteBuildError('Missing URL argument: %r' % E.args[0]) |
| 453 | |
| 454 | def match(self, environ): |
| 455 | """ Return a (target, url_args) tuple or raise HTTPError(400/404/405). """ |
| 456 | verb = environ['REQUEST_METHOD'].upper() |
| 457 | path = environ['PATH_INFO'] or '/' |
| 458 | |
| 459 | methods = ('PROXY', 'HEAD', 'GET', 'ANY') if verb == 'HEAD' else ('PROXY', verb, 'ANY') |
| 460 | |
| 461 | for method in methods: |
| 462 | if method in self.static and path in self.static[method]: |
| 463 | target, getargs = self.static[method][path] |
| 464 | return target, getargs(path) if getargs else {} |
| 465 | elif method in self.dyna_regexes: |
| 466 | for combined, rules in self.dyna_regexes[method]: |
| 467 | match = combined(path) |
| 468 | if match: |
| 469 | target, getargs = rules[match.lastindex - 1] |
| 470 | return target, getargs(path) if getargs else {} |
| 471 | |
| 472 | # No matching route found. Collect alternative methods for 405 response |
| 473 | allowed = set([]) |
| 474 | nocheck = set(methods) |
| 475 | for method in set(self.static) - nocheck: |
| 476 | if path in self.static[method]: |
| 477 | allowed.add(method) |
| 478 | for method in set(self.dyna_regexes) - allowed - nocheck: |
| 479 | for combined, rules in self.dyna_regexes[method]: |
| 480 | match = combined(path) |
| 481 | if match: |
| 482 | allowed.add(method) |
| 483 | if allowed: |
| 484 | allow_header = ",".join(sorted(allowed)) |
| 485 | raise HTTPError(405, "Method not allowed.", Allow=allow_header) |
| 486 | |
| 487 | # No matching route and no alternative method found. We give up |
| 488 | raise HTTPError(404, "Not found: " + repr(path)) |
| 489 | |
| 490 | |
| 491 | class Route(object): |
no test coverage detected