summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pyramid/config/routes.py35
-rw-r--r--src/pyramid/config/views.py34
-rw-r--r--src/pyramid/predicates.py52
3 files changed, 67 insertions, 54 deletions
diff --git a/src/pyramid/config/routes.py b/src/pyramid/config/routes.py
index 9452a05ab..4896ce0ea 100644
--- a/src/pyramid/config/routes.py
+++ b/src/pyramid/config/routes.py
@@ -219,23 +219,24 @@ class RoutesConfiguratorMixin:
header
- This argument represents an HTTP header name or a header
- name/value pair. If the argument contains a ``:`` (colon),
- it will be considered a name/value pair
- (e.g. ``User-Agent:Mozilla/.*`` or ``Host:localhost``). If
- the value contains a colon, the value portion should be a
- regular expression. If the value does not contain a colon,
- the entire value will be considered to be the header name
- (e.g. ``If-Modified-Since``). If the value evaluates to a
- header name only without a value, the header specified by
- the name must be present in the request for this predicate
- to be true. If the value evaluates to a header name/value
- pair, the header specified by the name must be present in
- the request *and* the regular expression specified as the
- value must match the header value. Whether or not the value
- represents a header name or a header name/value pair, the
- case of the header name is not significant. If this
- predicate returns ``False``, route matching continues.
+ This value can be a string or an iterable of strings for HTTP
+ header names. The header names are determined as follow:
+
+ - If a string does not contain a ``:`` (colon), it will be
+ considered to be the header name (e.g. ``If-Modified-Since``).
+ In this case, the header specified by the name must be present
+ in the request for this string to match. Case is not significant.
+
+ - If a string contains a colon, it will be considered a
+ name/value pair (e.g. ``User-Agent:Mozilla/.*`` or
+ ``Host:localhost``), where the value part is a regular
+ expression. The header specified by the name must be present
+ in the request *and* the regular expression specified as the
+ value must match the header value. Case is not significant for
+ the header name, but it is for the value.
+
+ All strings must be matched for this predicate to return ``True``.
+ If this predicate returns ``False``, route matching continues.
accept
diff --git a/src/pyramid/config/views.py b/src/pyramid/config/views.py
index 6faa29d20..170f8a028 100644
--- a/src/pyramid/config/views.py
+++ b/src/pyramid/config/views.py
@@ -670,22 +670,24 @@ class ViewsConfiguratorMixin:
header
- This value represents an HTTP header name or a header
- name/value pair. If the value contains a ``:`` (colon), it
- will be considered a name/value pair
- (e.g. ``User-Agent:Mozilla/.*`` or ``Host:localhost``). The
- value portion should be a regular expression. If the value
- does not contain a colon, the entire value will be
- considered to be the header name
- (e.g. ``If-Modified-Since``). If the value evaluates to a
- header name only without a value, the header specified by
- the name must be present in the request for this predicate
- to be true. If the value evaluates to a header name/value
- pair, the header specified by the name must be present in
- the request *and* the regular expression specified as the
- value must match the header value. Whether or not the value
- represents a header name or a header name/value pair, the
- case of the header name is not significant.
+ This value can be a string or an iterable of strings for HTTP
+ header names. The header names are determined as follow:
+
+ - If a string does not contain a ``:`` (colon), it will be
+ considered to be the header name (e.g. ``If-Modified-Since``).
+ In this case, the header specified by the name must be present
+ in the request for this string to match. Case is not significant.
+
+ - If a string contains a colon, it will be considered a
+ name/value pair (e.g. ``User-Agent:Mozilla/.*`` or
+ ``Host:localhost``), where the value part is a regular
+ expression. The header specified by the name must be present
+ in the request *and* the regular expression specified as the
+ value must match the header value. Case is not significant for
+ the header name, but it is for the value.
+
+ All strings must be matched for this predicate to return ``True``.
+ If this predicate returns ``False``, view matching continues.
path_info
diff --git a/src/pyramid/predicates.py b/src/pyramid/predicates.py
index 8b443e79b..576bbbce6 100644
--- a/src/pyramid/predicates.py
+++ b/src/pyramid/predicates.py
@@ -98,33 +98,43 @@ class RequestParamPredicate:
class HeaderPredicate:
def __init__(self, val, config):
- name = val
- v = None
- if ':' in name:
- name, val_str = name.split(':', 1)
- try:
- v = re.compile(val_str)
- except re.error as why:
- raise ConfigurationError(why.args[0])
- if v is None:
- self._text = 'header %s' % (name,)
- else:
- self._text = 'header %s=%s' % (name, val_str)
- self.name = name
- self.val = v
+ values = []
+
+ val = as_sorted_tuple(val)
+ for name in val:
+ v, val_str = None, None
+ if ':' in name:
+ name, val_str = name.split(':', 1)
+ try:
+ v = re.compile(val_str)
+ except re.error as why:
+ raise ConfigurationError(why.args[0])
+
+ values.append((name, v, val_str))
+
+ self.val = values
def text(self):
- return self._text
+ return 'header %s' % ', '.join(
+ '%s=%s' % (name, val_str) if val_str else name
+ for name, _, val_str in self.val
+ )
phash = text
def __call__(self, context, request):
- if self.val is None:
- return self.name in request.headers
- val = request.headers.get(self.name)
- if val is None:
- return False
- return self.val.match(val) is not None
+ for name, val, _ in self.val:
+ if val is None:
+ if name not in request.headers:
+ return False
+ else:
+ value = request.headers.get(name)
+ if value is None:
+ return False
+ if val.match(value) is None:
+ return False
+
+ return True
class AcceptPredicate: