mirror of
https://github.com/gospider007/requests.git
synced 2025-12-24 13:57:52 +08:00
update docs info
This commit is contained in:
60
client.go
60
client.go
@@ -12,28 +12,29 @@ import (
|
||||
"github.com/gospider007/ja3"
|
||||
)
|
||||
|
||||
// Connection Management Options
|
||||
type ClientOption struct {
|
||||
ForceHttp1 bool //force use http1 send requests
|
||||
OrderHeaders []string //order headers with http1
|
||||
Ja3 bool //enable ja3 fingerprint
|
||||
Ja3Spec ja3.Ja3Spec //custom ja3Spec,use ja3.CreateSpecWithStr or ja3.CreateSpecWithId create
|
||||
H2Ja3Spec ja3.H2Ja3Spec //h2 fingerprint
|
||||
Proxy string //proxy,support https,http,socks5
|
||||
DisCookie bool //disable cookies
|
||||
DisDecode bool //disable auto decode
|
||||
DisUnZip bool //disable auto zip decode
|
||||
DisAlive bool //disable keepalive
|
||||
Bar bool ////enable bar display
|
||||
Timeout time.Duration //request timeout
|
||||
OptionCallBack func(context.Context, *Client, *RequestOption) error //option callback,if error is returnd, break request
|
||||
ResultCallBack func(context.Context, *Client, *Response) error //result callback,if error is returnd,next errCallback
|
||||
ErrCallBack func(context.Context, *Client, error) error //error callback,if error is returnd,break request
|
||||
RequestCallBack func(context.Context, *http.Request, *http.Response) error //request and response callback,if error is returnd,reponse is error
|
||||
TryNum int //try num
|
||||
MaxRedirectNum int //redirect num ,<0 no redirect,==0 no limit
|
||||
Headers any //default headers
|
||||
ResponseHeaderTimeout time.Duration //ResponseHeaderTimeout ,default:30
|
||||
TlsHandshakeTimeout time.Duration //tls timeout,default:15
|
||||
ForceHttp1 bool //force use http1 send requests
|
||||
OrderHeaders []string //order headers with http1
|
||||
Ja3 bool //enable ja3 fingerprint
|
||||
Ja3Spec ja3.Ja3Spec //custom ja3Spec,use ja3.CreateSpecWithStr or ja3.CreateSpecWithId create
|
||||
H2Ja3Spec ja3.H2Ja3Spec //h2 fingerprint
|
||||
Proxy string //proxy,support https,http,socks5
|
||||
DisCookie bool //disable cookies
|
||||
DisDecode bool //disable auto decode
|
||||
DisUnZip bool //disable auto zip decode
|
||||
DisAlive bool //disable keepalive
|
||||
Bar bool ////enable bar display
|
||||
Timeout time.Duration //request timeout
|
||||
OptionCallBack func(ctx context.Context, client *Client, option *RequestOption) error //option callback,if error is returnd, break request
|
||||
ResultCallBack func(ctx context.Context, client *Client, response *Response) error //result callback,if error is returnd,next errCallback
|
||||
ErrCallBack func(ctx context.Context, client *Client, err error) error //error callback,if error is returnd,break request
|
||||
RequestCallBack func(ctx context.Context, request *http.Request, response *http.Response) error //request and response callback,if error is returnd,reponse is error
|
||||
TryNum int //try num
|
||||
MaxRedirectNum int //redirect num ,<0 no redirect,==0 no limit
|
||||
Headers any //default headers
|
||||
ResponseHeaderTimeout time.Duration //ResponseHeaderTimeout ,default:30
|
||||
TlsHandshakeTimeout time.Duration //tls timeout,default:15
|
||||
|
||||
//network card ip
|
||||
DialTimeout time.Duration //dial tcp timeout,default:15
|
||||
@@ -44,8 +45,10 @@ type ClientOption struct {
|
||||
Jar *Jar //custom cookies
|
||||
|
||||
GetProxy func(ctx context.Context, url *url.URL) (string, error) //proxy callback:support https,http,socks5 proxy
|
||||
GetAddrType func(string) gtls.AddrType
|
||||
GetAddrType func(host string) gtls.AddrType
|
||||
}
|
||||
|
||||
// Connection Management
|
||||
type Client struct {
|
||||
forceHttp1 bool
|
||||
orderHeaders []string
|
||||
@@ -61,7 +64,7 @@ type Client struct {
|
||||
requestCallBack func(context.Context, *http.Request, *http.Response) error
|
||||
|
||||
optionCallBack func(context.Context, *Client, *RequestOption) error
|
||||
resultCallBack func(context.Context, *Client, *Response) error
|
||||
resultCallBack func(ctx context.Context, client *Client, response *Response) error
|
||||
errCallBack func(context.Context, *Client, error) error
|
||||
|
||||
timeout time.Duration
|
||||
@@ -85,6 +88,9 @@ type Client struct {
|
||||
addrType gtls.AddrType
|
||||
}
|
||||
|
||||
var defaultClient, _ = NewClient(nil)
|
||||
|
||||
// New Connection Management
|
||||
func NewClient(preCtx context.Context, options ...ClientOption) (*Client, error) {
|
||||
if preCtx == nil {
|
||||
preCtx = context.TODO()
|
||||
@@ -160,21 +166,29 @@ func NewClient(preCtx context.Context, options ...ClientOption) (*Client, error)
|
||||
result.h2Ja3Spec = option.H2Ja3Spec
|
||||
return result, err
|
||||
}
|
||||
|
||||
// Modifying the client's proxy
|
||||
func (obj *Client) SetProxy(proxyUrl string) (err error) {
|
||||
obj.proxy, err = gtls.VerifyProxy(proxyUrl)
|
||||
return
|
||||
}
|
||||
|
||||
// Modify the proxy method of the client
|
||||
func (obj *Client) SetGetProxy(getProxy func(ctx context.Context, url *url.URL) (string, error)) {
|
||||
obj.transport.setGetProxy(getProxy)
|
||||
}
|
||||
|
||||
// Close idle connections. If the connection is in use, wait until it ends before closing
|
||||
func (obj *Client) CloseIdleConnections() {
|
||||
obj.transport.closeIdleConnections()
|
||||
}
|
||||
|
||||
// Close the connection, even if it is in use, it will be closed
|
||||
func (obj *Client) CloseConnections() {
|
||||
obj.transport.closeConnections()
|
||||
}
|
||||
|
||||
// Close the client and cannot be used again after shutdown
|
||||
func (obj *Client) Close() {
|
||||
obj.CloseConnections()
|
||||
obj.cnl()
|
||||
|
||||
59
cookies.go
59
cookies.go
@@ -2,12 +2,68 @@ package requests
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gospider007/gson"
|
||||
)
|
||||
|
||||
// 支持json,map,[]string,http.Header,string
|
||||
// cookies
|
||||
type Cookies []*http.Cookie
|
||||
|
||||
// return cookies with string,join with '; '
|
||||
func (obj Cookies) String() string {
|
||||
cooks := []string{}
|
||||
for _, cook := range obj {
|
||||
cooks = append(cooks, fmt.Sprintf("%s=%s", cook.Name, cook.Value))
|
||||
}
|
||||
return strings.Join(cooks, "; ")
|
||||
}
|
||||
|
||||
// get cookies by name
|
||||
func (obj Cookies) Gets(name string) Cookies {
|
||||
var result Cookies
|
||||
for _, cook := range obj {
|
||||
if cook.Name == name {
|
||||
result = append(result, cook)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// get cookie by name
|
||||
func (obj Cookies) Get(name string) *http.Cookie {
|
||||
vals := obj.Gets(name)
|
||||
if i := len(vals); i == 0 {
|
||||
return nil
|
||||
} else {
|
||||
return vals[i-1]
|
||||
}
|
||||
}
|
||||
|
||||
// get cookie values by name, return []string
|
||||
func (obj Cookies) GetVals(name string) []string {
|
||||
var result []string
|
||||
for _, cook := range obj {
|
||||
if cook.Name == name {
|
||||
result = append(result, cook.Value)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// get cookie value by name,return string
|
||||
func (obj Cookies) GetVal(name string) string {
|
||||
vals := obj.GetVals(name)
|
||||
if i := len(vals); i == 0 {
|
||||
return ""
|
||||
} else {
|
||||
return vals[i-1]
|
||||
}
|
||||
}
|
||||
|
||||
// read cookies or parse cookies,support json,map,[]string,http.Header,string
|
||||
func ReadCookies(val any) (Cookies, error) {
|
||||
switch cook := val.(type) {
|
||||
case *http.Cookie:
|
||||
@@ -33,6 +89,7 @@ func ReadCookies(val any) (Cookies, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// read set cookies or parse set cookies,support json,map,[]string,http.Header,string
|
||||
func ReadSetCookies(val any) (Cookies, error) {
|
||||
switch cook := val.(type) {
|
||||
case Cookies:
|
||||
|
||||
6
dial.go
6
dial.go
@@ -25,7 +25,7 @@ type DialClient struct {
|
||||
dnsIpData sync.Map
|
||||
dns *net.UDPAddr
|
||||
localAddr *net.TCPAddr
|
||||
getAddrType func(string) gtls.AddrType
|
||||
getAddrType func(host string) gtls.AddrType
|
||||
}
|
||||
type msgClient struct {
|
||||
time time.Time
|
||||
@@ -38,7 +38,7 @@ type DialOption struct {
|
||||
LocalAddr *net.TCPAddr //network card ip
|
||||
AddrType gtls.AddrType //first ip type
|
||||
Dns *net.UDPAddr
|
||||
GetAddrType func(string) gtls.AddrType
|
||||
GetAddrType func(host string) gtls.AddrType
|
||||
}
|
||||
type DialerOption struct {
|
||||
DialTimeout time.Duration
|
||||
@@ -46,7 +46,7 @@ type DialerOption struct {
|
||||
LocalAddr *net.TCPAddr //network card ip
|
||||
AddrType gtls.AddrType //first ip type
|
||||
Dns *net.UDPAddr
|
||||
GetAddrType func(string) gtls.AddrType
|
||||
GetAddrType func(host string) gtls.AddrType
|
||||
}
|
||||
|
||||
func NewDialer(option DialerOption) *net.Dialer {
|
||||
|
||||
12
jar.go
12
jar.go
@@ -9,10 +9,12 @@ import (
|
||||
"golang.org/x/net/publicsuffix"
|
||||
)
|
||||
|
||||
// cookies jar
|
||||
type Jar struct {
|
||||
jar *cookiejar.Jar
|
||||
}
|
||||
|
||||
// new cookies jar
|
||||
func NewJar() *Jar {
|
||||
jar, _ := cookiejar.New(nil)
|
||||
return &Jar{
|
||||
@@ -20,19 +22,25 @@ func NewJar() *Jar {
|
||||
}
|
||||
}
|
||||
|
||||
// get cookies
|
||||
func (obj *Client) GetCookies(href string) (Cookies, error) {
|
||||
return obj.jar.GetCookies(href)
|
||||
}
|
||||
|
||||
// set cookies
|
||||
func (obj *Client) SetCookies(href string, cookies ...any) error {
|
||||
return obj.jar.SetCookies(href, cookies...)
|
||||
}
|
||||
|
||||
// clear cookies
|
||||
func (obj *Client) ClearCookies() {
|
||||
if obj.client.Jar != nil {
|
||||
obj.jar.ClearCookies()
|
||||
obj.client.Jar = obj.jar.jar
|
||||
}
|
||||
}
|
||||
|
||||
// Get cookies
|
||||
func (obj *Jar) GetCookies(href string) (Cookies, error) {
|
||||
if obj.jar == nil {
|
||||
return nil, errors.New("jar is nil")
|
||||
@@ -43,6 +51,8 @@ func (obj *Jar) GetCookies(href string) (Cookies, error) {
|
||||
}
|
||||
return obj.jar.Cookies(u), nil
|
||||
}
|
||||
|
||||
// Set cookies
|
||||
func (obj *Jar) SetCookies(href string, cookies ...any) error {
|
||||
if obj.jar == nil {
|
||||
return errors.New("jar is nil")
|
||||
@@ -74,6 +84,8 @@ func (obj *Jar) SetCookies(href string, cookies ...any) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Clear cookies
|
||||
func (obj *Jar) ClearCookies() {
|
||||
jar, _ := cookiejar.New(nil)
|
||||
obj.jar = jar
|
||||
|
||||
43
option.go
43
option.go
@@ -17,27 +17,28 @@ import (
|
||||
"github.com/gospider007/websocket"
|
||||
)
|
||||
|
||||
// Options for sending requests
|
||||
type RequestOption struct {
|
||||
ForceHttp1 bool //force use http1 send requests
|
||||
OrderHeaders []string //order headers with http1
|
||||
Ja3 bool //enable ja3 fingerprint
|
||||
Ja3Spec ja3.Ja3Spec //custom ja3Spec,use ja3.CreateSpecWithStr or ja3.CreateSpecWithId create
|
||||
H2Ja3Spec ja3.H2Ja3Spec //custom h2 fingerprint
|
||||
Proxy string //proxy,support http,https,socks5,example:http://127.0.0.1:7005
|
||||
DisCookie bool //disable cookies,not use cookies
|
||||
DisDecode bool //disable auto decode
|
||||
DisUnZip bool //disable auto zip decode
|
||||
DisAlive bool //disable keepalive
|
||||
Bar bool //enable bar display
|
||||
Timeout time.Duration //request timeout
|
||||
OptionCallBack func(context.Context, *Client, *RequestOption) error //option callback,if error is returnd, break request
|
||||
ResultCallBack func(context.Context, *Client, *Response) error //result callback,if error is returnd,next errCallback
|
||||
ErrCallBack func(context.Context, *Client, error) error //error callback,if error is returnd,break request
|
||||
RequestCallBack func(context.Context, *http.Request, *http.Response) error //request and response callback,if error is returnd,reponse is error
|
||||
TryNum int //try num
|
||||
MaxRedirectNum int //redirect num ,<0 no redirect,==0 no limit
|
||||
Headers any //request headers:json,map,header
|
||||
ResponseHeaderTimeout time.Duration //ResponseHeaderTimeout ,default:30
|
||||
ForceHttp1 bool //force use http1 send requests
|
||||
OrderHeaders []string //order headers with http1
|
||||
Ja3 bool //enable ja3 fingerprint
|
||||
Ja3Spec ja3.Ja3Spec //custom ja3Spec,use ja3.CreateSpecWithStr or ja3.CreateSpecWithId create
|
||||
H2Ja3Spec ja3.H2Ja3Spec //custom h2 fingerprint
|
||||
Proxy string //proxy,support http,https,socks5,example:http://127.0.0.1:7005
|
||||
DisCookie bool //disable cookies,not use cookies
|
||||
DisDecode bool //disable auto decode
|
||||
DisUnZip bool //disable auto zip decode
|
||||
DisAlive bool //disable keepalive
|
||||
Bar bool //enable bar display
|
||||
Timeout time.Duration //request timeout
|
||||
OptionCallBack func(ctx context.Context, client *Client, option *RequestOption) error //option callback,if error is returnd, break request
|
||||
ResultCallBack func(ctx context.Context, client *Client, response *Response) error //result callback,if error is returnd,next errCallback
|
||||
ErrCallBack func(ctx context.Context, client *Client, err error) error //error callback,if error is returnd,break request
|
||||
RequestCallBack func(ctx context.Context, request *http.Request, response *http.Response) error //request and response callback,if error is returnd,reponse is error
|
||||
TryNum int //try num
|
||||
MaxRedirectNum int //redirect num ,<0 no redirect,==0 no limit
|
||||
Headers any //request headers:json,map,header
|
||||
ResponseHeaderTimeout time.Duration //ResponseHeaderTimeout ,default:30
|
||||
TlsHandshakeTimeout time.Duration
|
||||
|
||||
//network card ip
|
||||
@@ -71,6 +72,8 @@ type RequestOption struct {
|
||||
// body io.Reader
|
||||
once bool
|
||||
}
|
||||
|
||||
// Upload files with form-data
|
||||
type File struct {
|
||||
Key string
|
||||
Val []byte
|
||||
|
||||
256
requests.go
256
requests.go
@@ -49,116 +49,230 @@ type reqCtxData struct {
|
||||
localAddr *net.TCPAddr //network card ip
|
||||
addrType gtls.AddrType //first ip type
|
||||
dns *net.UDPAddr
|
||||
|
||||
isNewConn bool
|
||||
}
|
||||
|
||||
func Get(preCtx context.Context, href string, options ...RequestOption) (resp *Response, err error) {
|
||||
client, _ := NewClient(preCtx, ClientOption{DisAlive: true})
|
||||
resp, err = client.Request(preCtx, http.MethodGet, href, options...)
|
||||
if err != nil || resp == nil || !resp.oneceAlive() {
|
||||
client.Close()
|
||||
}
|
||||
return
|
||||
// sends a GET request and returns the response.
|
||||
// It takes the following parameters:
|
||||
// - preCtx: A context object used to control the timeout and cancellation of the request.
|
||||
// - href: The URL to be requested.
|
||||
// - options: A variadic parameter for optional request options.
|
||||
//
|
||||
// The function returns a tuple of the response object and an error object (if any).
|
||||
func Get(ctx context.Context, href string, options ...RequestOption) (resp *Response, err error) {
|
||||
return defaultClient.Request(ctx, http.MethodGet, href, options...)
|
||||
}
|
||||
func Head(preCtx context.Context, href string, options ...RequestOption) (resp *Response, err error) {
|
||||
client, _ := NewClient(preCtx, ClientOption{DisAlive: true})
|
||||
resp, err = client.Request(preCtx, http.MethodHead, href, options...)
|
||||
if err != nil || resp == nil || !resp.oneceAlive() {
|
||||
client.Close()
|
||||
}
|
||||
return
|
||||
|
||||
// sends a Head request and returns the response.
|
||||
// It takes the following parameters:
|
||||
// - preCtx: A context object used to control the timeout and cancellation of the request.
|
||||
// - href: The URL to be requested.
|
||||
// - options: A variadic parameter for optional request options.
|
||||
//
|
||||
// The function returns a tuple of the response object and an error object (if any).
|
||||
func Head(ctx context.Context, href string, options ...RequestOption) (resp *Response, err error) {
|
||||
return defaultClient.Request(ctx, http.MethodHead, href, options...)
|
||||
}
|
||||
func Post(preCtx context.Context, href string, options ...RequestOption) (resp *Response, err error) {
|
||||
client, _ := NewClient(preCtx, ClientOption{DisAlive: true})
|
||||
resp, err = client.Request(preCtx, http.MethodPost, href, options...)
|
||||
if err != nil || resp == nil || !resp.oneceAlive() {
|
||||
client.Close()
|
||||
}
|
||||
return
|
||||
|
||||
// sends a Post request and returns the response.
|
||||
// It takes the following parameters:
|
||||
// - preCtx: A context object used to control the timeout and cancellation of the request.
|
||||
// - href: The URL to be requested.
|
||||
// - options: A variadic parameter for optional request options.
|
||||
//
|
||||
// The function returns a tuple of the response object and an error object (if any).
|
||||
func Post(ctx context.Context, href string, options ...RequestOption) (resp *Response, err error) {
|
||||
return defaultClient.Request(ctx, http.MethodPost, href, options...)
|
||||
}
|
||||
func Put(preCtx context.Context, href string, options ...RequestOption) (resp *Response, err error) {
|
||||
client, _ := NewClient(preCtx, ClientOption{DisAlive: true})
|
||||
resp, err = client.Request(preCtx, http.MethodPut, href, options...)
|
||||
if err != nil || resp == nil || !resp.oneceAlive() {
|
||||
client.Close()
|
||||
}
|
||||
return
|
||||
|
||||
// sends a Put request and returns the response.
|
||||
// It takes the following parameters:
|
||||
// - preCtx: A context object used to control the timeout and cancellation of the request.
|
||||
// - href: The URL to be requested.
|
||||
// - options: A variadic parameter for optional request options.
|
||||
//
|
||||
// The function returns a tuple of the response object and an error object (if any).
|
||||
func Put(ctx context.Context, href string, options ...RequestOption) (resp *Response, err error) {
|
||||
return defaultClient.Request(ctx, http.MethodPut, href, options...)
|
||||
}
|
||||
func Patch(preCtx context.Context, href string, options ...RequestOption) (resp *Response, err error) {
|
||||
client, _ := NewClient(preCtx, ClientOption{DisAlive: true})
|
||||
resp, err = client.Request(preCtx, http.MethodPatch, href, options...)
|
||||
if err != nil || resp == nil || !resp.oneceAlive() {
|
||||
client.Close()
|
||||
}
|
||||
return
|
||||
|
||||
// sends a Patch request and returns the response.
|
||||
// It takes the following parameters:
|
||||
// - preCtx: A context object used to control the timeout and cancellation of the request.
|
||||
// - href: The URL to be requested.
|
||||
// - options: A variadic parameter for optional request options.
|
||||
//
|
||||
// The function returns a tuple of the response object and an error object (if any).
|
||||
func Patch(ctx context.Context, href string, options ...RequestOption) (resp *Response, err error) {
|
||||
return defaultClient.Request(ctx, http.MethodPatch, href, options...)
|
||||
}
|
||||
func Delete(preCtx context.Context, href string, options ...RequestOption) (resp *Response, err error) {
|
||||
client, _ := NewClient(preCtx, ClientOption{DisAlive: true})
|
||||
resp, err = client.Request(preCtx, http.MethodDelete, href, options...)
|
||||
if err != nil || resp == nil || !resp.oneceAlive() {
|
||||
client.Close()
|
||||
}
|
||||
return
|
||||
|
||||
// sends a Delete request and returns the response.
|
||||
// It takes the following parameters:
|
||||
// - preCtx: A context object used to control the timeout and cancellation of the request.
|
||||
// - href: The URL to be requested.
|
||||
// - options: A variadic parameter for optional request options.
|
||||
//
|
||||
// The function returns a tuple of the response object and an error object (if any).
|
||||
func Delete(ctx context.Context, href string, options ...RequestOption) (resp *Response, err error) {
|
||||
return defaultClient.Request(ctx, http.MethodDelete, href, options...)
|
||||
}
|
||||
func Connect(preCtx context.Context, href string, options ...RequestOption) (resp *Response, err error) {
|
||||
client, _ := NewClient(preCtx, ClientOption{DisAlive: true})
|
||||
resp, err = client.Request(preCtx, http.MethodConnect, href, options...)
|
||||
if err != nil || resp == nil || !resp.oneceAlive() {
|
||||
client.Close()
|
||||
}
|
||||
return
|
||||
|
||||
// sends a Connect request and returns the response.
|
||||
// It takes the following parameters:
|
||||
// - preCtx: A context object used to control the timeout and cancellation of the request.
|
||||
// - href: The URL to be requested.
|
||||
// - options: A variadic parameter for optional request options.
|
||||
//
|
||||
// The function returns a tuple of the response object and an error object (if any).
|
||||
func Connect(ctx context.Context, href string, options ...RequestOption) (resp *Response, err error) {
|
||||
return defaultClient.Request(ctx, http.MethodConnect, href, options...)
|
||||
}
|
||||
func Options(preCtx context.Context, href string, options ...RequestOption) (resp *Response, err error) {
|
||||
client, _ := NewClient(preCtx, ClientOption{DisAlive: true})
|
||||
resp, err = client.Request(preCtx, http.MethodOptions, href, options...)
|
||||
if err != nil || resp == nil || !resp.oneceAlive() {
|
||||
client.Close()
|
||||
}
|
||||
return
|
||||
|
||||
// sends a Options request and returns the response.
|
||||
// It takes the following parameters:
|
||||
// - preCtx: A context object used to control the timeout and cancellation of the request.
|
||||
// - href: The URL to be requested.
|
||||
// - options: A variadic parameter for optional request options.
|
||||
//
|
||||
// The function returns a tuple of the response object and an error object (if any).
|
||||
func Options(ctx context.Context, href string, options ...RequestOption) (resp *Response, err error) {
|
||||
return defaultClient.Request(ctx, http.MethodOptions, href, options...)
|
||||
}
|
||||
func Trace(preCtx context.Context, href string, options ...RequestOption) (resp *Response, err error) {
|
||||
client, _ := NewClient(preCtx, ClientOption{DisAlive: true})
|
||||
resp, err = client.Request(preCtx, http.MethodTrace, href, options...)
|
||||
if err != nil || resp == nil || !resp.oneceAlive() {
|
||||
client.Close()
|
||||
}
|
||||
return
|
||||
|
||||
// sends a Trace request and returns the response.
|
||||
// It takes the following parameters:
|
||||
// - preCtx: A context object used to control the timeout and cancellation of the request.
|
||||
// - href: The URL to be requested.
|
||||
// - options: A variadic parameter for optional request options.
|
||||
//
|
||||
// The function returns a tuple of the response object and an error object (if any).
|
||||
func Trace(ctx context.Context, href string, options ...RequestOption) (resp *Response, err error) {
|
||||
return defaultClient.Request(ctx, http.MethodTrace, href, options...)
|
||||
}
|
||||
|
||||
//Define a function named Request that takes in four parameters:
|
||||
//- preCtx: a context.Context object for setting request-related context information
|
||||
//- method: a string representing the request method (e.g., GET, POST)
|
||||
//- href: a string representing the URL link for the request
|
||||
//- options: a variadic parameter of type RequestOptions for setting specific options for the request
|
||||
|
||||
// Return a tuple of two values:
|
||||
// - resp: a pointer to a Response object containing information about the response of the request
|
||||
// - err: an error encountered during the request, which is nil if no error occurred
|
||||
func Request(preCtx context.Context, method string, href string, options ...RequestOption) (resp *Response, err error) {
|
||||
client, _ := NewClient(preCtx, ClientOption{DisAlive: true})
|
||||
resp, err = client.Request(preCtx, method, href, options...)
|
||||
if err != nil || resp == nil || !resp.oneceAlive() {
|
||||
client.Close()
|
||||
}
|
||||
return
|
||||
return defaultClient.Request(preCtx, method, href, options...)
|
||||
}
|
||||
|
||||
// sends a Get request and returns the response.
|
||||
// It takes the following parameters:
|
||||
// - preCtx: A context object used to control the timeout and cancellation of the request.
|
||||
// - href: The URL to be requested.
|
||||
// - options: A variadic parameter for optional request options.
|
||||
//
|
||||
// The function returns a tuple of the response object and an error object (if any).
|
||||
func (obj *Client) Get(preCtx context.Context, href string, options ...RequestOption) (*Response, error) {
|
||||
return obj.Request(preCtx, http.MethodGet, href, options...)
|
||||
}
|
||||
|
||||
// sends a Head request and returns the response.
|
||||
// It takes the following parameters:
|
||||
// - preCtx: A context object used to control the timeout and cancellation of the request.
|
||||
// - href: The URL to be requested.
|
||||
// - options: A variadic parameter for optional request options.
|
||||
//
|
||||
// The function returns a tuple of the response object and an error object (if any).
|
||||
func (obj *Client) Head(preCtx context.Context, href string, options ...RequestOption) (*Response, error) {
|
||||
return obj.Request(preCtx, http.MethodHead, href, options...)
|
||||
}
|
||||
|
||||
// sends a Post request and returns the response.
|
||||
// It takes the following parameters:
|
||||
// - preCtx: A context object used to control the timeout and cancellation of the request.
|
||||
// - href: The URL to be requested.
|
||||
// - options: A variadic parameter for optional request options.
|
||||
//
|
||||
// The function returns a tuple of the response object and an error object (if any).
|
||||
func (obj *Client) Post(preCtx context.Context, href string, options ...RequestOption) (*Response, error) {
|
||||
return obj.Request(preCtx, http.MethodPost, href, options...)
|
||||
}
|
||||
|
||||
// sends a Put request and returns the response.
|
||||
// It takes the following parameters:
|
||||
// - preCtx: A context object used to control the timeout and cancellation of the request.
|
||||
// - href: The URL to be requested.
|
||||
// - options: A variadic parameter for optional request options.
|
||||
//
|
||||
// The function returns a tuple of the response object and an error object (if any).
|
||||
func (obj *Client) Put(preCtx context.Context, href string, options ...RequestOption) (*Response, error) {
|
||||
return obj.Request(preCtx, http.MethodPut, href, options...)
|
||||
}
|
||||
|
||||
// sends a Patch request and returns the response.
|
||||
// It takes the following parameters:
|
||||
// - preCtx: A context object used to control the timeout and cancellation of the request.
|
||||
// - href: The URL to be requested.
|
||||
// - options: A variadic parameter for optional request options.
|
||||
//
|
||||
// The function returns a tuple of the response object and an error object (if any).
|
||||
func (obj *Client) Patch(preCtx context.Context, href string, options ...RequestOption) (*Response, error) {
|
||||
return obj.Request(preCtx, http.MethodPatch, href, options...)
|
||||
}
|
||||
|
||||
// sends a Delete request and returns the response.
|
||||
// It takes the following parameters:
|
||||
// - preCtx: A context object used to control the timeout and cancellation of the request.
|
||||
// - href: The URL to be requested.
|
||||
// - options: A variadic parameter for optional request options.
|
||||
//
|
||||
// The function returns a tuple of the response object and an error object (if any).
|
||||
func (obj *Client) Delete(preCtx context.Context, href string, options ...RequestOption) (*Response, error) {
|
||||
return obj.Request(preCtx, http.MethodDelete, href, options...)
|
||||
}
|
||||
|
||||
// sends a Connect request and returns the response.
|
||||
// It takes the following parameters:
|
||||
// - preCtx: A context object used to control the timeout and cancellation of the request.
|
||||
// - href: The URL to be requested.
|
||||
// - options: A variadic parameter for optional request options.
|
||||
//
|
||||
// The function returns a tuple of the response object and an error object (if any).
|
||||
func (obj *Client) Connect(preCtx context.Context, href string, options ...RequestOption) (*Response, error) {
|
||||
return obj.Request(preCtx, http.MethodConnect, href, options...)
|
||||
}
|
||||
|
||||
// sends a Options request and returns the response.
|
||||
// It takes the following parameters:
|
||||
// - preCtx: A context object used to control the timeout and cancellation of the request.
|
||||
// - href: The URL to be requested.
|
||||
// - options: A variadic parameter for optional request options.
|
||||
//
|
||||
// The function returns a tuple of the response object and an error object (if any).
|
||||
func (obj *Client) Options(preCtx context.Context, href string, options ...RequestOption) (*Response, error) {
|
||||
return obj.Request(preCtx, http.MethodOptions, href, options...)
|
||||
}
|
||||
|
||||
// sends a Trace request and returns the response.
|
||||
// It takes the following parameters:
|
||||
// - preCtx: A context object used to control the timeout and cancellation of the request.
|
||||
// - href: The URL to be requested.
|
||||
// - options: A variadic parameter for optional request options.
|
||||
//
|
||||
// The function returns a tuple of the response object and an error object (if any).
|
||||
func (obj *Client) Trace(preCtx context.Context, href string, options ...RequestOption) (*Response, error) {
|
||||
return obj.Request(preCtx, http.MethodTrace, href, options...)
|
||||
}
|
||||
|
||||
//Define a function named Request that takes in four parameters:
|
||||
//- preCtx: a context.Context object for setting request-related context information
|
||||
//- method: a string representing the request method (e.g., GET, POST)
|
||||
//- href: a string representing the URL link for the request
|
||||
//- options: a variadic parameter of type RequestOptions for setting specific options for the request
|
||||
|
||||
// Return a tuple of two values:
|
||||
// - resp: a pointer to a Response object containing information about the response of the request
|
||||
// - err: an error encountered during the request, which is nil if no error occurred
|
||||
func (obj *Client) Request(preCtx context.Context, method string, href string, options ...RequestOption) (resp *Response, err error) {
|
||||
if obj == nil {
|
||||
return nil, errors.New("client is nil")
|
||||
@@ -380,7 +494,9 @@ func (obj *Client) request(preCtx context.Context, option *RequestOption) (respo
|
||||
}
|
||||
}
|
||||
//send req
|
||||
if response.response, err = obj.getClient(option).Do(reqs); err != nil {
|
||||
response.response, err = obj.getClient(option).Do(reqs)
|
||||
response.isNewConn = ctxData.isNewConn
|
||||
if err != nil {
|
||||
err = tools.WrapError(err, "roundTripper error")
|
||||
return
|
||||
} else if response.response == nil {
|
||||
|
||||
86
response.go
86
response.go
@@ -5,7 +5,6 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"strconv"
|
||||
@@ -34,22 +33,25 @@ type Response struct {
|
||||
disUnzip bool
|
||||
filePath string
|
||||
bar bool
|
||||
isNewConn bool
|
||||
}
|
||||
|
||||
type SseClient struct {
|
||||
reader *bufio.Reader
|
||||
}
|
||||
type Event struct {
|
||||
Data string
|
||||
Event string
|
||||
Id string
|
||||
Retry int
|
||||
Comment string
|
||||
Data string //data
|
||||
Event string //event
|
||||
Id string //id
|
||||
Retry int //retry num
|
||||
Comment string //comment info
|
||||
}
|
||||
|
||||
func newSseClient(rd io.Reader) *SseClient {
|
||||
return &SseClient{reader: bufio.NewReader(rd)}
|
||||
}
|
||||
|
||||
// recv sse envent data
|
||||
func (obj *SseClient) Recv() (Event, error) {
|
||||
var event Event
|
||||
for {
|
||||
@@ -75,66 +77,22 @@ func (obj *SseClient) Recv() (Event, error) {
|
||||
}
|
||||
}
|
||||
|
||||
type Cookies []*http.Cookie
|
||||
|
||||
func (obj Cookies) String() string {
|
||||
cooks := []string{}
|
||||
for _, cook := range obj {
|
||||
cooks = append(cooks, fmt.Sprintf("%s=%s", cook.Name, cook.Value))
|
||||
}
|
||||
return strings.Join(cooks, "; ")
|
||||
}
|
||||
|
||||
func (obj Cookies) Gets(name string) Cookies {
|
||||
var result Cookies
|
||||
for _, cook := range obj {
|
||||
if cook.Name == name {
|
||||
result = append(result, cook)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (obj Cookies) Get(name string) *http.Cookie {
|
||||
vals := obj.Gets(name)
|
||||
if i := len(vals); i == 0 {
|
||||
return nil
|
||||
} else {
|
||||
return vals[i-1]
|
||||
}
|
||||
}
|
||||
|
||||
func (obj Cookies) GetVals(name string) []string {
|
||||
var result []string
|
||||
for _, cook := range obj {
|
||||
if cook.Name == name {
|
||||
result = append(result, cook.Value)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (obj Cookies) GetVal(name string) string {
|
||||
vals := obj.GetVals(name)
|
||||
if i := len(vals); i == 0 {
|
||||
return ""
|
||||
} else {
|
||||
return vals[i-1]
|
||||
}
|
||||
}
|
||||
|
||||
// return websocket client
|
||||
func (obj *Response) WebSocket() *websocket.Conn {
|
||||
return obj.webSocket
|
||||
}
|
||||
|
||||
// return sse client
|
||||
func (obj *Response) SseClient() *SseClient {
|
||||
return obj.sseClient
|
||||
}
|
||||
|
||||
// return URL redirected address
|
||||
func (obj *Response) Location() (*url.URL, error) {
|
||||
return obj.response.Location()
|
||||
}
|
||||
|
||||
// return response cookies
|
||||
func (obj *Response) Cookies() Cookies {
|
||||
if obj.filePath != "" {
|
||||
return nil
|
||||
@@ -142,6 +100,7 @@ func (obj *Response) Cookies() Cookies {
|
||||
return obj.response.Cookies()
|
||||
}
|
||||
|
||||
// return response status code
|
||||
func (obj *Response) StatusCode() int {
|
||||
if obj.filePath != "" {
|
||||
return 200
|
||||
@@ -149,6 +108,7 @@ func (obj *Response) StatusCode() int {
|
||||
return obj.response.StatusCode
|
||||
}
|
||||
|
||||
// return response status
|
||||
func (obj *Response) Status() string {
|
||||
if obj.filePath != "" {
|
||||
return "200 OK"
|
||||
@@ -156,6 +116,7 @@ func (obj *Response) Status() string {
|
||||
return obj.response.Status
|
||||
}
|
||||
|
||||
// return response url
|
||||
func (obj *Response) Url() *url.URL {
|
||||
if obj.filePath != "" {
|
||||
return nil
|
||||
@@ -163,6 +124,7 @@ func (obj *Response) Url() *url.URL {
|
||||
return obj.response.Request.URL
|
||||
}
|
||||
|
||||
// return response headers
|
||||
func (obj *Response) Headers() http.Header {
|
||||
if obj.filePath != "" {
|
||||
return http.Header{
|
||||
@@ -172,6 +134,7 @@ func (obj *Response) Headers() http.Header {
|
||||
return obj.response.Header
|
||||
}
|
||||
|
||||
// change decoding with content
|
||||
func (obj *Response) Decode(encoding string) {
|
||||
if obj.encoding != encoding {
|
||||
obj.encoding = encoding
|
||||
@@ -179,30 +142,38 @@ func (obj *Response) Decode(encoding string) {
|
||||
}
|
||||
}
|
||||
|
||||
// return content with map[string]any
|
||||
func (obj *Response) Map() (data map[string]any, err error) {
|
||||
_, err = gson.Decode(obj.Content(), &data)
|
||||
return
|
||||
}
|
||||
|
||||
// return content with json and you can parse struct
|
||||
func (obj *Response) Json(vals ...any) (*gson.Client, error) {
|
||||
return gson.Decode(obj.Content(), vals...)
|
||||
}
|
||||
|
||||
// return content with string
|
||||
func (obj *Response) Text() string {
|
||||
return tools.BytesToString(obj.Content())
|
||||
}
|
||||
|
||||
// set response content with []byte
|
||||
func (obj *Response) SetContent(val []byte) {
|
||||
obj.content = val
|
||||
}
|
||||
|
||||
// return content with []byte
|
||||
func (obj *Response) Content() []byte {
|
||||
return obj.content
|
||||
}
|
||||
|
||||
// return content with parse html
|
||||
func (obj *Response) Html() *bs4.Client {
|
||||
return bs4.NewClient(obj.Text(), obj.Url().String())
|
||||
}
|
||||
|
||||
// return content type
|
||||
func (obj *Response) ContentType() string {
|
||||
if obj.filePath != "" {
|
||||
return http.DetectContentType(obj.content)
|
||||
@@ -214,6 +185,7 @@ func (obj *Response) ContentType() string {
|
||||
return contentType
|
||||
}
|
||||
|
||||
// return content encoding
|
||||
func (obj *Response) ContentEncoding() string {
|
||||
if obj.filePath != "" {
|
||||
return ""
|
||||
@@ -221,6 +193,7 @@ func (obj *Response) ContentEncoding() string {
|
||||
return obj.response.Header.Get("Content-Encoding")
|
||||
}
|
||||
|
||||
// return content length
|
||||
func (obj *Response) ContentLength() int64 {
|
||||
if obj.filePath != "" {
|
||||
return int64(len(obj.content))
|
||||
@@ -334,6 +307,11 @@ func (obj *Response) InPool() bool {
|
||||
return obj.response.Body.(interface{ InPool() bool }).InPool()
|
||||
}
|
||||
|
||||
// conn is new conn
|
||||
func (obj *Response) IsNewConn() bool {
|
||||
return obj.isNewConn
|
||||
}
|
||||
|
||||
// conn ja3
|
||||
func (obj *Response) Ja3() string {
|
||||
return obj.response.Body.(interface{ Ja3() string }).Ja3()
|
||||
|
||||
@@ -79,7 +79,7 @@ type roundTripperOption struct {
|
||||
KeepAlive time.Duration
|
||||
LocalAddr *net.TCPAddr //network card ip
|
||||
AddrType gtls.AddrType //first ip type
|
||||
GetAddrType func(string) gtls.AddrType
|
||||
GetAddrType func(host string) gtls.AddrType
|
||||
Dns *net.UDPAddr
|
||||
GetProxy func(ctx context.Context, url *url.URL) (string, error)
|
||||
}
|
||||
@@ -292,6 +292,7 @@ func (obj *RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
return task.res, task.err
|
||||
}
|
||||
}
|
||||
ctxData.isNewConn = true
|
||||
newConn:
|
||||
ckey := key
|
||||
conn, err := obj.dial(ctxData, &ckey, req)
|
||||
|
||||
26
test/request_test.go
Normal file
26
test/request_test.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gospider007/requests"
|
||||
)
|
||||
|
||||
func TestDefaultClient(t *testing.T) {
|
||||
for i := 0; i < 2; i++ {
|
||||
resp, err := requests.Get(nil, "https://myip.top")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
} else {
|
||||
if i == 0 {
|
||||
if !resp.IsNewConn() {
|
||||
t.Error("new conn")
|
||||
}
|
||||
} else {
|
||||
if resp.IsNewConn() {
|
||||
t.Error("not new conn")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user