Fix FrozenError when passing a frozen URI as the base URL - #1685
Open
Leonard013 wants to merge 1 commit into
Open
Fix FrozenError when passing a frozen URI as the base URL#1685Leonard013 wants to merge 1 commit into
Leonard013 wants to merge 1 commit into
Conversation
Faraday::Utils.URI returns an incoming URI untouched (no dup) whenever it responds to :host, and Connection#url_prefix= then mutates that exact object in place (path=, query=, user=/password=). Passing a frozen URI therefore raised "FrozenError: can't modify frozen URI::HTTP", and passing an unfrozen URI silently mutated the caller's object. Coerce the value to a String before handing it to Utils.URI in url_prefix=, so a brand-new, mutable URI is always parsed. String base URLs are unaffected. Fixes lostisland#1349 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NX8ygWTRa86kE8k8Yn9bpu
| # URI instance. Otherwise, when passed an existing URI, Utils.URI returns | ||
| # it untouched and the in-place mutations below (`path=`, `query=`, | ||
| # `user=`/`password=`) would either raise a FrozenError on a frozen URI | ||
| # or unexpectedly modify the caller's object. |
Member
There was a problem hiding this comment.
Drop this implementation level comment.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix
FrozenErrorwhen passing a frozen URI as the base URLFixes #1349
Problem
Passing a frozen
URI(or, more generally, anyURIinstance the callerstill holds a reference to) as the base URL to
Faraday.newcrashes:Even without
freeze, the connection mutates the exactURIobject thecaller passed in, which is a surprising side effect.
Root cause
Faraday::Utils.URI(lib/faraday/utils.rb:70-78) returns the argumentuntouched whenever it already responds to
:host, i.e. it never duplicates anincoming
URI:Connection#url_prefix=(lib/faraday/connection.rb:365) then mutates thatexact object in place while pulling apart the URL:
self.path_prefix = uri.path→url_prefix.path = ...(connection.rb:391)uri.query = nil(connection.rb:369)uri.user = uri.password = nil(connection.rb:373)The first of these (
path=) is enough to raiseFrozenErroron a frozen URI;all three would mutate a caller-owned URI in place.
Fix
Coerce the incoming value to a
Stringbefore handing it toUtils.URIinConnection#url_prefix=, soUtils.URIalways parses a brand-new, mutableURIinstance rather than returning (and then mutating) the caller's object:This follows the maintainer's suggested direction on the issue (prefer the
simple
#dup/.to_sapproach, with a comment explaining why). AStringbaseURL — the common case — is unaffected: it was already re-parsed before, and
still is. The change is scoped to
url_prefix=; the trailingproxy_from_env(url)call still receives the originalurl, so proxy handlingfor
URIinputs is unchanged.Tests
Added a regression example under
Faraday::Connection.newinspec/faraday/connection_spec.rbthat passes a frozen URI carrying both aquery string and basic-auth credentials, exercising all three mutation sites
(
path=,query=,user=/password=):Verification (before / after)
Before the fix, the new examples fail:
After the fix:
Compatibility
No breaking changes. Behaviour for
Stringbase URLs is identical.URIbaseURLs now work when frozen and are no longer mutated in place — strictly a
bug fix. Public API and method signatures are unchanged.