You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@paimon.apache.org by lz...@apache.org on 2026/04/01 03:10:42 UTC

(paimon) branch master updated: [python] Fix REST signature mismatch by encoding query param values (#7568)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 1e989c81b1 [python] Fix REST signature mismatch by encoding query param values (#7568)
1e989c81b1 is described below

commit 1e989c81b1fc4636de613a40f365b99114061c53
Author: XiaoHongbo <13...@qq.com>
AuthorDate: Wed Apr 1 11:10:33 2026 +0800

    [python] Fix REST signature mismatch by encoding query param values (#7568)
    
    Requests with special characters in query parameters (e.g.
    functionNamePattern=func%) fail with `401 NotAuthorizedException:
    "accessKeyId validate failed with error message: current signature xxx
    not match"`. This PR fixes above issue by encoding query param values
---
 paimon-python/pypaimon/api/typedef.py                | 17 +++++++++++++++--
 paimon-python/pypaimon/tests/rest/dlf_signer_test.py |  7 +++++++
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/paimon-python/pypaimon/api/typedef.py b/paimon-python/pypaimon/api/typedef.py
index 893b199b4b..3d05cb2fb6 100644
--- a/paimon-python/pypaimon/api/typedef.py
+++ b/paimon-python/pypaimon/api/typedef.py
@@ -15,15 +15,28 @@
 #  specific language governing permissions and limitations
 #  under the License.
 
-from dataclasses import dataclass
+from dataclasses import dataclass, field
 from typing import Dict, TypeVar
+from urllib.parse import quote
 
 T = TypeVar("T")
 
 
+def _encode_string(value: str) -> str:
+    if value is None:
+        return value
+    return quote(str(value), safe='')
+
+
 @dataclass
 class RESTAuthParameter:
     method: str
     path: str
     data: str
-    parameters: Dict[str, str]
+    parameters: Dict[str, str] = field(default_factory=dict)
+
+    def __post_init__(self):
+        if self.parameters:
+            self.parameters = {
+                k: _encode_string(v) for k, v in self.parameters.items()
+            }
diff --git a/paimon-python/pypaimon/tests/rest/dlf_signer_test.py b/paimon-python/pypaimon/tests/rest/dlf_signer_test.py
index a2e72f599e..9109f5d619 100644
--- a/paimon-python/pypaimon/tests/rest/dlf_signer_test.py
+++ b/paimon-python/pypaimon/tests/rest/dlf_signer_test.py
@@ -131,6 +131,13 @@ class DLFSignerTest(unittest.TestCase):
         self.assertIn("Content-MD5", header)
         self.assertEqual("UNSIGNED-PAYLOAD", header.get("x-dlf-content-sha256"))
 
+    def test_rest_auth_parameter_encodes_values(self):
+        param = RESTAuthParameter(
+            method="GET", path="/test",
+            data="", parameters={"functionNamePattern": "func%"})
+        self.assertEqual(
+            param.parameters["functionNamePattern"], "func%25")
+
     def test_parse_signing_algo_from_uri(self):
         parse = DLFAuthProviderFactory.parse_signing_algo_from_uri