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:
@@ -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):
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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({}),
|
||||
|
||||
Reference in New Issue
Block a user