This commit is contained in:
2026-01-26 03:42:39 +08:00
parent bbea34bd77
commit 91c503b5c5
4 changed files with 212 additions and 10 deletions

View File

@@ -4,8 +4,13 @@ import (
"encoding/json"
"fmt"
"net/http"
"regexp"
"strings"
"time"
fhttp "github.com/bogdanfinn/fhttp"
tls_client "github.com/bogdanfinn/tls-client"
"github.com/bogdanfinn/tls-client/profiles"
)
var instances map[string]*Flaresolverr = make(map[string]*Flaresolverr)
@@ -15,6 +20,8 @@ type Flaresolverr struct {
v1Url string
sessionID string
proxy string
userAgent string
cookies []*http.Cookie
}
func GetInstance(flaresolverrURL string, sessionID string, proxy string) (*Flaresolverr, error) {
@@ -87,6 +94,9 @@ func (f *Flaresolverr) GetV1(reqURL string, req *V1RequestBase) (*V1ResponseBase
req.Cmd = "request.get"
req.URL = reqURL
req.Session = f.sessionID
if f.proxy != "" {
req.Proxy.Url = f.proxy
}
return f.requestV1(req)
}
@@ -100,6 +110,9 @@ func (f *Flaresolverr) PostV1(reqURL string, req *V1RequestBase) (*V1ResponseBas
req.Cmd = "request.post"
req.URL = reqURL
req.Session = f.sessionID
if f.proxy != "" {
req.Proxy.Url = f.proxy
}
return f.requestV1(req)
}
@@ -109,6 +122,9 @@ func (f *Flaresolverr) CreateSessionV1(sessionID string) (*V1ResponseBase, error
Session: sessionID,
Cmd: "sessions.create",
}
if f.proxy != "" {
req.Proxy.Url = f.proxy
}
return f.requestV1(req)
}
@@ -127,3 +143,112 @@ func (f *Flaresolverr) ListSessionsV1(sessionID string) (*V1ResponseBase, error)
}
return f.requestV1(req)
}
func (f *Flaresolverr) DetermineProfile(userAgent string) profiles.ClientProfile {
re := regexp.MustCompile(`Chrome/(\d+)\.`)
matches := re.FindStringSubmatch(userAgent)
if len(matches) < 2 {
return profiles.Chrome_120
}
ver := matches[1]
switch ver {
case "124", "123", "122", "121", "120":
return profiles.Chrome_120
case "119", "118", "117":
return profiles.Chrome_117
default:
return profiles.Chrome_120
}
}
func (f *Flaresolverr) SimulateGet(url string, ua string, cookies []*http.Cookie, opts ...tls_client.HttpClientOption) (*fhttp.Response, error) {
currentUA := ua
currentCookies := cookies
// Use cached credentials if arguments are empty
if currentUA == "" {
currentUA = f.userAgent
}
if len(currentCookies) == 0 {
currentCookies = f.cookies
}
// Helper to perform the request
doRequest := func(ua string, cookies []*http.Cookie) (*fhttp.Response, error) {
profile := f.DetermineProfile(ua)
reqOpts := append([]tls_client.HttpClientOption{}, opts...) // Clone opts
reqOpts = append(reqOpts, tls_client.WithClientProfile(profile))
if f.proxy != "" {
reqOpts = append(reqOpts, tls_client.WithProxyUrl(f.proxy))
}
client, err := tls_client.NewHttpClient(tls_client.NewNoopLogger(), reqOpts...)
if err != nil {
return nil, fmt.Errorf("failed to create client: %w", err)
}
req, err := fhttp.NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, fmt.Errorf("failed to create request: %w", err)
}
req.Header.Set("User-Agent", ua)
for _, cookie := range cookies {
req.AddCookie(&fhttp.Cookie{
Name: cookie.Name,
Value: cookie.Value,
Path: cookie.Path,
Domain: cookie.Domain,
Expires: cookie.Expires,
RawExpires: cookie.RawExpires,
MaxAge: cookie.MaxAge,
Secure: cookie.Secure,
HttpOnly: cookie.HttpOnly,
SameSite: fhttp.SameSite(cookie.SameSite),
Raw: cookie.Raw,
Unparsed: cookie.Unparsed,
})
}
return client.Do(req)
}
// First attempt
resp, err := doRequest(currentUA, currentCookies)
// Check for retry condition (err or 403)
needRetry := false
if err == nil && (resp.StatusCode == 403 || resp.StatusCode == 503) {
needRetry = true
}
if needRetry || (currentUA == "" && len(currentCookies) == 0) {
// Refresh credentials
fmt.Println("[Flaresolverr] Refreshing credentials via GetV1...")
v1Resp, err := f.GetV1(url, nil)
if err != nil {
return nil, fmt.Errorf("failed to refresh credentials: %w", err)
}
if v1Resp.Solution.Status != 200 {
return nil, fmt.Errorf("refresh failed with status: %d", v1Resp.Solution.Status)
}
// Update state
currentUA = v1Resp.Solution.UserAgent
currentCookies = v1Resp.Solution.Cookies
f.userAgent = currentUA
f.cookies = currentCookies
// Retry request
resp, err = doRequest(currentUA, currentCookies)
if err != nil {
return nil, fmt.Errorf("retry failed: %w", err)
}
}
if err != nil {
return nil, err
}
return resp, nil
}