package jsonrpc2 import ( "bytes" "context" "encoding/json" "fmt" "net/http" ) type httpClient struct { c *http.Client url string } // NewHTTPClient returns a Client which will use HTTP POST requests against the // given URL as a transport for JSONRPC2 method calls. func NewHTTPClient(url string) Client { return &httpClient{ c: &http.Client{ Transport: http.DefaultTransport.(*http.Transport).Clone(), }, url: url, } } func (c *httpClient) Call( ctx context.Context, rcv any, method string, params any, ) error { var ( body = new(bytes.Buffer) enc = json.NewEncoder(body) ) id, err := encodeRequest(enc, method, params) if err != nil { return fmt.Errorf("encoding request: %w", err) } req, err := http.NewRequestWithContext(ctx, "POST", c.url, body) if err != nil { return fmt.Errorf("constructing POST request to %q: %w", c.url, err) } res, err := c.c.Do(req) if err != nil { return fmt.Errorf("performing request: %w", err) } defer res.Body.Close() dec := json.NewDecoder(res.Body) resID, err := decodeResponse(dec, rcv) if err != nil { return fmt.Errorf("decoding response: %w", err) } else if resID != id { return fmt.Errorf( "expected response with ID %q, got %q", id, resID, ) } return nil }