package starnet import ( "net/http" "sync" "time" ) var ( defaultClient *Client defaultHTTPClient *http.Client defaultClientOnce sync.Once defaultHTTPOnce sync.Once defaultMu sync.RWMutex ) // DefaultClient 获取默认 Client(单例) func DefaultClient() *Client { defaultMu.RLock() if defaultClient != nil { c := defaultClient defaultMu.RUnlock() return c } defaultMu.RUnlock() defaultClientOnce.Do(func() { c := NewClientNoErr() defaultMu.Lock() defaultClient = c defaultMu.Unlock() }) defaultMu.RLock() c := defaultClient defaultMu.RUnlock() return c } // DefaultHTTPClient 获取默认 http.Client(单例) func DefaultHTTPClient() *http.Client { defaultMu.RLock() if defaultHTTPClient != nil { c := defaultHTTPClient defaultMu.RUnlock() return c } defaultMu.RUnlock() defaultHTTPOnce.Do(func() { c := &http.Client{ Transport: &Transport{ base: &http.Transport{ ForceAttemptHTTP2: true, MaxIdleConns: 100, MaxIdleConnsPerHost: 10, IdleConnTimeout: 90 * time.Second, TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, }, }, Timeout: 0, // 由请求级控制超时 } defaultMu.Lock() defaultHTTPClient = c defaultMu.Unlock() }) defaultMu.RLock() c := defaultHTTPClient defaultMu.RUnlock() return c } // SetDefaultClient 设置默认 Client func SetDefaultClient(client *Client) { defaultMu.Lock() defer defaultMu.Unlock() defaultClient = client // 标记 once 已完成,避免后续 DefaultClient() 再次初始化覆盖 defaultClientOnce.Do(func() {}) } // SetDefaultHTTPClient 设置默认 http.Client func SetDefaultHTTPClient(client *http.Client) { defaultMu.Lock() defer defaultMu.Unlock() defaultHTTPClient = client // 标记 once 已完成,避免后续 DefaultHTTPClient() 再次初始化覆盖 defaultHTTPOnce.Do(func() {}) } // Get 发送 GET 请求(使用默认 Client) func Get(url string, opts ...RequestOpt) (*Response, error) { return DefaultClient().Get(url, opts...) } // Post 发送 POST 请求(使用默认 Client) func Post(url string, opts ...RequestOpt) (*Response, error) { return DefaultClient().Post(url, opts...) } // Put 发送 PUT 请求(使用默认 Client) func Put(url string, opts ...RequestOpt) (*Response, error) { return DefaultClient().Put(url, opts...) } // Delete 发送 DELETE 请求(使用默认 Client) func Delete(url string, opts ...RequestOpt) (*Response, error) { return DefaultClient().Delete(url, opts...) } // Head 发送 HEAD 请求(使用默认 Client) func Head(url string, opts ...RequestOpt) (*Response, error) { return DefaultClient().Head(url, opts...) } // Patch 发送 PATCH 请求(使用默认 Client) func Patch(url string, opts ...RequestOpt) (*Response, error) { return DefaultClient().Patch(url, opts...) } // Options 发送 OPTIONS 请求(使用默认 Client) func Options(url string, opts ...RequestOpt) (*Response, error) { return DefaultClient().Options(url, opts...) } // Trace 发送 TRACE 请求(使用默认 Client) func Trace(url string, opts ...RequestOpt) (*Response, error) { req, err := DefaultClient().NewRequest(url, http.MethodTrace, opts...) if err != nil { return nil, err } return req.Do() } // Connect 发送 CONNECT 请求(使用默认 Client) func Connect(url string, opts ...RequestOpt) (*Response, error) { req, err := DefaultClient().NewRequest(url, http.MethodConnect, opts...) if err != nil { return nil, err } return req.Do() }