kaspad/cmd/kaspactl/httpclient.go
stasatdaglabs f46dec449d [NOD-510] Change all references to Bitcoin to Kaspa (#531)
* [NOD-510] Change coinbase flags to kaspad.

* [NOD-510] Removed superfluous spaces after periods in comments.

* [NOD-510] Rename btcd -> kaspad in the root folder.

* [NOD-510] Rename BtcEncode -> KaspaEncode and BtcDecode -> KaspaDecode.

* [NOD-510] Rename BtcEncode -> KaspaEncode and BtcDecode -> KaspaDecode.

* [NOD-510] Continue renaming btcd -> kaspad.

* [NOD-510] Rename btcjson -> kaspajson.

* [NOD-510] Rename file names inside kaspajson.

* [NOD-510] Rename kaspajson -> jsonrpc.

* [NOD-510] Finish renaming in addrmgr.

* [NOD-510] Rename package btcec to ecc.

* [NOD-510] Finish renaming stuff in blockdag.

* [NOD-510] Rename stuff in cmd.

* [NOD-510] Rename stuff in config.

* [NOD-510] Rename stuff in connmgr.

* [NOD-510] Rename stuff in dagconfig.

* [NOD-510] Rename stuff in database.

* [NOD-510] Rename stuff in docker.

* [NOD-510] Rename stuff in integration.

* [NOD-510] Rename jsonrpc to rpcmodel.

* [NOD-510] Rename stuff in limits.

* [NOD-510] Rename stuff in logger.

* [NOD-510] Rename stuff in mempool.

* [NOD-510] Rename stuff in mining.

* [NOD-510] Rename stuff in netsync.

* [NOD-510] Rename stuff in peer.

* [NOD-510] Rename stuff in release.

* [NOD-510] Rename stuff in rpcclient.

* [NOD-510] Rename stuff in server.

* [NOD-510] Rename stuff in signal.

* [NOD-510] Rename stuff in txscript.

* [NOD-510] Rename stuff in util.

* [NOD-510] Rename stuff in wire.

* [NOD-510] Fix failing tests.

* [NOD-510] Fix merge errors.

* [NOD-510] Fix go vet errors.

* [NOD-510] Remove merged file that's no longer relevant.

* [NOD-510] Add a comment above Op0.

* [NOD-510] Fix some comments referencing Bitcoin Core.

* [NOD-510] Fix some more comments referencing Bitcoin Core.

* [NOD-510] Fix bitcoin -> kaspa.

* [NOD-510] Fix more bitcoin -> kaspa.

* [NOD-510] Fix comments, remove DisconnectBlock in addrindex.

* [NOD-510] Rename KSPD to KASD.

* [NOD-510] Fix comments and user agent.
2019-12-12 15:21:41 +02:00

129 lines
3.4 KiB
Go

package main
import (
"bytes"
"crypto/tls"
"crypto/x509"
"encoding/json"
"github.com/pkg/errors"
"io/ioutil"
"net"
"net/http"
"github.com/btcsuite/go-socks/socks"
"github.com/kaspanet/kaspad/rpcmodel"
)
// newHTTPClient returns a new HTTP client that is configured according to the
// proxy and TLS settings in the associated connection configuration.
func newHTTPClient(cfg *ConfigFlags) (*http.Client, error) {
// Configure proxy if needed.
var dial func(network, addr string) (net.Conn, error)
if cfg.Proxy != "" {
proxy := &socks.Proxy{
Addr: cfg.Proxy,
Username: cfg.ProxyUser,
Password: cfg.ProxyPass,
}
dial = func(network, addr string) (net.Conn, error) {
c, err := proxy.Dial(network, addr)
if err != nil {
return nil, err
}
return c, nil
}
}
// Configure TLS if needed.
var tlsConfig *tls.Config
if !cfg.NoTLS && cfg.RPCCert != "" {
pem, err := ioutil.ReadFile(cfg.RPCCert)
if err != nil {
return nil, err
}
pool := x509.NewCertPool()
pool.AppendCertsFromPEM(pem)
tlsConfig = &tls.Config{
RootCAs: pool,
InsecureSkipVerify: cfg.TLSSkipVerify,
}
}
// Create and return the new HTTP client potentially configured with a
// proxy and TLS.
client := http.Client{
Transport: &http.Transport{
Dial: dial,
TLSClientConfig: tlsConfig,
},
}
return &client, nil
}
// sendPostRequest sends the marshalled JSON-RPC command using HTTP-POST mode
// to the server described in the passed config struct. It also attempts to
// unmarshal the response as a JSON-RPC response and returns either the result
// field or the error field depending on whether or not there is an error.
func sendPostRequest(marshalledJSON []byte, cfg *ConfigFlags) ([]byte, error) {
// Generate a request to the configured RPC server.
protocol := "http"
if !cfg.NoTLS {
protocol = "https"
}
url := protocol + "://" + cfg.RPCServer
bodyReader := bytes.NewReader(marshalledJSON)
httpRequest, err := http.NewRequest("POST", url, bodyReader)
if err != nil {
return nil, err
}
httpRequest.Close = true
httpRequest.Header.Set("Content-Type", "application/json")
// Configure basic access authorization.
httpRequest.SetBasicAuth(cfg.RPCUser, cfg.RPCPassword)
// Create the new HTTP client that is configured according to the user-
// specified options and submit the request.
httpClient, err := newHTTPClient(cfg)
if err != nil {
return nil, err
}
httpResponse, err := httpClient.Do(httpRequest)
if err != nil {
return nil, err
}
// Read the raw bytes and close the response.
respBytes, err := ioutil.ReadAll(httpResponse.Body)
httpResponse.Body.Close()
if err != nil {
err = errors.Errorf("error reading json reply: %s", err)
return nil, err
}
// Handle unsuccessful HTTP responses
if httpResponse.StatusCode < 200 || httpResponse.StatusCode >= 300 {
// Generate a standard error to return if the server body is
// empty. This should not happen very often, but it's better
// than showing nothing in case the target server has a poor
// implementation.
if len(respBytes) == 0 {
return nil, errors.Errorf("%d %s", httpResponse.StatusCode,
http.StatusText(httpResponse.StatusCode))
}
return nil, errors.Errorf("%s", respBytes)
}
// Unmarshal the response.
var resp rpcmodel.Response
if err := json.Unmarshal(respBytes, &resp); err != nil {
return nil, err
}
if resp.Error != nil {
return nil, resp.Error
}
return resp.Result, nil
}