feat(ja3): Update JA3 fingerprinting source and parsing
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -132,11 +133,20 @@ func (f *Flaresolverr) ListSessionsV1(sessionID string) (*V1ResponseBase, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *Flaresolverr) GetJa3AndUserAgent() (ua string, ja3 string, err 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 {
|
if err != nil {
|
||||||
return "", "", err
|
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 {
|
func (f *Flaresolverr) preSimulateRequest(opts *SimulateOptions) error {
|
||||||
|
|||||||
33
model.go
33
model.go
@@ -83,3 +83,36 @@ type IndexResponse struct {
|
|||||||
type HealthResponse struct {
|
type HealthResponse struct {
|
||||||
Status string `json:"status"`
|
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"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,13 +2,14 @@ package test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.nite07.com/nite/go-flaresolverr"
|
"git.nite07.com/nite/go-flaresolverr"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetV1(t *testing.T) {
|
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 {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
@@ -27,7 +28,7 @@ func TestGetV1(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestImitateGet(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 {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
@@ -49,6 +50,7 @@ func TestImitateGet(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if resp1.Status != 200 {
|
if resp1.Status != 200 {
|
||||||
|
fmt.Printf("status is not 200: %v", resp1.Status)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
jsonBytes, _ := json.Marshal(resp1)
|
jsonBytes, _ := json.Marshal(resp1)
|
||||||
|
|||||||
Reference in New Issue
Block a user