Skip to content

feat(storage): support setting a custom user-agent on the client#4839

Merged
joshuatants merged 2 commits intogoogleapis:mainfrom
joshuatants:storage-user-agent
Mar 4, 2026
Merged

feat(storage): support setting a custom user-agent on the client#4839
joshuatants merged 2 commits intogoogleapis:mainfrom
joshuatants:storage-user-agent

Conversation

@joshuatants
Copy link
Copy Markdown
Contributor

As requested in #3615

@product-auto-label product-auto-label bot added the api: storage Issues related to the Cloud Storage API. label Feb 27, 2026
@joshuatants
Copy link
Copy Markdown
Contributor Author

joshuatants commented Feb 27, 2026

I'm wondering if it's better to add user_agent agent directly to storage::RequestOptions instead of to CommonOptions. WDYT?

@codecov
Copy link
Copy Markdown

codecov bot commented Feb 27, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.52%. Comparing base (6266932) to head (7c28b62).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4839   +/-   ##
=======================================
  Coverage   94.52%   94.52%           
=======================================
  Files         210      210           
  Lines        8304     8317   +13     
=======================================
+ Hits         7849     7862   +13     
  Misses        455      455           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@joshuatants joshuatants force-pushed the storage-user-agent branch 3 times, most recently from f9c2401 to 0e6887c Compare February 27, 2026 08:25
@joshuatants joshuatants marked this pull request as ready for review February 27, 2026 08:47
@joshuatants joshuatants requested a review from a team as a code owner February 27, 2026 08:47
@joshuatants joshuatants requested a review from coryan February 27, 2026 08:48
Copy link
Copy Markdown
Collaborator

@coryan coryan left a comment

Choose a reason for hiding this comment

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

I'm wondering if it's better to add user_agent agent directly to storage::RequestOptions instead of to CommonOptions. WDYT?

You are probably right. Putting it in CommonOptions now forces us to think about how a per-client setting works.


When I was thinking about the feature request I was thinking about how in (say) secret manager I can say:

let client = SecretManagerService::builder().build().await?;
let get = client.get_secret().with_user_agent("foo/1.0").send().await?;

And the goal was to do the analogous thing for Storage:

let client = Storage::builder().build().await?;
let reader = client.read_object("projects/_/buckets/my-bucket", "my-object")
    .with_user_agent("foo/1.0") // ERROR, LET'S FIX THIS
    .send().await?;

This PR gives applications a different feature, they can do this now:

let client = Storage::builder()
    .set_user_agent("foo/1.0") // NEW, COOL, BUT NOT WHAT ASKED.
    .build().await?;
let reader = client.read_object("projects/_/buckets/my-bucket", "my-object")
    .with_user_agent("bar/1.0") // STILL AN ERROR...
    .send().await?;

To be clear: we will want the change in this PR too, someday, but it is not (I believe) what #3615 is asking.


In passing: the other changes in #3615 (host header, using reqwest::Client, library instrumentation for observability) are already done. You can mark that issue as fixed once the support for setting the user header is done.

@joshuatants joshuatants force-pushed the storage-user-agent branch 6 times, most recently from 60f12dd to b17d1b6 Compare March 3, 2026 03:19
Copy link
Copy Markdown
Collaborator

@coryan coryan left a comment

Choose a reason for hiding this comment

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

Thanks. There are a couple of extra changes that look out of place. I trust you to revert them and then merge the code.

@rfz-com
Copy link
Copy Markdown

rfz-com commented Mar 3, 2026

So the below should be possible with this change?

` let latest_builder: ReadObject =
gcs_client.read_object(format!("projects/_/buckets/{bucket}"), version_marker);

//  Looks like this is addressed by issue: https://github.com/googleapis/google-cloud-rust/issues/3615
//        .with_user_agent(format!("{app_name}/{user_agent_version} ({os_arch})"));

`

@coryan
Copy link
Copy Markdown
Collaborator

coryan commented Mar 3, 2026

So the below should be possible with this change?

yes, that is the intent.

Expectation::matching(all_of![
request::method_path("GET", "/storage/v1/b/test-bucket/o/test-object"),
request::headers(contains(("accept-encoding", "gzip"))),
request::headers(contains((USER_AGENT.as_str(), user_agent))),
Copy link
Copy Markdown
Contributor Author

@joshuatants joshuatants Mar 4, 2026

Choose a reason for hiding this comment

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

@coryan I wanted to use USER_AGENT here without having to have the storage crate depend direct on reqwest. I thought it'd be safer to use the constant from reqwest, though this is very minor since user-agent is practically a universal string. If I do want to use the constant from reqwest, is there a better way than making it visible through gaxi?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I would not export an extra name from google-cloud-gax-internal for a test like this. You can use http which also provides the constants and it is 1.0:

https://docs.rs/http/latest/http/header/constant.USER_AGENT.html

and since you are using .as_str() there is no type compatibility to worry about. And you have to use .as_str(), because this is going into httptest that does not use HeaderName for matching, just string slices.

I am not sure if those are "better", but the exporting the constant is not helping you that much anyway.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Got it thanks. If I decide it's worth it I'll submit the change in a separate PR.

@joshuatants
Copy link
Copy Markdown
Contributor Author

joshuatants commented Mar 4, 2026

And sorry I realise I amended my commit instead of creating a new one, thereby losing your comments from before...

@coryan
Copy link
Copy Markdown
Collaborator

coryan commented Mar 4, 2026

And sorry I realise I amended my commit instead of creating a new one, thereby losing your comments from before...

No worries.

@joshuatants joshuatants merged commit 67f9d6d into googleapis:main Mar 4, 2026
35 checks passed
@joshuatants joshuatants deleted the storage-user-agent branch March 4, 2026 00:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api: storage Issues related to the Cloud Storage API.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants