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()
|
|||
|
|
}
|