diff options
Diffstat (limited to 'netlib/http')
| -rw-r--r-- | netlib/http/cookies.py | 34 | ||||
| -rw-r--r-- | netlib/http/response.py | 34 | 
2 files changed, 68 insertions, 0 deletions
diff --git a/netlib/http/cookies.py b/netlib/http/cookies.py index 18544b5e..caa84ff7 100644 --- a/netlib/http/cookies.py +++ b/netlib/http/cookies.py @@ -1,4 +1,6 @@ +from six.moves import http_cookies as Cookie  import re +from email.utils import parsedate_tz, formatdate, mktime_tz  from .. import odict @@ -191,3 +193,35 @@ def format_cookie_header(od):          Formats a Cookie header value.      """      return _format_pairs(od.lst) + + +def refresh_set_cookie_header(c, delta): +    """ +    Args: +        c: A Set-Cookie string +        delta: Time delta in seconds +    Returns: +        A refreshed Set-Cookie string +    """ +    try: +        c = Cookie.SimpleCookie(str(c)) +    except Cookie.CookieError: +        raise ValueError("Invalid Cookie") +    for i in c.values(): +        if "expires" in i: +            d = parsedate_tz(i["expires"]) +            if d: +                d = mktime_tz(d) + delta +                i["expires"] = formatdate(d) +            else: +                # This can happen when the expires tag is invalid. +                # reddit.com sends a an expires tag like this: "Thu, 31 Dec +                # 2037 23:59:59 GMT", which is valid RFC 1123, but not +                # strictly correct according to the cookie spec. Browsers +                # appear to parse this tolerantly - maybe we should too. +                # For now, we just ignore this. +                del i["expires"] +    ret = c.output(header="").strip() +    if not ret: +        raise ValueError("Invalid Cookie") +    return ret diff --git a/netlib/http/response.py b/netlib/http/response.py index 8af3c041..4e2e6442 100644 --- a/netlib/http/response.py +++ b/netlib/http/response.py @@ -1,6 +1,8 @@  from __future__ import absolute_import, print_function, division  import warnings +from email.utils import parsedate_tz, formatdate, mktime_tz +import time  from . import cookies  from .headers import Headers @@ -94,6 +96,38 @@ class Response(Message):              values.append(header)          self.headers.set_all("set-cookie", values) +    def refresh(self, now=None): +        """ +        This fairly complex and heuristic function refreshes a server +        response for replay. + +            - It adjusts date, expires and last-modified headers. +            - It adjusts cookie expiration. +        """ +        if not now: +            now = time.time() +        delta = now - self.timestamp_start +        refresh_headers = [ +            "date", +            "expires", +            "last-modified", +        ] +        for i in refresh_headers: +            if i in self.headers: +                d = parsedate_tz(self.headers[i]) +                if d: +                    new = mktime_tz(d) + delta +                    self.headers[i] = formatdate(new) +        c = [] +        for set_cookie_header in self.headers.get_all("set-cookie"): +            try: +                refreshed = cookies.refresh_set_cookie_header(set_cookie_header, delta) +            except ValueError: +                refreshed = set_cookie_header +            c.append(refreshed) +        if c: +            self.headers.set_all("set-cookie", c) +      # Legacy      def get_cookies(self):  # pragma: no cover  | 
