feat(ja3): Update JA3 fingerprinting source and parsing

This commit is contained in:
2025-11-19 15:44:24 +11:00
parent 567048911d
commit 65b46e1975
3 changed files with 49 additions and 4 deletions

View File

@@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"net/http"
"regexp"
"strings"
"time"
@@ -132,11 +133,20 @@ func (f *Flaresolverr) ListSessionsV1(sessionID string) (*V1ResponseBase, error)
}
func (f *Flaresolverr) GetJa3AndUserAgent() (ua string, ja3 string, err error) {
resp, err := f.GetV1("https://tls.peet.ws/api/tls", nil)
resp, err := f.GetV1("view-source:https://tools.scrapfly.io/api/tls", nil)
if err != nil {
return "", "", err
}
return resp.Solution.UserAgent, resp.Solution.RawResponse.(map[string]any)["tls"].(map[string]any)["ja3"].(string), nil
j := regexp.MustCompile(`{(.*)}`).FindStringSubmatch(resp.Solution.RawResponse.(string))
if len(j) < 2 {
return "", "", fmt.Errorf("failed to get ja3")
}
ja3Obj := Ja3{}
err = json.Unmarshal([]byte(j[0]), &ja3Obj)
if err != nil {
return "", "", err
}
return resp.Solution.UserAgent, ja3Obj.Ja3, nil
}
func (f *Flaresolverr) preSimulateRequest(opts *SimulateOptions) error {

View File

@@ -83,3 +83,36 @@ type IndexResponse struct {
type HealthResponse struct {
Status string `json:"status"`
}
type Ja3 struct {
Ja3 string `json:"ja3"`
Ja3N string `json:"ja3n"`
Ja3Digest string `json:"ja3_digest"`
Ja3NDigest string `json:"ja3n_digest"`
ScrapflyFp string `json:"scrapfly_fp"`
ScrapflyFpDigest string `json:"scrapfly_fp_digest"`
TLS struct {
Version string `json:"version"`
Ciphers []string `json:"ciphers"`
Curves []string `json:"curves"`
Extensions []string `json:"extensions"`
Points []string `json:"points"`
Protocols []string `json:"protocols"`
Versions []string `json:"versions"`
HandshakeDuration string `json:"handshake_duration"`
IsSessionResumption bool `json:"is_session_resumption"`
SessionTicketSupported bool `json:"session_ticket_supported"`
SupportSecureRenegotiation bool `json:"support_secure_renegotiation"`
SupportedTLSVersions []int `json:"supported_tls_versions"`
SupportedProtocols []string `json:"supported_protocols"`
SignatureAlgorithms []int `json:"signature_algorithms"`
PskKeyExchangeMode string `json:"psk_key_exchange_mode"`
CertCompressionAlgorithms string `json:"cert_compression_algorithms"`
EarlyData bool `json:"early_data"`
UsingPsk bool `json:"using_psk"`
SelectedProtocol string `json:"selected_protocol"`
SelectedCurveGroup int `json:"selected_curve_group"`
SelectedCipherSuite int `json:"selected_cipher_suite"`
KeyShares []int `json:"key_shares"`
} `json:"tls"`
}

View File

@@ -2,13 +2,14 @@ package test
import (
"encoding/json"
"fmt"
"testing"
"git.nite07.com/nite/go-flaresolverr"
)
func TestGetV1(t *testing.T) {
f, err := flaresolverr.GetInstance("http://127.0.0.1:8191", "", "")
f, err := flaresolverr.GetInstance("http://100.64.0.1:8191", "", "")
if err != nil {
t.Error(err)
return
@@ -27,7 +28,7 @@ func TestGetV1(t *testing.T) {
}
func TestImitateGet(t *testing.T) {
f, err := flaresolverr.GetInstance("http://127.0.0.1:8191", "", "")
f, err := flaresolverr.GetInstance("http://100.64.0.1:8191", "", "")
if err != nil {
t.Error(err)
return
@@ -49,6 +50,7 @@ func TestImitateGet(t *testing.T) {
return
}
if resp1.Status != 200 {
fmt.Printf("status is not 200: %v", resp1.Status)
t.FailNow()
}
jsonBytes, _ := json.Marshal(resp1)