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]
