You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@impala.apache.org by as...@apache.org on 2023/07/19 00:23:42 UTC

[impala] branch master updated: IMPALA-12294 Fix Cookie handling for Impala Shell with python 3

This is an automated email from the ASF dual-hosted git repository.

asherman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git


The following commit(s) were added to refs/heads/master by this push:
     new 749d664c6 IMPALA-12294 Fix Cookie handling for Impala Shell with python 3
749d664c6 is described below

commit 749d664c60e2ce2e5f7eada86e5635fdea536c18
Author: Andrew Sherman <as...@cloudera.com>
AuthorDate: Mon Jul 17 16:12:24 2023 -0700

    IMPALA-12294 Fix Cookie handling for Impala Shell with python 3
    
    Impala Shell gets cookies from an HTTMessage object formed from a
    response to an HTTP message. The format of cookies in the message
    differs across the python versions. In Python 2 the HTTPMessage is a
    mimetools.Message object, and the Set-Cookie values all appear in a
    single header, separated by newlines. In Python 3 the HTTPMessage is an
    email.message.Message, and the Set-Cookie values appear as duplicate
    headers.
    
    Add platform dependent code to get_all_matching_cookies() that loads
    cookies from all the Set-Cookie headers.
    
    TESTING:
        Changed test_get_all_matching_cookies() to build the HTTPMessage
        using a new utility method that creates Set-Cookie headers in
        the appropriate format for the platform.
    
        Validated that the KNOX_BACKEND-IMPALA cookies is correctly set in
        Impala Shell on a Red Hat 9 system using Python 3 (which is how
        the problem was first observed).
    
    Change-Id: I057b5c2b9d78e36f32865537d091c4ac0e80d37f
    Reviewed-on: http://gerrit.cloudera.org:8080/20216
    Reviewed-by: Impala Public Jenkins <im...@cloudera.com>
    Tested-by: Impala Public Jenkins <im...@cloudera.com>
---
 shell/cookie_util.py            | 10 ++++--
 tests/shell/test_cookie_util.py | 79 +++++++++++++++++++++++++++++++----------
 2 files changed, 69 insertions(+), 20 deletions(-)

diff --git a/shell/cookie_util.py b/shell/cookie_util.py
index e243a2526..3f3220226 100644
--- a/shell/cookie_util.py
+++ b/shell/cookie_util.py
@@ -17,9 +17,10 @@
 # under the License.
 #
 
-import six
 import datetime
 import os.path
+import sys
+
 from six.moves import http_cookies
 
 
@@ -56,7 +57,12 @@ def get_all_matching_cookies(cookie_names, path, resp_headers):
 
   cookies = http_cookies.SimpleCookie()
   try:
-    cookies.load(resp_headers['Set-Cookie'])
+    if sys.version_info.major == 2:
+      cookies.load(resp_headers['Set-Cookie'])
+    else:
+      cookie_headers = resp_headers.get_all('Set-Cookie')
+      for header in cookie_headers:
+        cookies.load(header)
   except Exception:
     return None
 
diff --git a/tests/shell/test_cookie_util.py b/tests/shell/test_cookie_util.py
index 5441ee334..cf1c0bf01 100644
--- a/tests/shell/test_cookie_util.py
+++ b/tests/shell/test_cookie_util.py
@@ -19,9 +19,13 @@
 # under the License.
 
 from __future__ import absolute_import, division, print_function
+
+import sys
 import unittest
 
 from datetime import datetime, timedelta
+from http.client import HTTPMessage
+
 from shell.cookie_util import (cookie_matches_path, get_cookie_expiry,
                                get_all_matching_cookies)
 
@@ -85,9 +89,11 @@ class TestCookieUtil(unittest.TestCase):
         cookies = get_all_matching_cookies(['a', 'b'], '/path', {})
         assert not cookies
 
-        headers = {'Set-Cookie': '''c_cookie=c_value
-        b_cookie=b_value
-        a_cookie=a_value'''}
+        headers = make_cookie_headers([
+            ('c_cookie', 'c_value'),
+            ('b_cookie', 'b_value'),
+            ('a_cookie', 'a_value')
+        ])
         cookies = get_all_matching_cookies(['a_cookie', 'b_cookie'], '/path', headers)
         assert len(cookies) == 2
         assert cookies[0].key == 'a_cookie' and cookies[0].value == 'a_value'
@@ -97,17 +103,21 @@ class TestCookieUtil(unittest.TestCase):
         assert cookies[0].key == 'b_cookie' and cookies[0].value == 'b_value'
         assert cookies[1].key == 'a_cookie' and cookies[1].value == 'a_value'
 
