Skip to content

[core] Unify the REST User-Agent format - #992

Open
sundapeng wants to merge 2 commits into
apache:mainfrom
sundapeng:rest-user-agent
Open

sundapeng wants to merge 2 commits into
apache:mainfrom
sundapeng:rest-user-agent

Conversation

@sundapeng

@sundapeng sundapeng commented Sep 28, 2026 •

Copy link
Copy Markdown
Member

Purpose

REST catalog requests from paimon-rust carry no User-Agent, since reqwest sets none by default, so these clients can't be attributed in the catalog server's request logs.

REST requests now carry Paimon's unified User-Agent format, <module>(<transport>[;<feature>...])[ <extended>], the one object storage requests adopt as well (#991).

Brief change log

  • The REST client sends paimon-rust/<version>(reqwest), built from the catalog options user-agent.module, user-agent.features and user-agent.extended, which object storage requests read too. The version is a compile-time constant.
  • A user-set header.User-Agent option still takes precedence and is the only User-Agent sent.
  • The DLF ECS token client sends the default.

Examples:

Client and options User-Agent
REST catalog paimon-rust/0.4.0(reqwest)
user-agent.features=Flink, user-agent.extended=vvr paimon-rust/0.4.0(reqwest;Flink) vvr
header.User-Agent=starrocks/user starrocks/user

Related: #991 (object storage User-Agent), apache/paimon#10308 (Java REST), apache/paimon#10309 (Python REST).

Tests

  • api:: unit tests: new cases on a local HTTP endpoint for the default, the new options and the header.User-Agent override; 92 passed, plus rest_api_test (45) and rest_catalog_test (79). Also checked on a live DLF REST catalog: its request log shows the configured features and extended part.
  • cargo fmt --all -- --check and cargo clippy --locked --all-targets --workspace --features fulltext,vortex -- -D warnings.

API and Format

No.

Documentation

No.

REST catalog requests went out without a User-Agent. They now send
Paimon's unified User-Agent format, module(transport;features) extended,
by default paimon-rust/<version>(reqwest). The parts come from the
catalog options user-agent.module, user-agent.features and
user-agent.extended, which object storage requests share. A user-set
header.User-Agent option still takes precedence and is the only
User-Agent sent. The DLF ECS token client sends the default.
@JingsongLi

Copy link
Copy Markdown
Contributor

Requirement fit: SUPPORTED — request attribution in REST catalog logs has end-to-end operational value. Implementation: FINDINGS at 70cf3bf2.

[P2] Refresh the User-Agent after merging /v1/config options (crates/paimon/src/api/rest_api.rs:149-152). The client is constructed from the initial options, while the normal RESTCatalog path subsequently merges server defaults/overrides and refreshes only auth/header.*. Consequently the newly added user-agent.* configuration is ignored when supplied by the catalog server, even though it is present in api.options(). I reproduced this with a local HTTP server returning default user-agent.features=ServerFeature and override user-agent.extended=catalog-tag: the merged options contain both, but the following list-databases request sends paimon-rust/0.4.0(reqwest) instead of paimon-rust/0.4.0(reqwest;ServerFeature) catalog-tag. This defeats the configured attribution for clients configured through the catalog. Please update/rebuild the default User-Agent from the merged options after bootstrap, preserving the explicit header.User-Agent precedence, and add a config_required=true HTTP regression. The current new header tests all use false.

Verification: 92/92 API unit tests, 45/45 REST API integration tests, and 79/79 REST catalog integration tests passed. The temporary config-negotiation regression failed with the header mismatch above; the test edit was restored. Diff check and current-main merge-tree passed; all 14 head CI checks are green.

The REST client was built from the initial options only, so user-agent.*
options delivered through /v1/config were ignored. RESTApi::new now
rebuilds the default User-Agent from the merged options after bootstrap;
an explicit header.User-Agent still takes precedence per request.
@sundapeng

Copy link
Copy Markdown
Member Author

Thanks, good catch. The REST client was built from the initial options only, so user-agent.* delivered through /v1/config was ignored. RESTApi::new now rebuilds the default User-Agent from the merged options after bootstrap, and an explicit header.User-Agent still takes precedence. Added a config_required=true regression where the server returns user-agent.features as a default and user-agent.extended as an override (fixed in 7979517).

@JingsongLi

Copy link
Copy Markdown
Contributor

Re-reviewed 7979517f after the fix. The previous P2 is resolved: the original config-required HTTP regression now sends the server-provided features/extension, and the explicit header.User-Agent precedence test passes. The rebuilt client preserves the auth function and existing timeout/default-header behavior.

Validation on the updated head: 94 API unit tests, 46 REST API integration tests (including the original reproducer), and 79 REST catalog integration tests passed. Current-main merge check is clean. No further actionable code finding from this follow-up; remaining CI runs should finish before merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants