From cc3ca857a0d5d92309c655a37a60160abc51679b Mon Sep 17 00:00:00 2001 From: Piotr Tylenda Date: Mon, 8 May 2017 21:33:04 +0200 Subject: [PATCH] Fix non-ascii characters support in curl_httpclient username and password --- tornado/curl_httpclient.py | 2 +- tornado/test/curl_httpclient_test.py | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/tornado/curl_httpclient.py b/tornado/curl_httpclient.py index 54fc5b36d..c4ddbbbb2 100644 --- a/tornado/curl_httpclient.py +++ b/tornado/curl_httpclient.py @@ -450,7 +450,7 @@ class CurlAsyncHTTPClient(AsyncHTTPClient): else: raise ValueError("Unsupported auth_mode %s" % request.auth_mode) - curl.setopt(pycurl.USERPWD, native_str(userpwd)) + curl.setopt(pycurl.USERPWD, utf8(userpwd)) curl_log.debug("%s %s (username: %r)", request.method, request.url, request.auth_username) else: diff --git a/tornado/test/curl_httpclient_test.py b/tornado/test/curl_httpclient_test.py index b7a859522..4230d4cd6 100644 --- a/tornado/test/curl_httpclient_test.py +++ b/tornado/test/curl_httpclient_test.py @@ -32,13 +32,15 @@ class CurlHTTPClientCommonTestCase(httpclient_test.HTTPClientCommonTestCase): class DigestAuthHandler(RequestHandler): + def initialize(self, username, password): + self.username = username + self.password = password + def get(self): realm = 'test' opaque = 'asdf' # Real implementations would use a random nonce. nonce = "1234" - username = 'foo' - password = 'bar' auth_header = self.request.headers.get('Authorization', None) if auth_header is not None: @@ -53,9 +55,9 @@ class DigestAuthHandler(RequestHandler): assert param_dict['realm'] == realm assert param_dict['opaque'] == opaque assert param_dict['nonce'] == nonce - assert param_dict['username'] == username + assert param_dict['username'] == self.username assert param_dict['uri'] == self.request.path - h1 = md5(utf8('%s:%s:%s' % (username, realm, password))).hexdigest() + h1 = md5(utf8('%s:%s:%s' % (self.username, realm, self.password))).hexdigest() h2 = md5(utf8('%s:%s' % (self.request.method, self.request.path))).hexdigest() digest = md5(utf8('%s:%s:%s' % (h1, nonce, h2))).hexdigest() @@ -88,7 +90,8 @@ class CurlHTTPClientTestCase(AsyncHTTPTestCase): def get_app(self): return Application([ - ('/digest', DigestAuthHandler), + ('/digest', DigestAuthHandler, {'username': 'foo', 'password': 'bar'}), + ('/digest_non_ascii', DigestAuthHandler, {'username': 'foo', 'password': 'barユ£'}), ('/custom_reason', CustomReasonHandler), ('/custom_fail_reason', CustomFailReasonHandler), ]) @@ -143,3 +146,8 @@ class CurlHTTPClientTestCase(AsyncHTTPTestCase): # during the setup phase doesn't lead the request to # be dropped on the floor. response = self.fetch(u'/ユニコード', raise_error=True) + + def test_digest_auth_non_ascii(self): + response = self.fetch('/digest_non_ascii', auth_mode='digest', + auth_username='foo', auth_password='barユ£') + self.assertEqual(response.body, b'ok') -- 2.47.2