Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use bundler UA when downloading gems #7092

Merged
merged 1 commit into from
Nov 15, 2023

Conversation

segiddins
Copy link
Member

Gem::RemoteFetcher uses Gem::Request, which adds the RubyGems UA.
Gem::RemoteFetcher is used to download gems, as well as the full index.
We would like the bundler UA to be used whenever bundler is making
requests.

This PR also avoids unsafely mutating the headers hash on the shared
Gem::RemoteFetcher.fetcher instance, which could cause corruption or
incorrect headers when making parallel requests. Instead, we create one
remote fetcher per rubygems remote, which is similar to the connection
segregation bundler is already doing

Copy link
Member

@martinemde martinemde left a comment

Choose a reason for hiding this comment

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

Makes sense. Glad this was caught.

@segiddins segiddins force-pushed the user-bundler-ua-when-downloading-gems branch from 0a245e7 to 5bc01ee Compare October 24, 2023 21:41
Copy link
Member

@deivid-rodriguez deivid-rodriguez left a comment

Choose a reason for hiding this comment

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

I added a question and some suggestions!

end
end
end
end
Copy link
Member

Choose a reason for hiding this comment

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

Why are we adding this class? If we use a dedicated fetcher instance per remote and no longer use Gem::RemoteFetcher.fetcher, do we still need the cleanup?

Copy link
Member Author

Choose a reason for hiding this comment

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

needed because Gem::RemoteFetcher only adds the supplied headers, and we need to be able to completely set the UA header, otherwise all the parsing we do of bundler UAs won't work

Copy link
Member

Choose a reason for hiding this comment

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

I don't fully understand. Previously we were using a single instance and were using the headers setter to set headers, right? Was that incorrect already? Is there any test that fails if we use don't add this class, in case that illustrates its need?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, the artifice test. The header needs to be cleared so the custom UA is set rather than appended to the rubygems UA

Copy link
Member

Choose a reason for hiding this comment

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

I don't know for sure that this class is the best approach, but I feel confident that it won't be difficult to refactor later, if needed, since it adds no new interface. We can revisit, but I think this fix should go in so the parallel fetching code is not broken on master.

Copy link
Member

Choose a reason for hiding this comment

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

Cool, cool, I'm just curious but did not mean to block this fix.

bundler/lib/bundler/source/rubygems.rb Outdated Show resolved Hide resolved
@@ -4,7 +4,7 @@

class EndpointMirrorSource < Endpoint
get "/gems/:id" do
if request.env["HTTP_X_GEMFILE_SOURCE"] == "https://server.example.org/"
if request.env["HTTP_X_GEMFILE_SOURCE"] == "https://server.example.org/" && request.env["HTTP_USER_AGENT"].start_with?("bundler")
Copy link
Member

Choose a reason for hiding this comment

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

This is tied to spec/realworld/gemfile_source_header_spec.rb spec, right? And you have expanded it to also check that a proper Bundler user agent is set. It's still not a very straighforward spec, but we I would add this to the spec description:

it "sets the 'X-Gemfile-Source' header and bundles successfully" do

and maybe also rename the file.

@segiddins segiddins force-pushed the user-bundler-ua-when-downloading-gems branch 2 times, most recently from 6d47788 to f1016f9 Compare November 3, 2023 18:07
Copy link
Member

@duckinator duckinator left a comment

Choose a reason for hiding this comment

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

This looks good to me, with your most recent changes. 🙂

@martinemde martinemde force-pushed the user-bundler-ua-when-downloading-gems branch from f1016f9 to 7ea0be0 Compare November 14, 2023 22:32
Gem::RemoteFetcher uses Gem::Request, which adds the RubyGems UA.
Gem::RemoteFetcher is used to download gems, as well as the full index.
We would like the bundler UA to be used whenever bundler is making
requests.

This PR also avoids unsafely mutating the headers hash on the shared
`Gem::RemoteFetcher.fetcher` instance, which could cause corruption or
incorrect headers when making parallel requests. Instead, we create one
remote fetcher per rubygems remote, which is similar to the connection
segregation bundler is already doing
@martinemde martinemde force-pushed the user-bundler-ua-when-downloading-gems branch from 7ea0be0 to f0e8dac Compare November 14, 2023 22:32
@martinemde martinemde changed the title User bundler UA when downloading gems Use bundler UA when downloading gems Nov 15, 2023
@martinemde martinemde merged commit 1d6947c into master Nov 15, 2023
66 checks passed
@martinemde martinemde deleted the user-bundler-ua-when-downloading-gems branch November 15, 2023 08:33
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.

None yet

4 participants