summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipapython/cookie.py42
-rw-r--r--tests/test_ipapython/test_cookie.py15
2 files changed, 20 insertions, 37 deletions
diff --git a/ipapython/cookie.py b/ipapython/cookie.py
index b45cb2b1..bf551b51 100644
--- a/ipapython/cookie.py
+++ b/ipapython/cookie.py
@@ -20,6 +20,7 @@
import re
import time
import datetime
+import email.utils
from urllib2 import urlparse
from calendar import timegm
from ipapython.ipa_log_manager import log_mgr
@@ -172,47 +173,26 @@ class Cookie(object):
if utcoffset is not None and utcoffset.total_seconds() != 0.0:
raise ValueError("timezone is not UTC")
- # At this point we've validated as much as possible the
- # timezone is UTC or GMT but we can't use the %Z timezone
- # format specifier because the timezone in the string must be
- # 'GMT', not something equivalent to GMT, so hardcode the GMT
- # timezone string into the format.
+ # Do not use strftime because it respects the locale, instead
+ # use the RFC 1123 formatting function which uses only English
- return datetime.datetime.strftime(dt, '%a, %d %b %Y %H:%M:%S GMT')
+ return email.utils.formatdate(cls.datetime_to_time(dt), usegmt=True)
@classmethod
def parse_datetime(cls, s):
'''
- Parse a RFC 822, RFC 1123 date string, return a datetime aware object in UTC.
- Accommodates some non-standard formats found in the wild.
+ Parse a RFC 822, RFC 1123 date string, return a datetime naive object in UTC.
'''
- formats = ['%a, %d %b %Y %H:%M:%S',
- '%a, %d-%b-%Y %H:%M:%S',
- '%a, %d-%b-%y %H:%M:%S',
- '%a, %d %b %y %H:%M:%S',
- ]
s = s.strip()
- # strptime does not read the time zone and generate a tzinfo
- # object to insert in the datetime object so there is little point
- # in specifying a %Z format, instead verify GMT is specified and
- # generate the datetime object as if it were UTC.
+ # Do not use strptime because it respects the locale, instead
+ # use the RFC 1123 parsing function which uses only English
- if not s.endswith(' GMT'):
- raise ValueError("http date string '%s' does not end with GMT time zone" % s)
- s = s[:-4]
-
- dt = None
- for format in formats:
- try:
- dt = datetime.datetime(*(time.strptime(s, format)[0:6]))
- break
- except Exception:
- continue
-
- if dt is None:
- raise ValueError("unable to parse expires datetime '%s'" % s)
+ try:
+ dt = datetime.datetime(*email.utils.parsedate(s)[0:6])
+ except Exception, e:
+ raise ValueError("unable to parse expires datetime '%s': %s" % (s, e))
return dt
diff --git a/tests/test_ipapython/test_cookie.py b/tests/test_ipapython/test_cookie.py
index f8c5daf4..b8a2d36d 100644
--- a/tests/test_ipapython/test_cookie.py
+++ b/tests/test_ipapython/test_cookie.py
@@ -20,6 +20,7 @@
import unittest
import time
import datetime
+import email.utils
import calendar
from ipapython.cookie import Cookie
@@ -129,15 +130,16 @@ class TestExpires(unittest.TestCase):
# Force microseconds to zero because cookie timestamps only have second resolution
self.now = datetime.datetime.utcnow().replace(microsecond=0)
self.now_timestamp = calendar.timegm(self.now.utctimetuple())
- self.now_string = datetime.datetime.strftime(self.now, '%a, %d %b %Y %H:%M:%S GMT')
+ self.now_string = email.utils.formatdate(self.now_timestamp, usegmt=True)
self.max_age = 3600 # 1 hour
self.age_expiration = self.now + datetime.timedelta(seconds=self.max_age)
- self.age_string = datetime.datetime.strftime(self.age_expiration, '%a, %d %b %Y %H:%M:%S GMT')
+ self.age_timestamp = calendar.timegm(self.age_expiration.utctimetuple())
+ self.age_string = email.utils.formatdate(self.age_timestamp, usegmt=True)
self.expires = self.now + datetime.timedelta(days=1) # 1 day
self.expires_timestamp = calendar.timegm(self.expires.utctimetuple())
- self.expires_string = datetime.datetime.strftime(self.expires, '%a, %d %b %Y %H:%M:%S GMT')
+ self.expires_string = email.utils.formatdate(self.expires_timestamp, usegmt=True)
def test_expires(self):
# 1 cookie with name/value and no Max-Age and no Expires
@@ -407,15 +409,16 @@ class TestNormalization(unittest.TestCase):
# Force microseconds to zero because cookie timestamps only have second resolution
self.now = datetime.datetime.utcnow().replace(microsecond=0)
self.now_timestamp = calendar.timegm(self.now.utctimetuple())
- self.now_string = datetime.datetime.strftime(self.now, '%a, %d %b %Y %H:%M:%S GMT')
+ self.now_string = email.utils.formatdate(self.now_timestamp, usegmt=True)
self.max_age = 3600 # 1 hour
self.age_expiration = self.now + datetime.timedelta(seconds=self.max_age)
- self.age_string = datetime.datetime.strftime(self.age_expiration, '%a, %d %b %Y %H:%M:%S GMT')
+ self.age_timestamp = calendar.timegm(self.age_expiration.utctimetuple())
+ self.age_string = email.utils.formatdate(self.age_timestamp, usegmt=True)
self.expires = self.now + datetime.timedelta(days=1) # 1 day
self.expires_timestamp = calendar.timegm(self.expires.utctimetuple())
- self.expires_string = datetime.datetime.strftime(self.expires, '%a, %d %b %Y %H:%M:%S GMT')
+ self.expires_string = email.utils.formatdate(self.expires_timestamp, usegmt=True)
def test_path_normalization(self):
self.assertEqual(Cookie.normalize_url_path(''), '/')