-        headers = {'Set-Cookie': '''c_cookie=c_value;Path=/
-        b_cookie=b_value;Path=/path
-        a_cookie=a_value;Path=/'''}
+        headers = make_cookie_headers([
+            ('c_cookie', 'c_value;Path=/'),
+            ('b_cookie', 'b_value;Path=/path'),
+            ('a_cookie', 'a_value;Path=/')
+        ])
         cookies = get_all_matching_cookies(['a_cookie', 'b_cookie'], '/path', headers)
         assert len(cookies) == 2
         assert cookies[0].key == 'a_cookie' and cookies[0].value == 'a_value'
         assert cookies[1].key == 'b_cookie' and cookies[1].value == 'b_value'
 
-        headers = {'Set-Cookie': '''c_cookie=c_value;Path=/
-        b_cookie=b_value;Path=/path
-        a_cookie=a_value;Path=/path/path2'''}
+        headers = make_cookie_headers([
+            ('c_cookie', 'c_value;Path=/'),
+            ('b_cookie', 'b_value;Path=/path'),
+            ('a_cookie', 'a_value;Path=/path/path2')
+        ])
         cookies = get_all_matching_cookies(['a_cookie', 'b_cookie'], '/path', headers)
         assert len(cookies) == 1
         assert cookies[0].key == 'b_cookie' and cookies[0].value == 'b_value'
@@ -115,25 +125,58 @@ class TestCookieUtil(unittest.TestCase):
         assert len(cookies) == 1
         assert cookies[0].key == 'b_cookie' and cookies[0].value == 'b_value'
 
-        headers = {'Set-Cookie': '''c_cookie=c_value;Path=/
-        b_cookie=b_value;Path=/path
-        a_cookie=a_value;Path=/path'''}
+        headers = make_cookie_headers([
+            ('c_cookie', 'c_value;Path=/'),
+            ('b_cookie', 'b_value;Path=/path'),
+            ('a_cookie', 'a_value;Path=/path')
+        ])
         cookies = get_all_matching_cookies(['a_cookie', 'b_cookie'], '/path/path1',
             headers)
         assert len(cookies) == 2
         assert cookies[0].key == 'a_cookie' and cookies[0].value == 'a_value'
         assert cookies[1].key == 'b_cookie' and cookies[1].value == 'b_value'
 
-        headers = {'Set-Cookie': '''c_cookie=c_value;Path=/
-        b_cookie=b_value;Path=/path1
-        a_cookie=a_value;Path=/path2'''}
+        headers = make_cookie_headers([
+            ('c_cookie', 'c_value;Path=/'),
+            ('b_cookie', 'b_value;Path=/path1'),
+            ('a_cookie', 'a_value;Path=/path2')
+        ])
         cookies = get_all_matching_cookies(['a_cookie', 'b_cookie'], '/path', headers)
         assert not cookies
 
-        headers = {'Set-Cookie': '''c_cookie=c_value;Path=/
-        b_cookie=b_value;Path=/path1
-        a_cookie=a_value;Path=/path2'''}
+        headers = make_cookie_headers([
+            ('c_cookie', 'c_value;Path=/'),
+            ('b_cookie', 'b_value;Path=/path1'),
+            ('a_cookie', 'a_value;Path=/path2')
+        ])
         cookies = get_all_matching_cookies(['a_cookie', 'b_cookie', 'c_cookie'], '/path',
             headers)
         assert len(cookies) == 1
         assert cookies[0].key == 'c_cookie' and cookies[0].value == 'c_value'
+
+
+def make_cookie_headers(cookie_vals):
+    """Make an HTTPMessage containing Set-Cookie headers for Python 2 or Python 3"""
+    if sys.version_info.major == 2:
+        # In Python 2 the HTTPMessage is a mimetools.Message object, and the
+        # Set-Cookie values all appear in a single header, separated by newlines.
+        cookies = ""
+        count = 0
+        for pair in cookie_vals:
+            name = pair[0]
+            value = pair[1]
+            cookies += name + '=' + value
+            if count + 1 < len(cookie_vals):
+                # Separate the cookies, unless it is the last cookie.
+                cookies += '\n '
+            count += 1
+        return {'Set-Cookie': cookies}
+    else:
+        # In Python 3 the HTTPMessage is an email.message.Message, and the
+        # Set-Cookie values appear as duplicate headers.
+        headers = HTTPMessage()
+        for pair in cookie_vals:
+            name = pair[0]
+            value = pair[1]
+            headers.add_header('Set-Cookie', name + "=" + value)
+        return headers