Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions core/src/main/java/org/apache/iceberg/rest/HTTPClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ public class HTTPClient extends BaseHTTPClient {
static final String REST_PROXY_PORT = "rest.client.proxy.port";
static final String REST_PROXY_USERNAME = "rest.client.proxy.username";
static final String REST_PROXY_PASSWORD = "rest.client.proxy.password";
static final String REST_USER_AGENT = "rest.client.user-agent";

@VisibleForTesting
static final String REST_CONNECTION_TIMEOUT_MS = "rest.client.connection-timeout-ms";
Expand Down Expand Up @@ -116,6 +117,11 @@ private HTTPClient(
int maxRetries = PropertyUtil.propertyAsInt(properties, REST_MAX_RETRIES, 5);
clientBuilder.setRetryStrategy(new ExponentialHttpRequestRetryStrategy(maxRetries));

String userAgent = PropertyUtil.propertyAsString(properties, REST_USER_AGENT, null);
if (userAgent != null) {
clientBuilder.setUserAgent(userAgent);
}

if (proxy != null) {
if (proxyCredsProvider != null) {
clientBuilder.setDefaultCredentialsProvider(proxyCredsProvider);
Expand Down
10 changes: 8 additions & 2 deletions core/src/test/java/org/apache/iceberg/rest/TestHTTPClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ public class TestHTTPClient {

private static final int PORT = 1080;
private static final String BEARER_AUTH_TOKEN = "auth_token";
private static final String USER_AGENT = "User-Agent";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: USER_AGENT constant exists in HttpHeaders class.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking about adding this constant to class HTTPClient, but if it's only used by test, we might not do that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, I didn't find the constant in the class org.apache.iceberg.rest.HttpHeaders. Are you referring to another class with the same name?

private static final String TEST_USER_AGENT = "Test-User-Agent";
private static final String URI = String.format("http://127.0.0.1:%d", PORT);
private static final ObjectMapper MAPPER = RESTObjectMapper.mapper();

Expand All @@ -83,7 +85,10 @@ public class TestHTTPClient {
public static void beforeClass() {
mockServer = startClientAndServer(PORT);
restClient =
HTTPClient.builder(ImmutableMap.of()).uri(URI).withAuthSession(AuthSession.EMPTY).build();
HTTPClient.builder(ImmutableMap.of(HTTPClient.REST_USER_AGENT, TEST_USER_AGENT))
.uri(URI)
.withAuthSession(AuthSession.EMPTY)
.build();
icebergBuildGitCommitShort = IcebergBuild.gitCommitShortId();
icebergBuildFullVersion = IcebergBuild.fullVersion();
}
Expand Down Expand Up @@ -461,7 +466,8 @@ private static String addRequestTestCaseAndGetPath(HttpMethod method, Item body,
.withMethod(method.name().toUpperCase(Locale.ROOT))
.withHeader("Authorization", "Bearer " + BEARER_AUTH_TOKEN)
.withHeader(HTTPClient.CLIENT_VERSION_HEADER, icebergBuildFullVersion)
.withHeader(HTTPClient.CLIENT_GIT_COMMIT_SHORT_HEADER, icebergBuildGitCommitShort);
.withHeader(HTTPClient.CLIENT_GIT_COMMIT_SHORT_HEADER, icebergBuildGitCommitShort)
.withHeader(USER_AGENT, TEST_USER_AGENT);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for my understanding, if I have a HTTP client configured to "my-user-agent" and then I later set it to "some-new-agent" on the request level, it will override it at the request level right? Just wanted to double check the order of precedence (not that I expect it to be used in practice that way)

Copy link
Contributor Author

@singhpk234 singhpk234 Jun 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

precisely, request level override always wins over the client level override.


if (method.usesRequestBody()) {
mockRequest = mockRequest.withBody(asJson);
Expand Down