func (d *Doer) formatUserAgent() string {
	ua := fmt.Sprintf("%s %s (%s; %s; %s)", d.userAgent, ourUserAgent, ourUserAgentComment, runtime.GOOS, runtime.GOARCH)
	return strings.TrimSpace(ua)
}
formatUserAgent builds and returns the User-Agent string to use in requests.
package sender
import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"runtime"
	"strings"
	"github.com/go-acme/lego/v4/acme"
)
type RequestOption func(*http.Request) error
func contentType(ct string) RequestOption {
	return func(req *http.Request) error {
		req.Header.Set("Content-Type", ct)
		return nil
	}
}
type Doer struct {
	httpClient *http.Client
	userAgent  string
}
func NewDoer(client *http.Client, userAgent string) *Doer {
	return &Doer{
		httpClient: client,
		userAgent:  userAgent,
	}
}
func (d *Doer) Get(url string, response interface{}) (*http.Response, error) {
	req, err := d.newRequest(http.MethodGet, url, nil)
	if err != nil {
		return nil, err
	}
	return d.do(req, response)
}
func (d *Doer) Head(url string) (*http.Response, error) {
	req, err := d.newRequest(http.MethodHead, url, nil)
	if err != nil {
		return nil, err
	}
	return d.do(req, nil)
}
func (d *Doer) Post(url string, body io.Reader, bodyType string, response interface{}) (*http.Response, error) {
	req, err := d.newRequest(http.MethodPost, url, body, contentType(bodyType))
	if err != nil {
		return nil, err
	}
	return d.do(req, response)
}
func (d *Doer) newRequest(method, uri string, body io.Reader, opts ...RequestOption) (*http.Request, error) {
	req, err := http.NewRequest(method, uri, body)
	if err != nil {
		return nil, fmt.Errorf("failed to create request: %w", err)
	}
	req.Header.Set("User-Agent", d.formatUserAgent())
	for _, opt := range opts {
		err = opt(req)
		if err != nil {
			return nil, fmt.Errorf("failed to create request: %w", err)
		}
	}
	return req, nil
}
func (d *Doer) do(req *http.Request, response interface{}) (*http.Response, error) {
	resp, err := d.httpClient.Do(req)
	if err != nil {
		return nil, err
	}
	if err = checkError(req, resp); err != nil {
		return resp, err
	}
	if response != nil {
		raw, err := io.ReadAll(resp.Body)
		if err != nil {
			return resp, err
		}
		defer resp.Body.Close()
		err = json.Unmarshal(raw, response)
		if err != nil {
			return resp, fmt.Errorf("failed to unmarshal %q to type %T: %w", raw, response, err)
		}
	}
	return resp, nil
}