github.com/adoriasoft/tendermint@v0.34.0-dev1.0.20200722151356-96d84601a75a/rpc/jsonrpc/client/http_uri_client.go (about)

     1  package client
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"net/http"
     7  
     8  	types "github.com/tendermint/tendermint/rpc/jsonrpc/types"
     9  )
    10  
    11  const (
    12  	// URIClientRequestID in a request ID used by URIClient
    13  	URIClientRequestID = types.JSONRPCIntID(-1)
    14  )
    15  
    16  // URIClient is a JSON-RPC client, which sends POST form HTTP requests to the
    17  // remote server.
    18  //
    19  // URIClient is safe for concurrent use by multiple goroutines.
    20  type URIClient struct {
    21  	address string
    22  	client  *http.Client
    23  }
    24  
    25  var _ HTTPClient = (*URIClient)(nil)
    26  
    27  // NewURI returns a new client.
    28  // An error is returned on invalid remote.
    29  // The function panics when remote is nil.
    30  func NewURI(remote string) (*URIClient, error) {
    31  	parsedURL, err := newParsedURL(remote)
    32  	if err != nil {
    33  		return nil, err
    34  	}
    35  
    36  	httpClient, err := DefaultHTTPClient(remote)
    37  	if err != nil {
    38  		return nil, err
    39  	}
    40  
    41  	parsedURL.SetDefaultSchemeHTTP()
    42  
    43  	uriClient := &URIClient{
    44  		address: parsedURL.GetTrimmedURL(),
    45  		client:  httpClient,
    46  	}
    47  
    48  	return uriClient, nil
    49  }
    50  
    51  // Call issues a POST form HTTP request.
    52  func (c *URIClient) Call(method string, params map[string]interface{}, result interface{}) (interface{}, error) {
    53  	values, err := argsToURLValues(params)
    54  	if err != nil {
    55  		return nil, fmt.Errorf("failed to encode params: %w", err)
    56  	}
    57  
    58  	resp, err := c.client.PostForm(c.address+"/"+method, values)
    59  	if err != nil {
    60  		return nil, fmt.Errorf("post form failed: %w", err)
    61  	}
    62  	defer resp.Body.Close()
    63  
    64  	responseBytes, err := ioutil.ReadAll(resp.Body)
    65  	if err != nil {
    66  		return nil, fmt.Errorf("failed to read response body: %w", err)
    67  	}
    68  
    69  	return unmarshalResponseBytes(responseBytes, URIClientRequestID, result)
    70  }