mirror of
https://github.com/aykhans/dodo.git
synced 2025-04-16 09:53:12 +00:00
- Moved readers to the config package - Added an option to read remote config files - Moved the validation package to the config package and removed the validator dependency - Moved the customerrors package to the config package - Replaced fatih/color with jedib0t/go-pretty/v6/text - Removed proxy check functionality - Added param, header, cookie, body, and proxy flags to the CLI - Allowed multiple values for the same key in params, headers, and cookies
99 lines
3.1 KiB
Go
99 lines
3.1 KiB
Go
package requests
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"math/rand"
|
|
"net/url"
|
|
"time"
|
|
|
|
"github.com/aykhans/dodo/utils"
|
|
"github.com/valyala/fasthttp"
|
|
"github.com/valyala/fasthttp/fasthttpproxy"
|
|
)
|
|
|
|
type ClientGeneratorFunc func() *fasthttp.HostClient
|
|
|
|
// getClients initializes and returns a slice of fasthttp.HostClient based on the provided parameters.
|
|
// It can either return clients with proxies or a single client without proxies.
|
|
func getClients(
|
|
ctx context.Context,
|
|
timeout time.Duration,
|
|
proxies []url.URL,
|
|
maxConns uint,
|
|
URL url.URL,
|
|
) []*fasthttp.HostClient {
|
|
isTLS := URL.Scheme == "https"
|
|
|
|
if proxiesLen := len(proxies); proxiesLen > 0 {
|
|
clients := make([]*fasthttp.HostClient, 0, proxiesLen)
|
|
addr := URL.Host
|
|
if isTLS && URL.Port() == "" {
|
|
addr += ":443"
|
|
}
|
|
|
|
for _, proxy := range proxies {
|
|
dialFunc, err := getDialFunc(&proxy, timeout)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
clients = append(clients, &fasthttp.HostClient{
|
|
MaxConns: int(maxConns),
|
|
IsTLS: isTLS,
|
|
Addr: addr,
|
|
Dial: dialFunc,
|
|
MaxIdleConnDuration: timeout,
|
|
MaxConnDuration: timeout,
|
|
WriteTimeout: timeout,
|
|
ReadTimeout: timeout,
|
|
},
|
|
)
|
|
}
|
|
return clients
|
|
}
|
|
|
|
client := &fasthttp.HostClient{
|
|
MaxConns: int(maxConns),
|
|
IsTLS: isTLS,
|
|
Addr: URL.Host,
|
|
MaxIdleConnDuration: timeout,
|
|
MaxConnDuration: timeout,
|
|
WriteTimeout: timeout,
|
|
ReadTimeout: timeout,
|
|
}
|
|
return []*fasthttp.HostClient{client}
|
|
}
|
|
|
|
// getDialFunc returns the appropriate fasthttp.DialFunc based on the provided proxy URL scheme.
|
|
// It supports SOCKS5 ('socks5' or 'socks5h') and HTTP ('http') proxy schemes.
|
|
// For HTTP proxies, the timeout parameter determines connection timeouts.
|
|
// Returns an error if the proxy scheme is unsupported.
|
|
func getDialFunc(proxy *url.URL, timeout time.Duration) (fasthttp.DialFunc, error) {
|
|
var dialer fasthttp.DialFunc
|
|
|
|
if proxy.Scheme == "socks5" || proxy.Scheme == "socks5h" {
|
|
dialer = fasthttpproxy.FasthttpSocksDialerDualStack(proxy.String())
|
|
} else if proxy.Scheme == "http" {
|
|
dialer = fasthttpproxy.FasthttpHTTPDialerDualStackTimeout(proxy.String(), timeout)
|
|
} else {
|
|
return nil, errors.New("unsupported proxy scheme")
|
|
}
|
|
return dialer, nil
|
|
}
|
|
|
|
// getSharedClientFuncMultiple returns a ClientGeneratorFunc that cycles through a list of fasthttp.HostClient instances.
|
|
// The function uses a local random number generator to determine the starting index and stop index for cycling through the clients.
|
|
// The returned function isn't thread-safe and should be used in a single-threaded context.
|
|
func getSharedClientFuncMultiple(clients []*fasthttp.HostClient, localRand *rand.Rand) ClientGeneratorFunc {
|
|
return utils.RandomValueCycle(clients, localRand)
|
|
}
|
|
|
|
// getSharedClientFuncSingle returns a ClientGeneratorFunc that always returns the provided fasthttp.HostClient instance.
|
|
// This can be useful for sharing a single client instance across multiple requests.
|
|
func getSharedClientFuncSingle(client *fasthttp.HostClient) ClientGeneratorFunc {
|
|
return func() *fasthttp.HostClient {
|
|
return client
|
|
}
|
|
}
|