diff -r 000000000000 -r 0d40e90630ef web/lib/django/utils/http.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/lib/django/utils/http.py Wed Jan 20 00:34:04 2010 +0100 @@ -0,0 +1,119 @@ +import re +import urllib +from email.Utils import formatdate + +from django.utils.encoding import smart_str, force_unicode +from django.utils.functional import allow_lazy + +ETAG_MATCH = re.compile(r'(?:W/)?"((?:\\.|[^"])*)"') + +def urlquote(url, safe='/'): + """ + A version of Python's urllib.quote() function that can operate on unicode + strings. The url is first UTF-8 encoded before quoting. The returned string + can safely be used as part of an argument to a subsequent iri_to_uri() call + without double-quoting occurring. + """ + return force_unicode(urllib.quote(smart_str(url), safe)) + +urlquote = allow_lazy(urlquote, unicode) + +def urlquote_plus(url, safe=''): + """ + A version of Python's urllib.quote_plus() function that can operate on + unicode strings. The url is first UTF-8 encoded before quoting. The + returned string can safely be used as part of an argument to a subsequent + iri_to_uri() call without double-quoting occurring. + """ + return force_unicode(urllib.quote_plus(smart_str(url), safe)) +urlquote_plus = allow_lazy(urlquote_plus, unicode) + +def urlencode(query, doseq=0): + """ + A version of Python's urllib.urlencode() function that can operate on + unicode strings. The parameters are first case to UTF-8 encoded strings and + then encoded as per normal. + """ + if hasattr(query, 'items'): + query = query.items() + return urllib.urlencode( + [(smart_str(k), + isinstance(v, (list,tuple)) and [smart_str(i) for i in v] or smart_str(v)) + for k, v in query], + doseq) + +def cookie_date(epoch_seconds=None): + """ + Formats the time to ensure compatibility with Netscape's cookie standard. + + Accepts a floating point number expressed in seconds since the epoch, in + UTC - such as that outputted by time.time(). If set to None, defaults to + the current time. + + Outputs a string in the format 'Wdy, DD-Mon-YYYY HH:MM:SS GMT'. + """ + rfcdate = formatdate(epoch_seconds) + return '%s-%s-%s GMT' % (rfcdate[:7], rfcdate[8:11], rfcdate[12:25]) + +def http_date(epoch_seconds=None): + """ + Formats the time to match the RFC1123 date format as specified by HTTP + RFC2616 section 3.3.1. + + Accepts a floating point number expressed in seconds since the epoch, in + UTC - such as that outputted by time.time(). If set to None, defaults to + the current time. + + Outputs a string in the format 'Wdy, DD Mon YYYY HH:MM:SS GMT'. + """ + rfcdate = formatdate(epoch_seconds) + return '%s GMT' % rfcdate[:25] + +# Base 36 functions: useful for generating compact URLs + +def base36_to_int(s): + """ + Convertd a base 36 string to an integer + """ + return int(s, 36) + +def int_to_base36(i): + """ + Converts an integer to a base36 string + """ + digits = "0123456789abcdefghijklmnopqrstuvwxyz" + factor = 0 + # Find starting factor + while True: + factor += 1 + if i < 36 ** factor: + factor -= 1 + break + base36 = [] + # Construct base36 representation + while factor >= 0: + j = 36 ** factor + base36.append(digits[i / j]) + i = i % j + factor -= 1 + return ''.join(base36) + +def parse_etags(etag_str): + """ + Parses a string with one or several etags passed in If-None-Match and + If-Match headers by the rules in RFC 2616. Returns a list of etags + without surrounding double quotes (") and unescaped from \. + """ + etags = ETAG_MATCH.findall(etag_str) + if not etags: + # etag_str has wrong format, treat it as an opaque string then + return [etag_str] + etags = [e.decode('string_escape') for e in etags] + return etags + +def quote_etag(etag): + """ + Wraps a string in double quotes escaping contents as necesary. + """ + return '"%s"' % etag.replace('\\', '\\\\').replace('"', '\\"') +