dict.__init__(self)
self._as_list = {}
self._last_key = None
- self.update(*args, **kwargs)
+ if (len(args) == 1 and len(kwargs) == 0 and
+ isinstance(args[0], HTTPHeaders)):
+ # Copy constructor
+ for k,v in args[0].get_all():
+ self.add(k,v)
+ else:
+ # Dict-style initialization
+ self.update(*args, **kwargs)
# new public methods
def fetch(self, request, callback, **kwargs):
if not isinstance(request, HTTPRequest):
request = HTTPRequest(url=request, **kwargs)
- if not isinstance(request.headers, HTTPHeaders):
- request.headers = HTTPHeaders(request.headers)
+ # We're going to modify this (to add Host, Accept-Encoding, etc),
+ # so make sure we don't modify the caller's object. This is also
+ # where normal dicts get converted to HTTPHeaders objects.
+ request.headers = HTTPHeaders(request.headers)
callback = stack_context.wrap(callback)
self.queue.append((request, callback))
self._process_queue()
import re
import socket
+from tornado.httputil import HTTPHeaders
from tornado.ioloop import IOLoop
from tornado.simple_httpclient import SimpleAsyncHTTPClient, _DEFAULT_CA_CERTS
from tornado.test.httpclient_test import HTTPClientCommonTestCase, ChunkHandler, CountdownHandler, HelloWorldHandler
self.assertTrue(response.effective_url.endswith("/countdown/2"))
self.assertTrue(response.headers["Location"].endswith("/countdown/1"))
+ def test_header_reuse(self):
+ # Apps may reuse a headers object if they are only passing in constant
+ # headers like user-agent. The header object should not be modified.
+ headers = HTTPHeaders({'User-Agent': 'Foo'})
+ self.fetch("/hello", headers=headers)
+ self.assertEqual(list(headers.get_all()), [('User-Agent', 'Foo')])
+
def test_303_redirect(self):
response = self.fetch("/303_post", method="POST", body="blah")
self.assertEqual(200, response.code)