From f1349cd05d31ba0a925d9931a7c437a9650c6488 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Tue, 28 Mar 2006 12:40:24 +0000 Subject: [PATCH] Bug #1459963: urllib2 now normalizes HTTP header names correctly with title(). --- Lib/test/test_urllib2.py | 12 ++++++------ Lib/urllib.py | 12 ++++++------ Lib/urllib2.py | 26 +++++++++++++------------- Misc/NEWS | 6 ++++++ 4 files changed, 31 insertions(+), 25 deletions(-) diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py index 57104440175..8d1363d6bc5 100644 --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -493,11 +493,11 @@ class HandlerTests(unittest.TestCase): r = MockResponse(200, "OK", {}, "") newreq = h.do_request_(req) if data is None: # GET - self.assert_("Content-length" not in req.unredirected_hdrs) - self.assert_("Content-type" not in req.unredirected_hdrs) + self.assert_("Content-Length" not in req.unredirected_hdrs) + self.assert_("Content-Type" not in req.unredirected_hdrs) else: # POST - self.assertEqual(req.unredirected_hdrs["Content-length"], "0") - self.assertEqual(req.unredirected_hdrs["Content-type"], + self.assertEqual(req.unredirected_hdrs["Content-Length"], "0") + self.assertEqual(req.unredirected_hdrs["Content-Type"], "application/x-www-form-urlencoded") # XXX the details of Host could be better tested self.assertEqual(req.unredirected_hdrs["Host"], "example.com") @@ -509,8 +509,8 @@ class HandlerTests(unittest.TestCase): req.add_unredirected_header("Host", "baz") req.add_unredirected_header("Spam", "foo") newreq = h.do_request_(req) - self.assertEqual(req.unredirected_hdrs["Content-length"], "foo") - self.assertEqual(req.unredirected_hdrs["Content-type"], "bar") + self.assertEqual(req.unredirected_hdrs["Content-Length"], "foo") + self.assertEqual(req.unredirected_hdrs["Content-Type"], "bar") self.assertEqual(req.unredirected_hdrs["Host"], "baz") self.assertEqual(req.unredirected_hdrs["Spam"], "foo") diff --git a/Lib/urllib.py b/Lib/urllib.py index d1c50f61920..d4573c60a34 100644 --- a/Lib/urllib.py +++ b/Lib/urllib.py @@ -118,7 +118,7 @@ class URLopener: self.proxies = proxies self.key_file = x509.get('key_file') self.cert_file = x509.get('cert_file') - self.addheaders = [('User-agent', self.version)] + self.addheaders = [('User-Agent', self.version)] self.__tempfiles = [] self.__unlink = os.unlink # See cleanup() self.tempcache = None @@ -314,8 +314,8 @@ class URLopener: h = httplib.HTTP(host) if data is not None: h.putrequest('POST', selector) - h.putheader('Content-type', 'application/x-www-form-urlencoded') - h.putheader('Content-length', '%d' % len(data)) + h.putheader('Content-Type', 'application/x-www-form-urlencoded') + h.putheader('Content-Length', '%d' % len(data)) else: h.putrequest('GET', selector) if proxy_auth: h.putheader('Proxy-Authorization', 'Basic %s' % proxy_auth) @@ -400,9 +400,9 @@ class URLopener: cert_file=self.cert_file) if data is not None: h.putrequest('POST', selector) - h.putheader('Content-type', + h.putheader('Content-Type', 'application/x-www-form-urlencoded') - h.putheader('Content-length', '%d' % len(data)) + h.putheader('Content-Length', '%d' % len(data)) else: h.putrequest('GET', selector) if proxy_auth: h.putheader('Proxy-Authorization: Basic %s' % proxy_auth) @@ -584,7 +584,7 @@ class URLopener: data = base64.decodestring(data) else: data = unquote(data) - msg.append('Content-length: %d' % len(data)) + msg.append('Content-Length: %d' % len(data)) msg.append('') msg.append(data) msg = '\n'.join(msg) diff --git a/Lib/urllib2.py b/Lib/urllib2.py index 0434a51ad21..bc6ee4b41ad 100644 --- a/Lib/urllib2.py +++ b/Lib/urllib2.py @@ -254,11 +254,11 @@ class Request: def add_header(self, key, val): # useful for something like authentication - self.headers[key.capitalize()] = val + self.headers[key.title()] = val def add_unredirected_header(self, key, val): # will not be added to a redirected request - self.unredirected_hdrs[key.capitalize()] = val + self.unredirected_hdrs[key.title()] = val def has_header(self, header_name): return (header_name in self.headers or @@ -277,7 +277,7 @@ class Request: class OpenerDirector: def __init__(self): client_version = "Python-urllib/%s" % __version__ - self.addheaders = [('User-agent', client_version)] + self.addheaders = [('User-Agent', client_version)] # manage the individual handlers self.handlers = [] self.handle_open = {} @@ -592,7 +592,7 @@ class ProxyHandler(BaseHandler): user, password = user_pass.split(':', 1) user_pass = base64.encodestring('%s:%s' % (unquote(user), unquote(password))).strip() - req.add_header('Proxy-authorization', 'Basic ' + user_pass) + req.add_header('Proxy-Authorization', 'Basic ' + user_pass) host = unquote(host) req.set_proxy(host, type) if orig_type == type: @@ -755,7 +755,7 @@ class HTTPBasicAuthHandler(AbstractBasicAuthHandler, BaseHandler): class ProxyBasicAuthHandler(AbstractBasicAuthHandler, BaseHandler): - auth_header = 'Proxy-authorization' + auth_header = 'Proxy-Authorization' def http_error_407(self, req, fp, code, msg, headers): host = req.get_host() @@ -955,20 +955,20 @@ class AbstractHTTPHandler(BaseHandler): if request.has_data(): # POST data = request.get_data() - if not request.has_header('Content-type'): + if not request.has_header('Content-Type'): request.add_unredirected_header( - 'Content-type', + 'Content-Type', 'application/x-www-form-urlencoded') - if not request.has_header('Content-length'): + if not request.has_header('Content-Length'): request.add_unredirected_header( - 'Content-length', '%d' % len(data)) + 'Content-Length', '%d' % len(data)) scheme, sel = splittype(request.get_selector()) sel_host, sel_path = splithost(sel) if not request.has_header('Host'): request.add_unredirected_header('Host', sel_host or host) for name, value in self.parent.addheaders: - name = name.capitalize() + name = name.title() if not request.has_header(name): request.add_unredirected_header(name, value) @@ -1145,7 +1145,7 @@ class FileHandler(BaseHandler): modified = email.Utils.formatdate(stats.st_mtime, usegmt=True) mtype = mimetypes.guess_type(file)[0] headers = mimetools.Message(StringIO( - 'Content-type: %s\nContent-length: %d\nLast-modified: %s\n' % + 'Content-Type: %s\nContent-Length: %d\nLast-Modified: %s\n' % (mtype or 'text/plain', size, modified))) if host: host, port = splitport(host) @@ -1198,9 +1198,9 @@ class FTPHandler(BaseHandler): headers = "" mtype = mimetypes.guess_type(req.get_full_url())[0] if mtype: - headers += "Content-type: %s\n" % mtype + headers += "Content-Type: %s\n" % mtype if retrlen is not None and retrlen >= 0: - headers += "Content-length: %d\n" % retrlen + headers += "Content-Length: %d\n" % retrlen sf = StringIO(headers) headers = mimetools.Message(sf) return addinfourl(fp, headers, req.get_full_url()) diff --git a/Misc/NEWS b/Misc/NEWS index 42b6e401d65..7dade8ef461 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -483,6 +483,12 @@ Extension Modules Library ------- +- Bug #1459963: urllib2 now normalizes HTTP header names correctly + with title(). + +- Bug #1459963: urllib2 now normalizes HTTP header names correctly + with title(). + - Queue.Queue objects now support .task_done() and .join() methods to make it easier to monitor when daemon threads have completed processing all enqueued tasks. Patch #1455676.