Files
origin/sysmodule/httpclientmodule/httpclientpoolmodule.go
2024-04-09 16:40:13 +08:00

125 lines
2.7 KiB
Go

package httpclientmodule
import (
"bytes"
"crypto/tls"
"fmt"
"io"
"net"
"net/http"
"net/url"
"time"
"github.com/duanhf2012/origin/v2/service"
)
type HttpClientModule struct {
service.Module
client *http.Client
}
type HttpResponse struct {
Err error
Header http.Header
StatusCode int
Status string
Body []byte
}
type SyncHttpResponse struct {
resp chan HttpResponse
}
func (slf *SyncHttpResponse) Get(timeoutMs int) HttpResponse {
timerC := time.NewTicker(time.Millisecond * time.Duration(timeoutMs)).C
select {
case <-timerC:
break
case rsp := <-slf.resp:
return rsp
}
return HttpResponse{
Err: fmt.Errorf("Getting the return result timeout [%d]ms", timeoutMs),
}
}
func (m *HttpClientModule) InitHttpClient(transport http.RoundTripper,timeout time.Duration,checkRedirect func(req *http.Request, via []*http.Request) error){
m.client = &http.Client{
Transport: transport,
Timeout: timeout,
CheckRedirect: checkRedirect,
}
}
func (m *HttpClientModule) Init(proxyUrl string, maxpool int, dialTimeout time.Duration,dialKeepAlive time.Duration,idleConnTimeout time.Duration,timeout time.Duration) {
type ProxyFun func(_ *http.Request) (*url.URL, error)
var proxyFun ProxyFun
if proxyUrl != "" {
proxyFun = func(_ *http.Request) (*url.URL, error) {
return url.Parse(proxyUrl)
}
}
m.client = &http.Client{
Transport: &http.Transport{
DialContext: (&net.Dialer{
Timeout: dialTimeout,
KeepAlive: dialKeepAlive,
}).DialContext,
MaxIdleConns: maxpool,
MaxIdleConnsPerHost: maxpool,
IdleConnTimeout: idleConnTimeout,
Proxy: proxyFun,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
Timeout: timeout,
}
}
func (m *HttpClientModule) SetTimeOut(value time.Duration) {
m.client.Timeout = value
}
func (m *HttpClientModule) SyncRequest(method string, url string, body []byte, header http.Header) SyncHttpResponse {
ret := SyncHttpResponse{
resp: make(chan HttpResponse, 1),
}
go func() {
rsp := m.Request(method, url, body, header)
ret.resp <- rsp
}()
return ret
}
func (m *HttpClientModule) Request(method string, url string, body []byte, header http.Header) HttpResponse {
if m.client == nil {
panic("Call the init function first")
}
ret := HttpResponse{}
req, err := http.NewRequest(method, url, bytes.NewReader(body))
if err != nil {
ret.Err = err
return ret
}
if header != nil {
req.Header = header
}
rsp, err := m.client.Do(req)
if err != nil {
ret.Err = err
return ret
}
defer rsp.Body.Close()
ret.Body, err = io.ReadAll(rsp.Body)
if err != nil {
ret.Err = err
return ret
}
ret.StatusCode = rsp.StatusCode
ret.Status = rsp.Status
ret.Header = rsp.Header
return ret
}