sundapeng opened a new pull request, #9927:
URL: https://github.com/apache/paimon/pull/9927

   ### Purpose
   
   Follow-ups to #9918 from review feedback. Two of these can make a request 
fail to authenticate; the third turned out to be correct behaviour that nothing 
was holding in place, so it is pinned by a test rather than changed.
   
   **1. A base header that differs only in case is sent twice (Java and 
pypaimon)**
   
   `DLFAuthProvider.mergeAuthHeader` merged the caller's base headers and the 
signed headers into a case-sensitive map, and `HttpClient` turns every map 
entry into its own wire header. A base `Content-Type` therefore travelled 
alongside the V4 signer's lowercase `content-type`, and the request carried 
both.
   
   *When it breaks:* `dlf.signing-algorithm=openapi-v4` together with a base 
header whose name matches a signed one but differs in case — a 
`header.Content-Type` or `header.Host` catalog option, or the same key echoed 
back by the server, since `RESTApi` re-extracts `header.*` from the `/config` 
response. The gateway folds the duplicates into 
`application/json,application/json` while rebuilding the canonical headers, 
which is not the string that was signed, so the signature does not match. This 
is specific to the V4 signer: `DLFOpenApiSigner` emits the canonical spellings 
`Content-Type` and `Host`, so a colliding base entry was simply overwritten.
   
   Base headers whose name matches a signed one case-insensitively are now 
dropped; unrelated base headers are untouched.
   
   **2. An unrecognised `dlf.signing-algorithm` silently changes the scheme 
(pypaimon only)**
   
   `DLFAuthProvider._create_signer` ended in an unconditional `else: return 
DLFDefaultSigner(...)`.
   
   *When it breaks:* any typo or unsupported value — `openapiv4`, `openapi_v4`, 
`v4`. pypaimon then signs DLF4-HMAC-SHA256 against a `dlfnext` endpoint, and 
the server answers 403, which reads like a credential problem rather than a 
configuration one. The two options differing by three characters (`openapi` and 
`openapi-v4`) make this easy to hit. The Java client already throws 
`IllegalArgumentException` listing the supported values; pypaimon now raises 
`ValueError` the same way.
   
   **3. Canonical URI: correct as it stands, now pinned**
   
   The review flagged that this signer signs `resourcePath()` as-is while 
`DLFOpenApiSigner` decodes it first. `ResourcePaths` encodes each database and 
table name through `RESTUtil.encodeString`, and `URIBuilder` passes that path 
through byte-identically — checked for `my+db`, `a%7Eb` and `a%2Fb`, with and 
without query parameters. Signing the path as sent is therefore right, and 
decoding it would cover a path the gateway never sees. No behaviour change; a 
test now fails if the decode is ever reintroduced.
   
   ### Tests
   
   `DLFOpenApiV4SignerTest`: 15 tests, 2 new — a base `Content-Type`/`Host` is 
dropped while an unrelated base header survives, and two paths that differ only 
by encoding must not produce the same signature. `DLFRequestSignerTest`: 15 
passed. `dlf_signer_test.py`: 26 tests, 3 new — the same header case, an 
unknown algorithm raising, and the canonical-URI pin. Spotless and flake8 clean.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to