main
lzf 2025-07-11 16:57:24 +08:00
parent 27ccc2a080
commit 1cb7943903
2 changed files with 113 additions and 34 deletions

View File

@ -3,7 +3,6 @@ package httpc
import ( import (
"bytes" "bytes"
"context" "context"
"crypto/tls"
"errors" "errors"
"fmt" "fmt"
"git.makemake.in/kzkzzzz/mycommon/mylog" "git.makemake.in/kzkzzzz/mycommon/mylog"
@ -21,18 +20,34 @@ var (
) )
func init() { func init() {
defaultClient = NewWithRedirect(false) defaultClient = New()
noRedirectClient = NewWithRedirect(true) noRedirectClient = New(WithNoRedirect())
} }
func NewTransport() *http.Transport { func Client() *HttpClient {
return defaultClient
}
func NoRedirectClient() *HttpClient {
return noRedirectClient
}
func NewTransport(maxConn int, idleTimeout time.Duration) *http.Transport {
if maxConn <= 0 {
panic("max connection <= 0")
}
if idleTimeout <= 0 {
panic("idle timeout <= 0")
}
tr := http.DefaultTransport.(*http.Transport).Clone() tr := http.DefaultTransport.(*http.Transport).Clone()
tr.MaxIdleConns = 0 tr.MaxIdleConns = 0
tr.MaxConnsPerHost = 0 tr.MaxConnsPerHost = 0
tr.MaxIdleConnsPerHost = 2048 tr.MaxIdleConnsPerHost = maxConn
tr.IdleConnTimeout = time.Second * 90 tr.IdleConnTimeout = idleTimeout
tr.DisableKeepAlives = false tr.DisableKeepAlives = false
tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: false} //tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: false}
return tr return tr
} }
@ -46,24 +61,43 @@ type Request struct {
} }
type HttpClient struct { type HttpClient struct {
config *Config
client *http.Client client *http.Client
} }
func NewWithRedirect(noRedirect bool) *HttpClient { func New(opts ...ConfigOpt) *HttpClient {
tr := NewTransport() config := &Config{}
for _, opt := range opts {
opt(config)
}
if config.timeout <= 0 {
config.timeout = time.Second * 6
}
if config.transport == nil {
config.transport = NewTransport(3072, time.Second*90)
}
if config.client == nil {
client := &http.Client{ client := &http.Client{
Transport: tr, Transport: config.transport,
Timeout: time.Second * 6, Timeout: config.timeout,
} }
if noRedirect { if config.redirectFn != nil {
client.CheckRedirect = func(req *http.Request, via []*http.Request) error { client.CheckRedirect = config.redirectFn
return http.ErrUseLastResponse
}
} }
h := &HttpClient{client: client} config.client = client
return h }
hc := &HttpClient{
config: config,
client: config.client,
}
return hc
} }
func NewWithClient(httpClient *http.Client) *HttpClient { func NewWithClient(httpClient *http.Client) *HttpClient {
@ -81,7 +115,7 @@ func (h *HttpClient) SetProxy(pr string) *HttpClient {
return h return h
} }
func (h *HttpClient) Request(ctx context.Context) *Request { func (h *HttpClient) NewRequest(ctx context.Context) *Request {
r := &Request{ r := &Request{
ctx: ctx, ctx: ctx,
header: nil, header: nil,
@ -91,22 +125,26 @@ func (h *HttpClient) Request(ctx context.Context) *Request {
return r return r
} }
func PcRequest(ctx context.Context) *Request { func NewRequest(ctx context.Context) *Request {
return defaultClient.PcRequest(ctx) return defaultClient.NewRequest(ctx)
} }
func MobileRequest(ctx context.Context) *Request { func NewPcRequest(ctx context.Context) *Request {
return defaultClient.MobileRequest(ctx) return defaultClient.NewPcRequest(ctx)
} }
func (h *HttpClient) PcRequest(ctx context.Context) *Request { func NewMobileRequest(ctx context.Context) *Request {
r := h.Request(ctx) return defaultClient.NewMobileRequest(ctx)
}
func (h *HttpClient) NewPcRequest(ctx context.Context) *Request {
r := h.NewRequest(ctx)
r.SetHeaderPcAgent() r.SetHeaderPcAgent()
return r return r
} }
func (h *HttpClient) MobileRequest(ctx context.Context) *Request { func (h *HttpClient) NewMobileRequest(ctx context.Context) *Request {
r := h.Request(ctx) r := h.NewRequest(ctx)
r.SetHeaderMobileAgent() r.SetHeaderMobileAgent()
return r return r
} }
@ -223,14 +261,6 @@ func (r *Request) Do(method, rawUrl string) (*Response, error) {
return resp, nil return resp, nil
} }
func Client() *HttpClient {
return defaultClient
}
func NoRedirectClient() *HttpClient {
return noRedirectClient
}
func (r *Request) SetHeaderPcAgent() *Request { func (r *Request) SetHeaderPcAgent() *Request {
r.SetHeader(HeaderUserAgent, PcUserAgent) r.SetHeader(HeaderUserAgent, PcUserAgent)
return r return r

49
myhttp/httpc/option.go Normal file
View File

@ -0,0 +1,49 @@
package httpc
import (
"net/http"
"time"
)
type (
Config struct {
timeout time.Duration
client *http.Client
transport *http.Transport
redirectFn func(req *http.Request, via []*http.Request) error
}
ConfigOpt func(c *Config)
)
func WithTimout(v time.Duration) ConfigOpt {
return func(c *Config) {
c.timeout = v
}
}
func WithClient(v *http.Client) ConfigOpt {
return func(c *Config) {
c.client = v
}
}
func WithTransport(v *http.Transport) ConfigOpt {
return func(c *Config) {
c.transport = v
}
}
func WithRedirectFn(v func(req *http.Request, via []*http.Request) error) ConfigOpt {
return func(c *Config) {
c.redirectFn = v
}
}
func WithNoRedirect() ConfigOpt {
return func(c *Config) {
c.redirectFn = func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
}
}
}