feat(Request): date property should return a datetime instance

BREAKING CHANGE: req.date now returns a datetime instance rather than a
string, and will raise HTTPBadRequest if the value of the Date header
does not confrom to RFC 1123.
This commit is contained in:
kgriffs
2013-04-04 01:44:18 -04:00
parent 7d121fd79d
commit 0bf71a62cb
4 changed files with 49 additions and 3 deletions

View File

@@ -187,8 +187,26 @@ class Request(object):
@property
def date(self):
"""Value of the Date header, or None if missing."""
return self._get_header_by_wsgi_name('DATE')
"""Value of the Date header, converted to a datetime instance.
Returns:
An instance of datetime.datetime representing the value of
the Date header, or None if the Date header is not present
in the request.
Raises:
HTTPBadRequest: The date value could not be parsed, likely
because it does not confrom to RFC 1123.
"""
http_date = self._get_header_by_wsgi_name('DATE')
try:
return util.http_date_to_dt(http_date)
except ValueError:
msg = ('The value of the Date header could not be parsed. It '
'must be formatted according to RFC 1123.')
raise InvalidHeaderValueError(msg)
@property
def expect(self):

View File

@@ -16,6 +16,8 @@ limitations under the License.
"""
import datetime
def dt_to_http(dt):
"""Converts a datetime instance to an HTTP date string.
@@ -33,6 +35,11 @@ def dt_to_http(dt):
return dt.strftime('%a, %d %b %Y %H:%M:%S GMT')
def http_date_to_dt(http_date):
return datetime.datetime.strptime(
http_date, '%a, %d %b %Y %H:%M:%S %Z')
def to_query_str(params):
"""Converts a dict of params to an actual query string.

View File

@@ -1,3 +1,5 @@
import datetime
import falcon
from falcon.request import Request
import falcon.testing as testing
@@ -199,6 +201,17 @@ class TestReqVars(testing.TestBase):
req = Request(testing.create_environ(headers=headers))
self.assertRaises(falcon.HTTPBadRequest, lambda: req.content_length)
def test_date(self):
date = datetime.datetime(2013, 4, 4, 5, 19, 18)
headers = {'date': 'Thu, 04 Apr 2013 05:19:18 GMT'}
req = Request(testing.create_environ(headers=headers))
self.assertEquals(req.date, date)
def test_date_invalid(self):
headers = {'date': 'Thu, 04 Apr 2013'}
req = Request(testing.create_environ(headers=headers))
self.assertRaises(falcon.HTTPBadRequest, lambda: req.date)
def test_attribute_headers(self):
date = testing.httpnow()
hash = 'fa0d1a60ef6616bb28038515c8ea4cb2'
@@ -212,7 +225,6 @@ class TestReqVars(testing.TestBase):
self._test_attribute_header('Content-Type', 'text/plain',
'content_type')
self._test_attribute_header('Expect', '100-continue', 'expect')
self._test_attribute_header('Date', date, 'date')
self._test_attribute_header('If-Match', hash, 'if_match')
self._test_attribute_header('If-Modified-Since', date,

View File

@@ -15,6 +15,15 @@ class TestFalconUtils(testtools.TestCase):
falcon.dt_to_http(datetime(2013, 4, 4, 10, 28, 54)),
'Thu, 04 Apr 2013 10:28:54 GMT')
def test_http_date_to_dt(self):
self.assertEquals(
falcon.http_date_to_dt('Thu, 04 Apr 2013 00:00:00 GMT'),
datetime(2013, 4, 4))
self.assertEquals(
falcon.http_date_to_dt('Thu, 04 Apr 2013 10:28:54 GMT'),
datetime(2013, 4, 4, 10, 28, 54))
def test_pack_query_params_none(self):
self.assertEquals(
falcon.to_query_str({}),