Files
requests/option.go
gospider d941aad1a2 sync
2025-08-19 10:08:50 +08:00

235 lines
13 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package requests
import (
"crypto/tls"
"net/url"
"time"
"github.com/gospider007/websocket"
"github.com/quic-go/quic-go"
uquic "github.com/refraction-networking/uquic"
utls "github.com/refraction-networking/utls"
)
type LogType string
const (
LogType_DNSLookup LogType = "DNSLookup"
LogType_TCPConnect LogType = "TCPConnect"
LogType_TLSHandshake LogType = "TLSHandshake"
LogType_ProxyConnectRemote LogType = "ProxyConnectRemote"
LogType_ResponseHeader LogType = "ResponseHeader"
LogType_ResponseBody LogType = "ResponseBody"
)
type Log struct {
Time time.Time
Msg any `json:"msg"`
Id string `json:"id"`
Type LogType `json:"type"`
}
// Connection Management Options
type ClientOption struct {
Spec string //goSpiderSpec origin : https://github.com/gospider007/fp
OrderHeaders []string
DialOption *DialOption
Jar Jar //custom cookies
Logger func(Log) //debuggable
OptionCallBack func(ctx *Response) error //option callback,if error is returnd, break request
ResultCallBack func(ctx *Response) error //result callback,if error is returnd,next errCallback
ErrCallBack func(ctx *Response) error //error callback,if error is returnd,break request
RequestCallBack func(ctx *Response) error //request and response callback,if error is returnd,reponse is error
GetProxy func(ctx *Response) (any, error) //proxy callback:support https,http,socks5 proxy
TlsConfig *tls.Config
UtlsConfig *utls.Config
QuicConfig *quic.Config
UquicConfig *uquic.Config
USpec any //support ja3.USpec,uquic.QUICID,bool
UserAgent string //headers User-Agent value
Proxy any //strong or []string, ,support https,http,socks5
MaxRetries int //try num
MaxRedirect int //redirect num ,<0 no redirect,==0 no limit
Timeout time.Duration //request timeout
ResponseHeaderTimeout time.Duration //ResponseHeaderTimeout
TlsHandshakeTimeout time.Duration //tls timeout
ForceHttp3 bool //force use http3 send requests
ForceHttp1 bool //force use http1 send requests
DisCookie bool //disable cookies
DisDecode bool //disable auto decode
Bar bool ////enable bar display
Headers any //default headers
WsOption *websocket.Option //websocket option
Stream bool //disable auto read
}
// Options for sending requests
type RequestOption struct {
Spec string //goSpiderSpec origin : https://github.com/gospider007/fp
OrderHeaders []string
DialOption *DialOption
Jar Jar //custom cookies
Logger func(Log) //debuggable
OptionCallBack func(ctx *Response) error //option callback,if error is returnd, break request
ResultCallBack func(ctx *Response) error //result callback,if error is returnd,next errCallback
ErrCallBack func(ctx *Response) error //error callback,if error is returnd,break request
RequestCallBack func(ctx *Response) error //request and response callback,if error is returnd,reponse is error
GetProxy func(ctx *Response) (any, error) //proxy callback:support https,http,socks5 proxy
TlsConfig *tls.Config
UtlsConfig *utls.Config
QuicConfig *quic.Config
UquicConfig *uquic.Config
USpec any //support ja3.USpec,uquic.QUICID,bool
UserAgent string //headers User-Agent value
Proxy any //strong or []string, ,support https,http,socks5
MaxRetries int //try num
MaxRedirect int //redirect num ,<0 no redirect,==0 no limit
Timeout time.Duration //request timeout
ResponseHeaderTimeout time.Duration //ResponseHeaderTimeout
TlsHandshakeTimeout time.Duration //tls timeout
ForceHttp3 bool //force use http3 send requests
ForceHttp1 bool //force use http1 send requests
DisCookie bool //disable cookies
DisDecode bool //disable auto decode
Bar bool ////enable bar display
Headers any //default headers
WsOption *websocket.Option //websocket option
Stream bool //disable auto read
//分割线
//以下为请求参数
Cookies any // cookies,support :json,map,strhttp.Header
Params any //url paramsjoin url query,json,map
Json any //send application/json,support io.Reader,string,[]bytes,json,map
Data any //send application/x-www-form-urlencoded, support io.Reader, string,[]bytes,json,map
Form any //send multipart/form-data,file upload,support io.Reader, json,map
Text any //send text/xml,support: io.Reader, string,[]bytes,json,map
Body any //not setting context-type,support io.Reader, string,[]bytes,json,map
Url *url.URL
// other option
Method string //method
Host string
Referer string //set headers referer value
ContentType string //headers Content-Type value
DisProxy bool //force disable proxy
readOne bool
orderHeaders *OrderData //order headers
gospiderSpec *GospiderSpec
disBody bool
}
func merge(option *RequestOption, clientOption *ClientOption) {
if option.Spec == "" {
option.Spec = clientOption.Spec
}
if option.WsOption == nil {
option.WsOption = clientOption.WsOption
}
if option.Headers == nil {
option.Headers = clientOption.Headers
}
if option.OrderHeaders == nil {
option.OrderHeaders = clientOption.OrderHeaders
}
if option.DialOption == nil {
option.DialOption = clientOption.DialOption
}
if option.Jar == nil {
option.Jar = clientOption.Jar
}
if option.Logger == nil {
option.Logger = clientOption.Logger
}
if option.OptionCallBack == nil {
option.OptionCallBack = clientOption.OptionCallBack
}
if option.ResultCallBack == nil {
option.ResultCallBack = clientOption.ResultCallBack
}
if option.ErrCallBack == nil {
option.ErrCallBack = clientOption.ErrCallBack
}
if option.RequestCallBack == nil {
option.RequestCallBack = clientOption.RequestCallBack
}
if option.GetProxy == nil {
option.GetProxy = clientOption.GetProxy
}
if option.TlsConfig == nil {
option.TlsConfig = clientOption.TlsConfig
}
if option.UtlsConfig == nil {
option.UtlsConfig = clientOption.UtlsConfig
}
if option.QuicConfig == nil {
option.QuicConfig = clientOption.QuicConfig
}
if option.UquicConfig == nil {
option.UquicConfig = clientOption.UquicConfig
}
if option.USpec == nil {
option.USpec = clientOption.USpec
}
if option.UserAgent == "" {
option.UserAgent = clientOption.UserAgent
}
if option.Proxy == nil {
option.Proxy = clientOption.Proxy
}
if option.MaxRetries == 0 {
option.MaxRetries = clientOption.MaxRetries
}
if option.MaxRedirect == 0 {
option.MaxRedirect = clientOption.MaxRedirect
}
if option.Timeout == 0 {
option.Timeout = clientOption.Timeout
}
if option.ResponseHeaderTimeout == 0 {
option.ResponseHeaderTimeout = clientOption.ResponseHeaderTimeout
}
if option.TlsHandshakeTimeout == 0 {
option.TlsHandshakeTimeout = clientOption.TlsHandshakeTimeout
}
if !option.ForceHttp3 {
option.ForceHttp3 = clientOption.ForceHttp3
}
if !option.ForceHttp1 {
option.ForceHttp1 = clientOption.ForceHttp1
}
if !option.DisCookie {
option.DisCookie = clientOption.DisCookie
}
if !option.DisDecode {
option.DisDecode = clientOption.DisDecode
}
if !option.Bar {
option.Bar = clientOption.Bar
}
if !option.Stream {
option.Stream = clientOption.Stream
}
}
func (obj *Client) newRequestOption(option RequestOption) (RequestOption, error) {
merge(&option, obj.ClientOption)
if option.MaxRetries < 0 {
option.MaxRetries = 0
}
if option.UserAgent == "" {
option.UserAgent = obj.ClientOption.UserAgent
}
if option.DisCookie {
option.Jar = nil
}
if option.DisProxy {
option.Proxy = ""
}
if option.Spec == "" {
option.Spec = "16030106f2010006ee03039a2b98d81139db0e128ea09eff6874549c219b543fb6dbaa7e4dbfe9e31602c620ce04c4026f019442affade7fed8ba66e022e186f77f1c670fd992f33c0143f120020aaaa130113021303c02bc02fc02cc030cca9cca8c013c014009c009d002f0035010006851a1a00000010000e000c02683208687474702f312e31002b000706dada03040303002d00020101000d0012001004030804040105030805050108060601001b0003020002ff0100010000230000000a000c000afafa11ec001d001700180000000e000c0000096c6f63616c686f7374003304ef04edfafa00010011ec04c06903195f3660633741f9f5ae64d05a316ac8e717582adb9e58c5c242ba306c99ca8f68c15f261245f9141812383c9265f7d0b5c44a5e0d7633f4f40ab8e820ec01bb6cc74e6ab3168e66b40cc4cd37e96e286b4080552b8b0217f786b7c1a0088fb613cc84471b17a33fbcc68db151df387907a1cf3fb14a0f45c6b84608db5b103131b537255c09559cf1940c3980a7f37959a7f95d32c49923600c76c616af238c579361e1c6a20c251d3d42a50e182ad54b1e5d54a57fe6986e64142815b9478cca8066c9bdcc0eb9022ebe05b0ebd53e7d146761d81aee41cd377611699c536a444d300c152994bfeef3cfb4736cb3d57d683269c1e3c001fba2ac220b2c993cec410f6fa5104d1bcde21c46a9b0be8ab7b51aba15f1745ebbd0a0d3a5224170b3bce456c157937e43390b733375bb96601667f5b36888f9520931bead48bae4723d9ed40af2680746e27eee4328503a280ee8846b37803d6206e0f5248bea4ca4a53ca4e1afdd2b84bce0c83260333bc9b38b86486fb48e18d1ce9187b1b6332b2f4145eca38122ac363210137f52140a57b7976b609d739844fa61f21c1e3c300f3434bc3f8b6856994847e2c9b0f20a24b976f9d552b153246db69f30d4a95301b933b0ba9d48402ddb7863cb4f1923a2c33021fd68634a387bf0f76d87f01b35b6182dd10fe9c14b8e548d7988388308b08ff1585ba18a7615737857a7c23c24ee9b3a2ab1915be18b233acd354c7c6513b8ea617a5cf299f34139756cc1df524292c43ee3364990961b2490ae204634a4461b53c95a11d214503985f27ab85bc7c179ab1ba37a828312cabea8cfc5088616386a83e566279a0a5517b60aca4ec6c30a32191dca3cbb7d33ae5087bbdbab5c42e6293b63ad8e35311d459e1ce57037e65e96283e449c3e012051d247653197834c42613ac377a950607c98cbd5a79fef948d18e99758e12d31d13231e638cfb183623346b231a443f56533d444c7204a63479e4efb34ef97597d858915a8a10a32aa78824c9d2993741176da643be1c6c4d91b6511055b098477e7a3c5b5c312cf7bb4ef5905fd741375e62c8ce942a2117bbe707fcc9871e59c0687507862f3634c871885949fce97612793a30a155e84ac503dc519816a13772c50e1167a7031cb2c8187913108f9a26e55958fd19a6e1ef18ed53a70f1c13d01d71d3b40a22413852c9982daac4ae8071966016c38a60bd5c0258c32b882740c6ed5252093c91e51c50cf037d4f5cb6ca610672710f7ca77b0a76039a9968e368a6b243ee4ca7632855cb568c73f01764c4944fc5879d2c52d7992840863c057db2efec658eeb2a73e02bd62617438d9192911bac1f6b0e55cb38255417af20000d69378c857bb278156f16a684200125906b6c22f3d505bc9e76d75fac3a009332ff98fe6baabe3941cab5271c6d2c0ebc993b944c49bd437353019d1b24d10390e45fa87ad77b329a9025933a11af2af0da44d3ed761722c94d8053242f537624113d7bc0155600573301bd2217c6c481ce63b0944b052c97bcb9d3349258257ff33cccf963a6945119ecab21c25051ce02548f642e0ec1ffd392d60facfdf76bfb7274363b62979231f4996362c85d5ba19d2cab7019750b3443565436867a53b71d875eba3282e6d0ee22076d6b97b7c6c556ae216e8bc1bc9f202ce94c763bfe9afc105fca9372dec2e286a001d00200ee8ac33f1ea3153f6b4a06ab71d21b7ce7955ce64ccfc66b7ec8077d02ffd18fe0d00fa00000100018b00206cada2aa48ee4478c40adad21f147d6bc90d13f6889a9b8a58a02536585a261f00d09306c85aab2a6e424b658f3cd9d1c46f35020839287259d3be605ff97faea0d87b9f7f96529661f08cf3f3899db8e805ee7405e2f9b6abd99bc4f6fa5f99b1ed442ebe53c5b10451c93d1221f662783efc3cc8fcf135ed935bcf02ec32251dd09705f191bd7959afbab5619d8e63cb634a259dd63d1b0e42225ae8c08b5b1620cd59d914857e9f1e8a3b7b892863bdaa05429922d75583059641468d8fc51c01e977a69d3a51d714cd5cceea9a5f404ce4a285fd6647931ed8b1c12db027328f214afdbe2c8102b46fe041b553f8670b00050005010000000044cd0005000302683200170000000b0002010000120000caca000100@@505249202a20485454502f322e300d0a0d0a534d0d0a0d0a00001804000000000000010001000000020000000000040060000000060004000000000408000000000000ef00010001d401250000000180000000ff82418aa0e41d139d09b8f3efbf87845887a47e561cc5801f40874148b1275ad1ffb9fe749d3fd4372ed83aa4fe7efbc1fcbefff3f4a7f388e79a82a97a7b0f497f9fbef07f21659fe7e94fe6f4f61e935b4ff3f7de0fe42cb3fcff408b4148b1275ad1ad49e33505023f30408d4148b1275ad1ad5d034ca7b29f07226d61634f53224092b6b9ac1c8558d520a4b6c2ad617b5a54251f01317ad9d07f66a281b0dae053fad0321aa49d13fda992a49685340c8a6adca7e28104416e277fb521aeba0bc8b1e632586d975765c53facd8f7e8cff4a506ea5531149d4ffda97a7b0f49580b2cae05c0b814dc394761986d975765cf53e5497ca589d34d1f43aeba0c41a4c7a98f33a69a3fdf9a68fa1d75d0620d263d4c79a68fbed00177fe8d48e62b03ee697e8d48e62b1e0b1d7f46a4731581d754df5f2c7cfdf6800bbdf43aeba0c41a4c7a9841a6a8b22c5f249c754c5fbef046cfdf6800bbbf408a4148b4a549275906497f83a8f517408a4148b4a549275a93c85f86a87dcd30d25f408a4148b4a549275ad416cf023f31408a4148b4a549275a42a13f8690e4b692d49f50929bd9abfa5242cb40d25fa523b3e94f684c9f518cf73ad7b4fd7b9fefb4005dff4086aec31ec327d785b6007d286f"
}
return option, nil
}