148 lines
3.5 KiB
Go
148 lines
3.5 KiB
Go
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()
|
||
}
|