liuhaijun e94826ce29 add server
Change-Id: I0760f17f6a01c0121b59fcbfafc666032dbc30af
2024-09-19 09:44:15 +00:00

91 lines
2.8 KiB
Go

package httputils
import (
"crypto/tls"
"io"
"net"
"net/http"
"time"
)
const DefaultTimeout = 10 * time.Second
func HttpGet(url string, timeout time.Duration, customHeaders map[string]string, cookies []*http.Cookie) ([]byte, int, []*http.Cookie, error) {
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, 0, nil, err
}
for _, c := range cookies {
req.AddCookie(c)
}
transport, err := CreateTransport(&http.Transport{}, timeout, customHeaders)
if err != nil {
return nil, 0, nil, err
}
client := http.Client{Transport: transport, Timeout: timeout}
resp, err := client.Do(req)
if err != nil {
return nil, 0, nil, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
return body, resp.StatusCode, resp.Cookies(), err
}
type customHeadersRoundTripper struct {
headers map[string]string
originalRT http.RoundTripper
}
func (rt *customHeadersRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
// note: no need to check for nil or empty map - newCustomHeadersRoundTripper will assure us there will always be at least 1
for k, v := range rt.headers {
req.Header.Set(k, v)
}
return rt.originalRT.RoundTrip(req)
}
func newCustomHeadersRoundTripper(headers map[string]string, rt http.RoundTripper) http.RoundTripper {
if len(headers) == 0 {
// if there are no custom headers then there is no need for a special RoundTripper; therefore just return the original RoundTripper
return rt
}
return &customHeadersRoundTripper{
headers: headers,
originalRT: rt,
}
}
// Creates a new HTTP Transport with TLS, Timeouts, and optional custom headers.
//
// Please remember that setting long timeouts is not recommended as it can make
// idle connections stay open for as long as 2 * timeout. This should only be
// done in cases where you know the request is very likely going to be reused at
// some point in the near future.
func CreateTransport(transportConfig *http.Transport, timeout time.Duration, customHeaders map[string]string) (http.RoundTripper, error) {
// Limits the time spent establishing a TCP connection if a new one is
// needed. If DialContext is not set, Dial is used, we only create a new one
// if neither is defined.
if transportConfig.DialContext == nil {
transportConfig.DialContext = (&net.Dialer{
Timeout: timeout,
}).DialContext
}
transportConfig.IdleConnTimeout = timeout
transportConfig.TLSClientConfig = &tls.Config{
InsecureSkipVerify: true,
}
// We might need some custom RoundTrippers to manipulate the requests (for auth and other custom request headers).
// Chain together the RoundTrippers that we need, retaining the outer-most round tripper so we can return it.
outerRoundTripper := newCustomHeadersRoundTripper(customHeaders, transportConfig)
return outerRoundTripper, nil
}