100 lines
2.2 KiB
Go
100 lines
2.2 KiB
Go
package toolkit
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httputil"
|
|
"net/url"
|
|
|
|
"dev.mediocregopher.com/mediocre-go-lib.git/mlog"
|
|
"github.com/tv42/httpunix"
|
|
)
|
|
|
|
// HTTPClient is an interface around the default http.Client type.
|
|
type HTTPClient interface {
|
|
Do(*http.Request) (*http.Response, error)
|
|
|
|
// Close cleans up any resources being held by the HTTPClient.
|
|
Close() error
|
|
}
|
|
|
|
type httpClient struct {
|
|
logger *mlog.Logger
|
|
*http.Client
|
|
}
|
|
|
|
// NewHTTPClient returns a new HTTPClient using a clone of
|
|
// [http.DefaultTransport].
|
|
func NewHTTPClient(logger *mlog.Logger) HTTPClient {
|
|
return &httpClient{
|
|
logger,
|
|
&http.Client{
|
|
Transport: http.DefaultTransport.(*http.Transport).Clone(),
|
|
},
|
|
}
|
|
}
|
|
|
|
// NewUnixHTTPClient returns an HTTPClient which will use the given
|
|
// unixSocketPath to serve requests. The base URL (scheme and host) which should
|
|
// be used for requests is returned as well.
|
|
func NewUnixHTTPClient(
|
|
logger *mlog.Logger, unixSocketPath string,
|
|
) (
|
|
HTTPClient, *url.URL,
|
|
) {
|
|
const host = "uds"
|
|
|
|
u := &url.URL{
|
|
Scheme: httpunix.Scheme,
|
|
Host: host,
|
|
}
|
|
|
|
transport := new(httpunix.Transport)
|
|
transport.RegisterLocation(host, unixSocketPath)
|
|
|
|
return &httpClient{logger, &http.Client{Transport: transport}}, u
|
|
}
|
|
|
|
func (c *httpClient) Do(req *http.Request) (*http.Response, error) {
|
|
if c.logger.MaxLevel() < mlog.LevelDebug.Int() {
|
|
return c.Client.Do(req)
|
|
}
|
|
|
|
var (
|
|
ctx = req.Context()
|
|
origScheme = req.URL.Scheme
|
|
)
|
|
|
|
// httputil.DumpRequestOut doesn't like the httpunix.Scheme, so we
|
|
// temporarily switch it.
|
|
if req.URL.Scheme == httpunix.Scheme {
|
|
req.URL.Scheme = "http"
|
|
}
|
|
|
|
reqB, err := httputil.DumpRequestOut(req, true)
|
|
if err != nil {
|
|
c.logger.Error(ctx, "failed to dump http request", err)
|
|
} else {
|
|
c.logger.Debug(ctx, "------ request ------\n"+string(reqB)+"\n")
|
|
}
|
|
|
|
req.URL.Scheme = origScheme
|
|
|
|
res, err := c.Client.Do(req)
|
|
|
|
if res != nil {
|
|
resB, err := httputil.DumpResponse(res, true)
|
|
if err != nil {
|
|
c.logger.Error(ctx, "failed to dump http response", err)
|
|
} else {
|
|
c.logger.Debug(ctx, "------ response ------\n"+string(resB)+"\n")
|
|
}
|
|
}
|
|
|
|
return res, err
|
|
}
|
|
|
|
func (c *httpClient) Close() error {
|
|
c.CloseIdleConnections()
|
|
return nil
|
|
}
|