From: Cory Benfield Date: Tue, 30 Apr 2013 19:45:37 +0000 (+0100) Subject: Header keys should be native strings. X-Git-Tag: v2.0~5^2~16^2~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f5775594ccc0e2947b965c1fcf40747301a93974;p=services%2Fpython-requests.git Header keys should be native strings. This commit follows a discussion on IRC. For more information, see the Pull Request associated with it. --- diff --git a/requests/models.py b/requests/models.py index 2439153..62cd0f5 100644 --- a/requests/models.py +++ b/requests/models.py @@ -23,7 +23,7 @@ from .exceptions import HTTPError, RequestException, MissingSchema, InvalidURL from .utils import ( guess_filename, get_auth_from_url, requote_uri, stream_decode_response_unicode, to_key_val_list, parse_header_links, - iter_slices, guess_json_utf, super_len) + iter_slices, guess_json_utf, super_len, to_native_string) from .compat import ( cookielib, urlunparse, urlsplit, urlencode, str, bytes, StringIO, is_py2, chardet, json, builtin_str, basestring) @@ -346,7 +346,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): """Prepares the given HTTP headers.""" if headers: - headers = dict((name.encode('ascii'), value) for name, value in headers.items()) + headers = dict((to_native_string(name), value) for name, value in headers.items()) self.headers = CaseInsensitiveDict(headers) else: self.headers = CaseInsensitiveDict() diff --git a/requests/utils.py b/requests/utils.py index 37aa19e..e592c8b 100644 --- a/requests/utils.py +++ b/requests/utils.py @@ -21,8 +21,8 @@ from netrc import netrc, NetrcParseError from . import __version__ from . import certs from .compat import parse_http_list as _parse_list_header -from .compat import quote, urlparse, bytes, str, OrderedDict, urlunparse -from .compat import getproxies, proxy_bypass +from .compat import (quote, urlparse, bytes, str, OrderedDict, urlunparse, + is_py2, is_py3, builtin_str, getproxies, proxy_bypass) from .cookies import RequestsCookieJar, cookiejar_from_dict from .structures import CaseInsensitiveDict @@ -393,18 +393,18 @@ def get_environ_proxies(url): # we're getting isn't in the no_proxy list. no_proxy = get_proxy('no_proxy') netloc = urlparse(url).netloc - + if no_proxy: # We need to check whether we match here. We need to see if we match # the end of the netloc, both with and without the port. no_proxy = no_proxy.split(',') - + for host in no_proxy: if netloc.endswith(host) or netloc.split(':')[0].endswith(host): # The URL does match something in no_proxy, so we don't want # to apply the proxies on this URL. return {} - + # If the system proxy settings indicate that this URL should be bypassed, # don't proxy. if proxy_bypass(netloc): @@ -414,7 +414,7 @@ def get_environ_proxies(url): # anywhere that no_proxy applies to, and the system settings don't require # bypassing the proxy for the current URL. return getproxies() - + def default_user_agent(): """Return a string representing the default user agent.""" @@ -546,3 +546,22 @@ def get_auth_from_url(url): return (parsed.username, parsed.password) else: return ('', '') + + +def to_native_string(string, encoding='ascii'): + """ + Given a string object, regardless of type, returns a representation of that + string in the native string type, encoding and decoding where necessary. + This assumes ASCII unless told otherwise. + """ + out = None + + if isinstance(string, builtin_str): + out = string + else: + if is_py2: + out = string.encode(encoding) + else: + out = string.decode(encoding) + + return out diff --git a/test_requests.py b/test_requests.py index 27d5e67..ca05f4a 100755 --- a/test_requests.py +++ b/test_requests.py @@ -199,13 +199,13 @@ class RequestsTestCase(unittest.TestCase): assert r.json()['cookies']['foo'] == 'bar' # Make sure the session cj is still the custom one assert s.cookies is cj - + def test_requests_in_history_are_not_overridden(self): resp = requests.get(httpbin('redirect/3')) urls = [r.url for r in resp.history] req_urls = [r.request.url for r in resp.history] self.assertEquals(urls, req_urls) - + def test_user_agent_transfers(self): heads = { @@ -263,7 +263,7 @@ class RequestsTestCase(unittest.TestCase): self.assertEqual(r.status_code, 401) s = requests.session() - + # Should use netrc and work. r = s.get(url) self.assertEqual(r.status_code, 200) @@ -640,6 +640,16 @@ class RequestsTestCase(unittest.TestCase): r = requests.Request('GET', url).prepare() self.assertEqual(r.url, url) + def test_header_keys_are_native(self): + headers = {u'unicode': 'blah', 'byte'.encode('ascii'): 'blah'} + r = requests.Request('GET', httpbin('get'), headers=headers) + p = r.prepare() + + # This is testing that they are builtin strings. A bit weird, but there + # we go. + self.assertTrue('unicode' in p.headers.keys()) + self.assertTrue('byte' in p.headers.keys()) + class TestCaseInsensitiveDict(unittest.TestCase):