from __future__ import absolute_import, division, print_function, with_statement
-import calendar
-import email.utils
import time
import weakref
if headers is None:
headers = httputil.HTTPHeaders()
if if_modified_since:
- timestamp = calendar.timegm(if_modified_since.utctimetuple())
- headers["If-Modified-Since"] = email.utils.formatdate(
- timestamp, localtime=False, usegmt=True)
+ headers["If-Modified-Since"] = httputil.format_timestamp(
+ if_modified_since)
self.proxy_host = proxy_host
self.proxy_port = proxy_port
self.proxy_username = proxy_username
from __future__ import absolute_import, division, print_function, with_statement
+import datetime
+import numbers
import re
+import time
from tornado.escape import native_str, parse_qs_bytes, utf8
from tornado.log import gen_log
arguments.setdefault(name, []).append(value)
+def format_timestamp(ts):
+ """Formats a timestamp in the format used by HTTP.
+
+ The argument may be a numeric timestamp as returned by `time.time()`,
+ a time tuple as returned by `time.gmtime()`, or a `datetime.datetime`
+ object.
+
+ >>> format_timestamp(1359312200)
+ 'Sun, 27 Jan 2013 18:43:20 GMT'
+ """
+ if isinstance(ts, (tuple, time.struct_time)):
+ pass
+ elif isinstance(ts, datetime.datetime):
+ ts = ts.utctimetuple()
+ elif isinstance(ts, numbers.Real):
+ ts = time.gmtime(ts)
+ else:
+ raise TypeError("unknown timestamp type: %r" % ts)
+ return time.strftime("%a, %d %b %Y %H:%M:%S GMT", ts)
+
# _parseparam and _parse_header are copied and modified from python2.7's cgi.py
# The original 2.7 version of this code did not correctly support some
# combinations of semicolons and double quotes.
from __future__ import absolute_import, division, print_function, with_statement
-from tornado.httputil import url_concat, parse_multipart_form_data, HTTPHeaders
+from tornado.httputil import url_concat, parse_multipart_form_data, HTTPHeaders, format_timestamp
from tornado.escape import utf8
from tornado.log import gen_log
from tornado.testing import ExpectLog
from tornado.test.util import unittest
+
+import datetime
import logging
+import time
class TestUrlConcat(unittest.TestCase):
[("Asdf", "qwer zxcv"),
("Foo", "bar baz"),
("Foo", "even more lines")])
+
+
+class FormatTimestampTest(unittest.TestCase):
+ # Make sure that all the input types are supported.
+ TIMESTAMP = 1359312200.503611
+ EXPECTED = 'Sun, 27 Jan 2013 18:43:20 GMT'
+
+ def check(self, value):
+ self.assertEqual(format_timestamp(value), self.EXPECTED)
+
+ def test_unix_time_float(self):
+ self.check(self.TIMESTAMP)
+
+ def test_unix_time_int(self):
+ self.check(int(self.TIMESTAMP))
+
+ def test_struct_time(self):
+ self.check(time.gmtime(self.TIMESTAMP))
+
+ def test_time_tuple(self):
+ tup = tuple(time.gmtime(self.TIMESTAMP))
+ self.assertEqual(9, len(tup))
+ self.check(tup)
+
+ def test_datetime(self):
+ self.check(datetime.datetime.utcfromtimestamp(self.TIMESTAMP))
import base64
import binascii
-import calendar
import datetime
import email.utils
import functools
import gzip
import hashlib
import hmac
-import itertools
import mimetypes
import numbers
import os.path
self._headers = httputil.HTTPHeaders({
"Server": "TornadoServer/%s" % tornado.version,
"Content-Type": "text/html; charset=UTF-8",
- "Date": datetime.datetime.utcnow().strftime(
- "%a, %d %b %Y %H:%M:%S GMT"),
+ "Date": httputil.format_timestamp(time.gmtime()),
})
self.set_default_headers()
if not self.request.supports_http_1_1():
# return immediately since we know the converted value will be safe
return str(value)
elif isinstance(value, datetime.datetime):
- t = calendar.timegm(value.utctimetuple())
- return email.utils.formatdate(t, localtime=False, usegmt=True)
+ return httputil.format_timestamp(value)
else:
raise TypeError("Unsupported header value %r" % value)
# If \n is allowed into the header, it is possible to inject
expires = datetime.datetime.utcnow() + datetime.timedelta(
days=expires_days)
if expires:
- timestamp = calendar.timegm(expires.utctimetuple())
- morsel["expires"] = email.utils.formatdate(
- timestamp, localtime=False, usegmt=True)
+ morsel["expires"] = httputil.format_timestamp(expires)
if path:
morsel["path"] = path
for k, v in kwargs.items():