# our __setitem__
dict.__init__(self)
self._as_list = {}
+ self._last_key = None
self.update(*args, **kwargs)
# new public methods
def add(self, name, value):
"""Adds a new value for the given key."""
norm_name = HTTPHeaders._normalize_name(name)
+ self._last_key = norm_name
if norm_name in self:
# bypass our override of __setitem__ since it modifies _as_list
dict.__setitem__(self, norm_name, self[norm_name] + ',' + value)
>>> h.get('content-type')
'text/html'
"""
- name, value = line.split(":", 1)
- self.add(name, value.strip())
+ if line[0].isspace():
+ # continuation of a multi-line header
+ new_part = ' ' + line.lstrip()
+ self._as_list[self._last_key][-1] += new_part
+ dict.__setitem__(self, self._last_key,
+ self[self._last_key] + new_part)
+ else:
+ name, value = line.split(":", 1)
+ self.add(name, value.strip())
@classmethod
def parse(cls, headers):
#!/usr/bin/env python
-from tornado.httputil import url_concat, parse_multipart_form_data
+from tornado.httputil import url_concat, parse_multipart_form_data, HTTPHeaders
from tornado.escape import utf8
from tornado.testing import LogTrapTestCase
from tornado.util import b
file = files["files"][0]
self.assertEqual(file["filename"], filename)
self.assertEqual(file["body"], b("Foo"))
+
+class HTTPHeadersTest(unittest.TestCase):
+ def test_multi_line(self):
+ # Lines beginning with whitespace are appended to the previous line
+ # with any leading whitespace replaced by a single space.
+ # Note that while multi-line headers are a part of the HTTP spec,
+ # their use is strongly discouraged.
+ data = """\
+Foo: bar
+ baz
+Asdf: qwer
+\tzxcv
+Foo: even
+ more
+ lines
+""".replace("\n", "\r\n")
+ headers = HTTPHeaders.parse(data)
+ self.assertEqual(headers["asdf"], "qwer zxcv")
+ self.assertEqual(headers.get_list("asdf"), ["qwer zxcv"])
+ self.assertEqual(headers["Foo"], "bar baz,even more lines")
+ self.assertEqual(headers.get_list("foo"), ["bar baz", "even more lines"])
+ self.assertEqual(sorted(list(headers.get_all())),
+ [("Asdf", "qwer zxcv"),
+ ("Foo", "bar baz"),
+ ("Foo", "even more lines")])