Open
Conversation
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.
This PR contains the following updates:
5.3.1→6.0.1Release Notes
httprb/http (http)
v6.0.1Compare Source
Changed
v6.0.0Compare Source
Changed
http-form_datagem into the mainhttpgem. TheHTTP::FormDatamodule (including
Part,File,Multipart,Urlencoded, andCompositeIO)is now shipped directly with
httpinstead of being a separate dependency.The public API is unchanged.
Fixed
Inflaterno longer raisesZlib::BufErrorwhen a response declaresContent-Encoding: gzip(or deflate) but the body is not valid compresseddata. This commonly occurred when following redirects with
auto_inflateenabled, because the redirect response had a
Content-Encodingheader but anon-compressed body. (#621)
the next request, instead of raising
StateError. Bodies up to 1 MiB aredrained transparently; larger bodies cause the connection to close and reopen.
This prevents the silent body clobbering described in #371, where an unread
response body would return
""after a subsequent request. (#371)Response#content_lengthnow handles duplicateContent-Lengthheaders perRFC 7230 Section 3.3.2. When all values are identical, they are collapsed into
a single valid value. When values conflict,
nilis returned instead ofraising
TypeError. (#566)100 Continue) are now transparentlyskipped, returning the final response. This was a regression introduced when
the parser was migrated from http-parser to llhttp. (#667)
same URL with different cookies is no longer falsely detected as an endless
loop. Fixes cookie-dependent redirect flows where a server sets a cookie on
one hop and expects it on the next. (#544)
HTTP.timeout(read: n, write: n, connect: n)) nolonger default unspecified values to 0.25 seconds. Omitted timeouts now mean
no timeout for that operation, matching the behavior when no timeout is
configured at all. (#579)
:wait_writablefromread_nonblockand:wait_readablefromwrite_nonblockon SSL socketsduring TLS renegotiation. Previously these symbols were returned as data
instead of being waited on. (#358)
StateError.HTTP.persistentreturns anHTTP::Sessionthat pools oneHTTP::Clientper origin, so redirects to a different domain transparentlyopen (and reuse) a separate persistent connection. Cookie management is
preserved across all hops. (#557)
.headers,.auth,.cookies, etc.) on apersistent session no longer breaks connection reuse. Child sessions created
by chaining now share the parent's connection pool, so
HTTP.persistent(host).headers(...).get(path)reuses the same underlyingTCP connection across calls. (#372)
Changed
HTTP.persistentnow returns anHTTP::Sessioninstead of anHTTP::Client. The session pools persistent clients per origin and exposesthe same chainable API (
get,post,headers,follow, etc.) plus aclosemethod that shuts down all pooled connections. Code that calledHTTP::Client-only methods on the return value will need updating. (#557)across the public API. Methods like
HTTP.get(url, body: "data")continue towork, but passing an explicit hash (e.g.,
HTTP.get(url, {body: "data"})) isno longer supported, and unrecognized keyword arguments now raise
ArgumentError. Affected methods: all HTTP verb methods (get,post,etc.),
request,follow,retriable,URI.new,Request.new,Response.new,Redirector.new,Retriable::Performer.new,Retriable::DelayCalculator.new, andTimeout::Null.new(and subclasses).HTTP::URI.newalso no longer acceptsAddressable::URIobjects.addressableis no longer a runtime dependency. It is nowlazy-loaded only when parsing non-ASCII (IRI) URIs or normalizing
internationalized hostnames. Install the
addressablegem if you neednon-ASCII URI support. ASCII-only URIs use Ruby's stdlib
URIparserexclusively.
HTTP::Request::Builder. Thebuild_requestmethod has been removed fromClient,Session, and thetop-level
HTTPmodule. UseHTTP::Request::Builder.new(options).build(verb, uri)to construct requests without executing them.
Added
requestthat auto-closes the connectionafter the block returns.
HTTP.get(url) { |response| response.status }yieldsthe response, closes the underlying connection, and returns the block's value.
Works with all verb methods and chained options. (#270)
HTTP.use(:caching)) that stores and reuses responsesaccording to RFC 7234. Supports
Cache-Control(max-age,no-cache,no-store),Expires,ETag/If-None-Match, andLast-Modified/If-Modified-Sincefor freshness checks and conditionalrevalidation. Ships with a default in-memory store; custom stores can be
passed via
store:option. Only GET and HEAD responses are cached. (#223)HTTP.digest_auth(user:, pass:)for HTTP Digest Authentication (RFC 2617 /RFC 7616). Automatically handles 401 challenges with digest credentials,
supporting MD5, SHA-256, MD5-sess, and SHA-256-sess algorithms with
quality-of-protection negotiation. Works as a chainable feature:
HTTP.digest_auth(user: "admin", pass: "secret").get(url)(#448)TCPSocketimplementation. Connection attempts now try multiple addresses (IPv6 and
IPv4) concurrently, improving reliability on dual-stack networks. Connect
timeouts are passed natively to
TCPSocketinstead of usingTimeout.timeout, avoidingThread.raiseinterference with the HappyEyeballs state machine. (#739)
HTTP.base_urifor setting a base URI that resolves relative request pathsper RFC 3986. Supports chaining (
HTTP.base_uri("https://api.example.com/v1") .get("users")), and integrates withpersistentconnections by deriving thehost when omitted (#519, #512, #493)
Request::Body#loggable?andResponse::Body#loggable?predicates, and abinary_formatteroption for the logging feature. Binary bodies(IO/Enumerable request sources, binary-encoded request strings, and
binary-encoded responses) are now formatted instead of dumped raw,
preventing unreadable log output when transferring files like images or
audio. Available formatters:
:stats(default, logs byte count),:base64(logs base64-encoded content), or a customProc. Invalidformatter values raise
ArgumentError(#784)Feature#on_requestandFeature#around_requestlifecycle hooks, calledbefore/around each request attempt (including retries), for per-attempt side
effects like instrumentation spans and circuit breakers (#826)
deconstruct_keys) for Response, Response::Status,Headers, ContentType, and URI (#642)
are no longer mutually exclusive. Use
HTTP.timeout(global: 60, read: 30, write: 30, connect: 5)to set both aglobal request timeout and individual operation limits (#773)
Fixed
HTTP::URI.form_encodenow encodes newlines as%0Ainstead of%0D%0A(#449)Headers::Normalizercache is now per-thread viaThread.current, eliminating a potential race condition when multiplethreads share a normalizer instance
attempt, fixing
NoMethodErrorwithActiveSupport::Notificationswhenusing
.retriablewith the instrumentation feature (#826)HTTP::URI::InvalidErrorfor malformed or schemeless URIs andArgumentErrorfor nil or empty URIs, instead of confusingUnsupportedSchemeErrororAddressable::URI::InvalidURIError(#565)AuthorizationandCookieheaders when following redirects to adifferent origin (scheme, host, or port) to prevent credential leakage
(#516, #770)
defaulting to
Encoding::BINARY(#535)LocalJumpErrorwhen using instrumentation with instrumenters thatunconditionally yield in
#instrument(e.g.,ActiveSupport::Notifications)(#673)
body chunks are now logged as they are streamed, preserving
response.body.each(#785)Removed
HTTP::URIsetter methods (scheme=,user=,password=,authority=,origin=,port=,request_uri=,fragment=) and normalized accessors(
normalized_user,normalized_password,normalized_port,normalized_path,normalized_query) that were delegated toAddressable::URIbut never used internallyHTTP::URI#originis no longer delegated toAddressable::URI. The newimplementation follows RFC 6454, normalizing scheme and host to lowercase
and excluding user info from the origin string
HTTP::URI#request_uriis no longer delegated toAddressable::URIHTTP::URI#omitis no longer delegated toAddressable::URIand nowreturns
HTTP::URIinstead ofAddressable::URI(#491)HTTP::URI#query_valuesandHTTP::URI#query_values=delegations toAddressable::URI. Query parameter merging now uses stdlibURI.decode_www_form/URI.encode_www_formHTTP::URIdelegations fornormalized_scheme,normalized_authority,normalized_fragment, andauthoritytoAddressable::URI. The URInormalizer now inlines these operations directly
HTTP::URI#joinis no longer delegated toAddressable::URIand nowreturns
HTTP::URIinstead ofAddressable::URI. Uses stdlibURI.joinwith automatic percent-encoding of non-ASCII characters (#491)
HTTP::URI.form_encodeno longer delegates toAddressable::URI. Usesstdlib
URI.encode_www_forminsteadChanged
HTTP::Response::Statusno longer inherits fromDelegator.It now uses
ComparableandForwardableinstead, providingto_i,to_int, and<=>for numeric comparisons and range matching. Code thatcalled
__getobj__/__setobj__or relied on implicit delegation ofarbitrary
Integermethods (e.g.,status.even?) will need to be updatedto use
status.codeinstead.headers,.timeout,.cookies,.auth,.follow,.via,.use,.encoding,.nodelay,.basic_auth,.accept) now return a thread-safeHTTP::Sessioninstead ofHTTP::Client.Sessioncreates a newClientfor each request, making it safe to share aconfigured session across threads.
HTTP.persistentstill returnsHTTP::Clientsince persistent connections require mutable state. Code thatcalls HTTP verb methods (
.get,.post, etc.) or accesses.default_optionsis unaffected. Code that checks
is_a?(HTTP::Client)on the return value ofchainable methods will need to be updated to check for
HTTP::Session.retriablenow returnsHTTP::Sessioninstead ofHTTP::Retriable::Client. Retry is a session-level option: it flows throughHTTP::OptionsintoHTTP::Client#perform, eliminating the need forseparate
Retriable::ClientandRetriable::Sessionclassessetting
Content-Lengthexplicitly or using chunkedTransfer-Encoding(#560)Connection#readpartialnow raisesEOFErrorinstead ofreturning
nilat end-of-stream, and supports anoutbufparameter,conforming to the
IO#readpartialAPI.Body#readpartialandInflater#readpartialalso raiseEOFError(#618).timeout()with a Hash nowrejects unknown keys, non-numeric values, string keys, and empty hashes (#754)
Response#cookiesnow returnsArray<HTTP::Cookie>instead ofHTTP::CookieJar. Thecookiesoption has been removed fromOptions;Chainable#cookiesnow sets theCookieheader directly with no implicitmerging — the last
.cookies()call wins (#536)RedirectortoSession.Redirectoris now a pure redirect-following engine with no cookieawareness;
Session#requestmanages cookies across redirect hopsHTTP::Options.new,HTTP::Client.new, andHTTP::Session.newnow accept keyword arguments instead of an options hash. For example,
HTTP::Options.new(response: :body)continues to work, butHTTP::Options.new({response: :body})must be updated toHTTP::Options.new(**options). Invalid option names now raiseArgumentErrorautomatically (#447)Removed
Headers::Mixinand the[]/[]=delegators onRequestandResponse. Userequest.headers["..."]andresponse.headers["..."]instead (#537)Configuration
📅 Schedule: Branch creation - At 12:00 AM through 04:59 AM and 10:00 PM through 11:59 PM, Monday through Friday ( * 0-4,22-23 * * 1-5 ), Only on Sunday and Saturday ( * * * * 0,6 ) (UTC), Automerge - At any time (no schedule defined).
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.