Source code for nereid.routing
# -*- coding: utf-8 -*-
"""
The host matching URL Map seems to be matching hosts well but fails in
generating/building URLs when there are same endpoints.
This patch makes strict host matching to ensure nothing skips host
matching.
Also see: https://github.com/mitsuhiko/werkzeug/issues/488
:copyright: (c) 2014 by Openlabs Technologies & Consulting (P) Limited
:license: BSD, see LICENSE for more details.
"""
from werkzeug import routing
from nereid import request
class Map(routing.Map):
def _partial_build(self, endpoint, values, method, append_unknown):
"""Helper for :meth:`build`. Returns subdomain and path for the
rule that accepts this endpoint, values and method.
:internal:
"""
# in case the method is none, try with the default method first
if method is None:
rv = self._partial_build(endpoint, values, self.default_method,
append_unknown)
if rv is not None:
return rv
host = self.map.host_matching and self.server_name or self.subdomain
# default method did not match or a specific method is passed,
# check all and go with first result.
for rule in self.map._rules_by_endpoint.get(endpoint, ()):
if rule.suitable_for(values, method, host):
rv = rule.build(values, append_unknown)
if rv is not None:
return rv
class Rule(routing.Rule):
def __init__(self, *args, **kwargs):
self.readonly = kwargs.pop('readonly', None)
self.is_csrf_exempt = kwargs.pop('exempt_csrf', False)
super(Rule, self).__init__(*args, **kwargs)
def empty(self):
"""Return an unbound copy of this rule. This can be useful if you
want to reuse an already bound URL for another map.
Ref: https://github.com/mitsuhiko/werkzeug/pull/645
"""
defaults = None
if self.defaults:
defaults = dict(self.defaults)
return self.__class__(
self.rule, defaults, self.subdomain, self.methods,
self.build_only, self.endpoint, self.strict_slashes,
self.redirect_to, self.alias, self.host
)
@property
def is_readonly(self):
if self.readonly is not None:
# If a value that is not None is explicitly set for the URL,
# then return that.
return self.readonly
# By default GET and HEAD requests are allocated a readonly cursor
return request.method in ('HEAD', 'GET')