github.com/gospider007/requests@v0.0.0-20240506025355-c73d46169a23/option.go (about) 1 package requests 2 3 import ( 4 "context" 5 "io" 6 "net" 7 "net/http" 8 "net/url" 9 "time" 10 11 "github.com/gospider007/gtls" 12 "github.com/gospider007/ja3" 13 "github.com/gospider007/websocket" 14 ) 15 16 // Connection Management Options 17 type ClientOption struct { 18 Ja3Spec ja3.Ja3Spec //custom ja3Spec,use ja3.CreateSpecWithStr or ja3.CreateSpecWithId create 19 H2Ja3Spec ja3.H2Ja3Spec //h2 fingerprint 20 Proxy string //proxy,support https,http,socks5 21 ForceHttp1 bool //force use http1 send requests 22 Ja3 bool //enable ja3 fingerprint 23 DisCookie bool //disable cookies 24 DisDecode bool //disable auto decode 25 DisUnZip bool //disable auto zip decode 26 DisAlive bool //disable keepalive 27 Bar bool ////enable bar display 28 OptionCallBack func(ctx context.Context, option *RequestOption) error //option callback,if error is returnd, break request 29 ResultCallBack func(ctx context.Context, option *RequestOption, response *Response) error //result callback,if error is returnd,next errCallback 30 ErrCallBack func(ctx context.Context, option *RequestOption, response *Response, err error) error //error callback,if error is returnd,break request 31 RequestCallBack func(ctx context.Context, request *http.Request, response *http.Response) error //request and response callback,if error is returnd,reponse is error 32 MaxRetries int //try num 33 MaxRedirect int //redirect num ,<0 no redirect,==0 no limit 34 Headers any //default headers 35 Timeout time.Duration //request timeout 36 ResponseHeaderTimeout time.Duration //ResponseHeaderTimeout ,default:300 37 TlsHandshakeTimeout time.Duration //tls timeout,default:15 38 39 //network card ip 40 DialTimeout time.Duration //dial tcp timeout,default:15 41 KeepAlive time.Duration //keepalive,default:30 42 LocalAddr *net.TCPAddr 43 Dns *net.UDPAddr //dns 44 AddrType gtls.AddrType //dns parse addr type 45 Jar *Jar //custom cookies 46 47 //other option 48 GetProxy func(ctx context.Context, url *url.URL) (string, error) //proxy callback:support https,http,socks5 proxy 49 GetAddrType func(host string) gtls.AddrType 50 } 51 52 // Options for sending requests 53 type RequestOption struct { 54 Ja3Spec ja3.Ja3Spec //custom ja3Spec,use ja3.CreateSpecWithStr or ja3.CreateSpecWithId create 55 H2Ja3Spec ja3.H2Ja3Spec //custom h2 fingerprint 56 Proxy string //proxy,support http,https,socks5,example:http://127.0.0.1:7005 57 ForceHttp1 bool //force use http1 send requests 58 Ja3 bool //enable ja3 fingerprint 59 DisCookie bool //disable cookies,not use cookies 60 DisDecode bool //disable auto decode 61 DisUnZip bool //disable auto zip decode 62 DisAlive bool //disable keepalive 63 Bar bool //enable bar display 64 OptionCallBack func(ctx context.Context, option *RequestOption) error //option callback,if error is returnd, break request 65 ResultCallBack func(ctx context.Context, option *RequestOption, response *Response) error //result callback,if error is returnd,next errCallback 66 ErrCallBack func(ctx context.Context, option *RequestOption, response *Response, err error) error //error callback,if error is returnd,break request 67 RequestCallBack func(ctx context.Context, request *http.Request, response *http.Response) error //request and response callback,if error is returnd,reponse is error 68 69 MaxRetries int //try num 70 MaxRedirect int //redirect num ,<0 no redirect,==0 no limit 71 Headers any //request headers:json,map,header 72 Timeout time.Duration //request timeout 73 ResponseHeaderTimeout time.Duration //ResponseHeaderTimeout ,default:300 74 TlsHandshakeTimeout time.Duration 75 76 //network card ip 77 DialTimeout time.Duration //dial tcp timeout,default:15 78 KeepAlive time.Duration //keepalive,default:30 79 LocalAddr *net.TCPAddr 80 Dns *net.UDPAddr //dns 81 AddrType gtls.AddrType //dns parse addr type //tls timeout,default:15 82 Jar *Jar //custom cookies 83 84 // other option 85 Method string //method 86 Url *url.URL 87 Host string 88 Referer string //set headers referer value 89 ContentType string //headers Content-Type value 90 Cookies any // cookies,support :json,map,str,http.Header 91 92 Params any //url params,join url query,json,map 93 Json any //send application/json,support io.Reader,:string,[]bytes,json,map 94 Data any //send application/x-www-form-urlencoded, support io.Reader, string,[]bytes,json,map 95 Form any //send multipart/form-data,file upload,support io.Reader, json,map 96 Text any //send text/xml,support: io.Reader, string,[]bytes,json,map 97 Body any //not setting context-type,support io.Reader, string,[]bytes,json,map 98 99 Stream bool //disable auto read 100 WsOption websocket.Option //websocket option 101 DisProxy bool //force disable proxy 102 once bool 103 client *Client 104 } 105 106 func (obj *RequestOption) Client() *Client { 107 return obj.client 108 } 109 110 // Upload files with form-data, 111 type File struct { 112 FileName string 113 ContentType string 114 Content any 115 } 116 117 func (obj *RequestOption) initBody(ctx context.Context) (io.Reader, error) { 118 if obj.Body != nil { 119 body, _, _, err := obj.newBody(obj.Body, readType) 120 if err != nil || body == nil { 121 return nil, err 122 } 123 return body, err 124 } else if obj.Form != nil { 125 var orderMap *OrderMap 126 _, orderMap, _, err := obj.newBody(obj.Form, mapType) 127 if err != nil { 128 return nil, err 129 } 130 if orderMap == nil { 131 return nil, nil 132 } 133 body, contentType, once, err := orderMap.parseForm(ctx) 134 if err != nil { 135 return nil, err 136 } 137 obj.once = once 138 if obj.ContentType == "" { 139 obj.ContentType = contentType 140 } 141 if body == nil { 142 return nil, nil 143 } 144 return body, nil 145 } else if obj.Data != nil { 146 body, orderMap, _, err := obj.newBody(obj.Data, mapType) 147 if err != nil { 148 return body, err 149 } 150 if obj.ContentType == "" { 151 obj.ContentType = "application/x-www-form-urlencoded" 152 } 153 if body != nil { 154 return body, nil 155 } 156 if orderMap == nil { 157 return nil, nil 158 } 159 body2 := orderMap.parseData() 160 if body2 == nil { 161 return nil, nil 162 } 163 return body2, nil 164 } else if obj.Json != nil { 165 body, _, _, err := obj.newBody(obj.Json, readType) 166 if err != nil { 167 return nil, err 168 } 169 if obj.ContentType == "" { 170 obj.ContentType = "application/json" 171 } 172 if body == nil { 173 return nil, nil 174 } 175 return body, nil 176 } else if obj.Text != nil { 177 body, _, _, err := obj.newBody(obj.Text, readType) 178 if err != nil { 179 return nil, err 180 } 181 if obj.ContentType == "" { 182 obj.ContentType = "text/plain" 183 } 184 if body == nil { 185 return nil, nil 186 } 187 return body, nil 188 } else { 189 return nil, nil 190 } 191 } 192 func (obj *RequestOption) initParams() (*url.URL, error) { 193 baseUrl := cloneUrl(obj.Url) 194 if obj.Params == nil { 195 return baseUrl, nil 196 } 197 _, dataMap, _, err := obj.newBody(obj.Params, mapType) 198 if err != nil { 199 return nil, err 200 } 201 query := dataMap.parseParams().String() 202 if query == "" { 203 return baseUrl, nil 204 } 205 pquery := baseUrl.Query().Encode() 206 if pquery == "" { 207 baseUrl.RawQuery = query 208 } else { 209 baseUrl.RawQuery = pquery + "&" + query 210 } 211 return baseUrl, nil 212 } 213 func (obj *Client) newRequestOption(option RequestOption) RequestOption { 214 // start 215 if !option.Ja3Spec.IsSet() { 216 option.Ja3Spec = obj.option.Ja3Spec 217 } 218 if !option.H2Ja3Spec.IsSet() { 219 option.H2Ja3Spec = obj.option.H2Ja3Spec 220 } 221 if option.Proxy == "" { 222 option.Proxy = obj.option.Proxy 223 } 224 if !option.ForceHttp1 { 225 option.ForceHttp1 = obj.option.ForceHttp1 226 } 227 if !option.Ja3 { 228 option.Ja3 = obj.option.Ja3 229 } 230 if !option.DisCookie { 231 option.DisCookie = obj.option.DisCookie 232 } 233 if !option.DisDecode { 234 option.DisDecode = obj.option.DisDecode 235 } 236 if !option.DisUnZip { 237 option.DisUnZip = obj.option.DisUnZip 238 } 239 if !option.DisAlive { 240 option.DisAlive = obj.option.DisAlive 241 } 242 if !option.Bar { 243 option.Bar = obj.option.Bar 244 } 245 if option.OptionCallBack == nil { 246 option.OptionCallBack = obj.option.OptionCallBack 247 } 248 if option.ResultCallBack == nil { 249 option.ResultCallBack = obj.option.ResultCallBack 250 } 251 if option.ErrCallBack == nil { 252 option.ErrCallBack = obj.option.ErrCallBack 253 } 254 if option.RequestCallBack == nil { 255 option.RequestCallBack = obj.option.RequestCallBack 256 } 257 if option.MaxRetries == 0 { 258 option.MaxRetries = obj.option.MaxRetries 259 } 260 if option.MaxRedirect == 0 { 261 option.MaxRedirect = obj.option.MaxRedirect 262 } 263 if option.Headers == nil { 264 option.Headers = obj.option.Headers 265 } 266 if option.Timeout == 0 { 267 option.Timeout = obj.option.Timeout 268 } 269 if option.ResponseHeaderTimeout == 0 { 270 option.ResponseHeaderTimeout = obj.option.ResponseHeaderTimeout 271 } 272 if option.TlsHandshakeTimeout == 0 { 273 option.TlsHandshakeTimeout = obj.option.TlsHandshakeTimeout 274 } 275 if option.DialTimeout == 0 { 276 option.DialTimeout = obj.option.DialTimeout 277 } 278 if option.KeepAlive == 0 { 279 option.KeepAlive = obj.option.KeepAlive 280 } 281 if option.LocalAddr == nil { 282 option.LocalAddr = obj.option.LocalAddr 283 } 284 if option.Dns == nil { 285 option.Dns = obj.option.Dns 286 } 287 if option.AddrType == 0 { 288 option.AddrType = obj.option.AddrType 289 } 290 if option.Jar == nil { 291 option.Jar = obj.option.Jar 292 } 293 //end 294 if option.MaxRetries < 0 { 295 option.MaxRetries = 0 296 } 297 if !option.Ja3Spec.IsSet() && option.Ja3 { 298 option.Ja3Spec = ja3.DefaultJa3Spec() 299 } 300 if option.DisCookie { 301 option.Jar = nil 302 } 303 if option.DisProxy { 304 option.Proxy = "" 305 } 306 return option 307 }