1b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikfrom datetime import ( 2b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik date, 3b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik datetime, 4b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ) 5b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 6b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikimport re 7b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 8b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikfrom webob.byterange import ( 9b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ContentRange, 10b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Range, 11b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ) 12b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 13b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikfrom webob.compat import ( 14b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik PY3, 15b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik text_type, 16b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ) 17b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 18b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikfrom webob.datetime_utils import ( 19b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik parse_date, 20b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik serialize_date, 21b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ) 22b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 23b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikfrom webob.util import ( 24b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik header_docstring, 25b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik warn_deprecation, 26b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ) 27b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 28b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 29b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikCHARSET_RE = re.compile(r';\s*charset=([^;]*)', re.I) 30b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikSCHEME_RE = re.compile(r'^[a-z]+:', re.I) 31b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 32b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 33b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik_not_given = object() 34b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 35b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef environ_getter(key, default=_not_given, rfc_section=None): 36b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if rfc_section: 37b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik doc = header_docstring(key, rfc_section) 38b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik else: 39b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik doc = "Gets and sets the ``%s`` key in the environment." % key 40b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if default is _not_given: 41b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def fget(req): 42b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return req.environ[key] 43b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def fset(req, val): 44b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik req.environ[key] = val 45b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik fdel = None 46b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik else: 47b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def fget(req): 48b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return req.environ.get(key, default) 49b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def fset(req, val): 50b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if val is None: 51b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if key in req.environ: 52b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik del req.environ[key] 53b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik else: 54b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik req.environ[key] = val 55b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def fdel(req): 56b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik del req.environ[key] 57b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return property(fget, fset, fdel, doc=doc) 58b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 59b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 60b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef environ_decoder(key, default=_not_given, rfc_section=None, 61b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik encattr=None): 62b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if rfc_section: 63b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik doc = header_docstring(key, rfc_section) 64b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik else: 65b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik doc = "Gets and sets the ``%s`` key in the environment." % key 66b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if default is _not_given: 67b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def fget(req): 68b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return req.encget(key, encattr=encattr) 69b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def fset(req, val): 70b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return req.encset(key, val, encattr=encattr) 71b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik fdel = None 72b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik else: 73b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def fget(req): 74b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return req.encget(key, default, encattr=encattr) 75b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def fset(req, val): 76b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if val is None: 77b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if key in req.environ: 78b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik del req.environ[key] 79b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik else: 80b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return req.encset(key, val, encattr=encattr) 81b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def fdel(req): 82b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik del req.environ[key] 83b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return property(fget, fset, fdel, doc=doc) 84b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 85b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef upath_property(key): 86b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if PY3: # pragma: no cover 87b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def fget(req): 88b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik encoding = req.url_encoding 89b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return req.environ.get(key, '').encode('latin-1').decode(encoding) 90b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def fset(req, val): 91b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik encoding = req.url_encoding 92b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik req.environ[key] = val.encode(encoding).decode('latin-1') 93b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik else: 94b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def fget(req): 95b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik encoding = req.url_encoding 96b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return req.environ.get(key, '').decode(encoding) 97b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def fset(req, val): 98b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik encoding = req.url_encoding 99b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if isinstance(val, text_type): 100b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik val = val.encode(encoding) 101b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik req.environ[key] = val 102b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return property(fget, fset, doc='upath_property(%r)' % key) 103b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 104b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 105b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef deprecated_property(attr, name, text, version): # pragma: no cover 106b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 107b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Wraps a descriptor, with a deprecation warning or error 108b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 109b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def warn(): 110b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik warn_deprecation('The attribute %s is deprecated: %s' 111b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik % (name, text), 112b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik version, 113b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 3 114b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ) 115b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def fget(self): 116b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik warn() 117b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return attr.__get__(self, type(self)) 118b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def fset(self, val): 119b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik warn() 120b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik attr.__set__(self, val) 121b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def fdel(self): 122b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik warn() 123b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik attr.__delete__(self) 124b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return property(fget, fset, fdel, 125b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik '<Deprecated attribute %s>' % name 126b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ) 127b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 128b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 129b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef header_getter(header, rfc_section): 130b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik doc = header_docstring(header, rfc_section) 131b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik key = header.lower() 132b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 133b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def fget(r): 134b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik for k, v in r._headerlist: 135b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if k.lower() == key: 136b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return v 137b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 138b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def fset(r, value): 139b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik fdel(r) 140b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if value is not None: 141b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if isinstance(value, text_type) and not PY3: 142b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik value = value.encode('latin-1') 143b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik r._headerlist.append((header, value)) 144b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 145b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def fdel(r): 146b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik items = r._headerlist 147b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik for i in range(len(items)-1, -1, -1): 148b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if items[i][0].lower() == key: 149b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik del items[i] 150b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 151b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return property(fget, fset, fdel, doc) 152b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 153b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 154b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 155b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 156b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef converter(prop, parse, serialize, convert_name=None): 157b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik assert isinstance(prop, property) 158b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik convert_name = convert_name or "``%s`` and ``%s``" % (parse.__name__, 159b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik serialize.__name__) 160b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik doc = prop.__doc__ or '' 161b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik doc += " Converts it using %s." % convert_name 162b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik hget, hset = prop.fget, prop.fset 163b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def fget(r): 164b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return parse(hget(r)) 165b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def fset(r, val): 166b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if val is not None: 167b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik val = serialize(val) 168b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik hset(r, val) 169b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return property(fget, fset, prop.fdel, doc) 170b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 171b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 172b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 173b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef list_header(header, rfc_section): 174b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik prop = header_getter(header, rfc_section) 175b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return converter(prop, parse_list, serialize_list, 'list') 176b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 177b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef parse_list(value): 178b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if not value: 179b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return None 180b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return tuple(filter(None, [v.strip() for v in value.split(',')])) 181b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 182b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef serialize_list(value): 183b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if isinstance(value, (text_type, bytes)): 184b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return str(value) 185b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik else: 186b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return ', '.join(map(str, value)) 187b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 188b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 189b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 190b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 191b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef converter_date(prop): 192b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return converter(prop, parse_date, serialize_date, 'HTTP date') 193b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 194b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef date_header(header, rfc_section): 195b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return converter_date(header_getter(header, rfc_section)) 196b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 197b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 198b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 199b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 200b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 201b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 202b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 203b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 204b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 205b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik######################## 206b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik## Converter functions 207b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik######################## 208b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 209b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 210b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik_rx_etag = re.compile(r'(?:^|\s)(W/)?"((?:\\"|.)*?)"') 211b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 212b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef parse_etag_response(value, strong=False): 213b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 214b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Parse a response ETag. 215b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik See: 216b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.19 217b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.11 218b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 219b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if not value: 220b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return None 221b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik m = _rx_etag.match(value) 222b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if not m: 223b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik # this etag is invalid, but we'll just return it anyway 224b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return value 225b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik elif strong and m.group(1): 226b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik # this is a weak etag and we want only strong ones 227b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return None 228b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik else: 229b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return m.group(2).replace('\\"', '"') 230b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 231b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef serialize_etag_response(value): #return '"%s"' % value.replace('"', '\\"') 232b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik strong = True 233b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if isinstance(value, tuple): 234b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik value, strong = value 235b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik elif _rx_etag.match(value): 236b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik # this is a valid etag already 237b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return value 238b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik # let's quote the value 239b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik r = '"%s"' % value.replace('"', '\\"') 240b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if not strong: 241b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik r = 'W/' + r 242b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return r 243b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 244b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef serialize_if_range(value): 245b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if isinstance(value, (datetime, date)): 246b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return serialize_date(value) 247b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik value = str(value) 248b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return value or None 249b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 250b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef parse_range(value): 251b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if not value: 252b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return None 253b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik # Might return None too: 254b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return Range.parse(value) 255b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 256b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef serialize_range(value): 257b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if not value: 258b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return None 259b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik elif isinstance(value, (list, tuple)): 260b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return str(Range(*value)) 261b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik else: 262b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik assert isinstance(value, str) 263b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return value 264b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 265b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef parse_int(value): 266b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if value is None or value == '': 267b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return None 268b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return int(value) 269b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 270b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef parse_int_safe(value): 271b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if value is None or value == '': 272b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return None 273b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik try: 274b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return int(value) 275b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik except ValueError: 276b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return None 277b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 278b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikserialize_int = str 279b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 280b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef parse_content_range(value): 281b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if not value or not value.strip(): 282b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return None 283b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik # May still return None 284b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return ContentRange.parse(value) 285b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 286b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef serialize_content_range(value): 287b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if isinstance(value, (tuple, list)): 288b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if len(value) not in (2, 3): 289b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik raise ValueError( 290b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik "When setting content_range to a list/tuple, it must " 291b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik "be length 2 or 3 (not %r)" % value) 292b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if len(value) == 2: 293b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik begin, end = value 294b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik length = None 295b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik else: 296b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik begin, end, length = value 297b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik value = ContentRange(begin, end, length) 298b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik value = str(value).strip() 299b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if not value: 300b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return None 301b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return value 302b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 303b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 304b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 305b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 306b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik_rx_auth_param = re.compile(r'([a-z]+)[ \t]*=[ \t]*(".*?"|[^,]*?)[ \t]*(?:\Z|, *)') 307b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 308b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef parse_auth_params(params): 309b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik r = {} 310b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik for k, v in _rx_auth_param.findall(params): 311b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik r[k] = v.strip('"') 312b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return r 313b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 314b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik# see http://lists.w3.org/Archives/Public/ietf-http-wg/2009OctDec/0297.html 315b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikknown_auth_schemes = ['Basic', 'Digest', 'WSSE', 'HMACDigest', 'GoogleLogin', 316b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'Cookie', 'OpenID'] 317b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikknown_auth_schemes = dict.fromkeys(known_auth_schemes, None) 318b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 319b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef parse_auth(val): 320b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if val is not None: 321b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik authtype, params = val.split(' ', 1) 322b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if authtype in known_auth_schemes: 323b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if authtype == 'Basic' and '"' not in params: 324b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik # this is the "Authentication: Basic XXXXX==" case 325b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik pass 326b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik else: 327b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik params = parse_auth_params(params) 328b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return authtype, params 329b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return val 330b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 331b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef serialize_auth(val): 332b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if isinstance(val, (tuple, list)): 333b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik authtype, params = val 334b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if isinstance(params, dict): 335b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik params = ', '.join(map('%s="%s"'.__mod__, params.items())) 336b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik assert isinstance(params, str) 337b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return '%s %s' % (authtype, params) 338b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return val 339