Skip to content

v0.2.0

Choose a tag to compare

@luinor223 luinor223 released this 28 Oct 17:15
· 5 commits to main since this release

This release moves cloudfetch to an API modelled on net/http. It has breaking changes; see the upgrade notes below.

go get github.com/luinor223/cloudfetch@v0.2.0

Breaking changes

  • Do takes an *http.Request. Its context and headers apply to the whole call, including challenge solving, and req is not modified. DoContext is removed: use http.NewRequestWithContext instead.
  • Post takes a content type, like net/http: Post(url, contentType, body).
  • WithBrowser takes a Browser (Chrome, Firefox, Safari, Edge) instead of a utls.ClientHelloID. Each preset pins a TLS fingerprint and headers for the same version: Chrome 133, Firefox 120, Safari 16.0 and Edge 85.
  • MaxChallengeRetries is replaced by WithMaxRetries(n). The default is 3; 0 disables solving.
  • Unsolvable challenges return sentinel errors you can check with errors.Is: ErrManagedChallenge, ErrCaptcha and ErrChallengeFailed. Running out of retries now returns ErrChallengeFailed instead of the challenge page.
  • Header precedence: headers set on the request now override WithHeader, which overrides the browser defaults.

Upgrading

// v0.1.0
resp, err := client.DoContext(ctx, "POST", url, body)
client := cloudfetch.New(cloudfetch.WithBrowser(utls.HelloFirefox_120))

// v0.2.0
req, _ := http.NewRequestWithContext(ctx, http.MethodPost, url, body)
resp, err := client.Do(req)
client := cloudfetch.New(cloudfetch.WithBrowser(cloudfetch.Firefox))

New

  • Client.CloseIdleConnections(), which http.Client.CloseIdleConnections() also reaches.
  • Runnable programs in examples/.

Fixes

  • The IUAM solver handles real Cloudflare pages. It is tested against challenge pages captured by cloudscraper, including pages with decoy inputs, setInterval and answers read from hidden elements.
  • Concurrent first requests to one host no longer leak a connection, and HTTP/2 connections that get replaced now close once they are idle.
  • Bare IPv6 hosts such as https://[::1]/ get the default port.
  • Non-Cloudflare 403, 429 and 503 responses are no longer read into memory just to check for a challenge.

Full changelog: v0.1.0...v0.2.0