Documentation
¶
Overview ¶
Package cloudfetch provides an HTTP client that bypasses Cloudflare bot detection by mimicking a real browser's TLS fingerprint and headers.
It uses uTLS to reproduce a browser's TLS Client Hello (JA3/JA4 fingerprint), sends that browser's default headers, keeps a cookie jar across requests, and solves Cloudflare's classic IUAM JS challenge.
Index ¶
- Variables
- type Browser
- type Client
- func (c *Client) CloseIdleConnections()
- func (c *Client) Cookies(rawURL string) []*http.Cookie
- func (c *Client) Do(req *http.Request) (*Response, error)
- func (c *Client) Get(url string) (*Response, error)
- func (c *Client) Post(url, contentType string, body io.Reader) (*Response, error)
- func (c *Client) Underlying() *http.Client
- type Option
- type Response
Constants ¶
This section is empty.
Variables ¶
var ( // Chrome is Chrome 133 on Windows, the default. Chrome = Browser{utls.HelloChrome_133, [][2]string{ {"sec-ch-ua", `"Not(A:Brand";v="99", "Google Chrome";v="133", "Chromium";v="133"`}, {"sec-ch-ua-mobile", "?0"}, {"sec-ch-ua-platform", `"Windows"`}, {"Upgrade-Insecure-Requests", "1"}, {"User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36"}, {"Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"}, {"Sec-Fetch-Site", "none"}, {"Sec-Fetch-Mode", "navigate"}, {"Sec-Fetch-User", "?1"}, {"Sec-Fetch-Dest", "document"}, {"Accept-Encoding", "gzip, deflate, br, zstd"}, {"Accept-Language", "en-US,en;q=0.9"}, {"Priority", "u=0, i"}, }} // Firefox is Firefox 120 on Windows. Firefox = Browser{utls.HelloFirefox_120, [][2]string{ {"User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/120.0"}, {"Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"}, {"Accept-Language", "en-US,en;q=0.5"}, {"Accept-Encoding", "gzip, deflate, br"}, {"Upgrade-Insecure-Requests", "1"}, {"Sec-Fetch-Dest", "document"}, {"Sec-Fetch-Mode", "navigate"}, {"Sec-Fetch-Site", "none"}, {"Sec-Fetch-User", "?1"}, }} // Safari is Safari 16.0 on macOS. Safari = Browser{utls.HelloSafari_16_0, [][2]string{ {"Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"}, {"User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15"}, {"Accept-Language", "en-US,en;q=0.9"}, {"Accept-Encoding", "gzip, deflate, br"}, }} // Edge is Edge 85 on Windows. Edge = Browser{utls.HelloEdge_85, [][2]string{ {"Upgrade-Insecure-Requests", "1"}, {"User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36 Edg/85.0.564.51"}, {"Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"}, {"Sec-Fetch-Site", "none"}, {"Sec-Fetch-Mode", "navigate"}, {"Sec-Fetch-User", "?1"}, {"Sec-Fetch-Dest", "document"}, {"Accept-Encoding", "gzip, deflate, br"}, {"Accept-Language", "en-US,en;q=0.9"}, }} )
Browsers to impersonate with WithBrowser.
var ( // ErrManagedChallenge means the site served a managed challenge // (Turnstile), which needs a real browser. ErrManagedChallenge = errors.New("cloudfetch: managed challenge (Turnstile) needs a real browser") // ErrCaptcha means the site served a CAPTCHA, which needs an external // solving service. ErrCaptcha = errors.New("cloudfetch: CAPTCHA challenge needs an external solving service") // ErrChallengeFailed means the site still served a JS challenge after the // number of attempts set by WithMaxRetries. ErrChallengeFailed = errors.New("cloudfetch: challenge not solved") )
Errors returned by Client when a challenge can't be solved.
Functions ¶
This section is empty.
Types ¶
type Browser ¶ added in v0.2.0
type Browser struct {
// contains filtered or unexported fields
}
Browser is a browser to impersonate: its TLS fingerprint and the default headers it sends, both for the same version.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is an HTTP client with browser TLS fingerprinting. It is safe for concurrent use.
func (*Client) CloseIdleConnections ¶ added in v0.2.0
func (c *Client) CloseIdleConnections()
CloseIdleConnections closes connections kept open by earlier requests that are not in use. It does not interrupt requests in progress.
func (*Client) Do ¶
Do sends req and returns the response, solving Cloudflare challenges along the way. It fills in the headers req doesn't set and leaves req unmodified. req's context also bounds the waits before submitting challenge answers.
If a challenge can't be solved, Do returns ErrManagedChallenge, ErrCaptcha or ErrChallengeFailed. Otherwise the caller must close the response body, directly or by calling Text or Bytes.
func (*Client) Underlying ¶
Underlying returns the *http.Client that sends requests. It keeps the browser's TLS fingerprint and the cookie jar, but requests sent through it directly get none of the browser's default headers and no challenge solving.
type Option ¶
type Option func(*Client)
Option configures a Client.
func WithBrowser ¶
WithBrowser sets the browser to impersonate: its TLS fingerprint and its default headers. Defaults to Chrome.
func WithHeader ¶
WithHeader adds a header sent with every request. It overrides the browser's default for the same header, and is overridden by headers set on the request itself.
func WithMaxRetries ¶ added in v0.2.0
WithMaxRetries sets how many times to solve a challenge for one request before giving up with ErrChallengeFailed. Defaults to 3; 0 disables solving.
func WithProxy ¶
WithProxy routes connections through an HTTP proxy, given as "http://[user:pass@]host:port", using CONNECT tunnels. The TLS handshake with the target still happens end to end, so the fingerprint is unchanged.
func WithTimeout ¶
WithTimeout sets the HTTP client timeout. Defaults to 30s.
type Response ¶
Response is an HTTP response from a Client.
Text and Bytes read the whole body, decompress it according to its Content-Encoding, close it, and cache the result, so they can be called more than once. Reading Body directly gives the raw, possibly compressed bytes instead. For Cloudflare 403, 429 and 503 responses Client has already read the body to look for a challenge, so use Text or Bytes for those.
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
basic
command
Command basic fetches a page through cloudfetch and prints its status and size.
|
Command basic fetches a page through cloudfetch and prints its status and size. |
|
request
command
Command request sends a custom request with a deadline and its own headers, impersonating Firefox, and reports challenges it can't solve.
|
Command request sends a custom request with a deadline and its own headers, impersonating Firefox, and reports challenges it can't solve. |