Files
origin/sysmodule/httpclientmodule/httpclientpoolmodule.go
2020-10-30 16:32:37 +08:00

117 lines
2.4 KiB
Go

package httpclientmodule
import (
"bytes"
"crypto/tls"
"fmt"
"io/ioutil"
"net"
"net/http"
"net/url"
"time"
"github.com/duanhf2012/origin/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) Init(maxpool int, proxyUrl string) {
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: 5 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
MaxIdleConns: maxpool,
MaxIdleConnsPerHost: maxpool,
IdleConnTimeout: 60 * time.Second,
Proxy: proxyFun,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
Timeout: 5 * time.Second,
}
}
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 = ioutil.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
}