mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-05-20 05:46:44 +00:00

* [NOD-386] Extract net parsing functionality to a shared place. * [NOD-386] Add extract ActiveNetParams to cmdconfig * [NOD-386] Adding comments so go-vet won't shout at me * [NOD-386] Rename package name to config * [NOD-386] Rename commandConfig to configFlags * [NOD-386] Rename function to ResolveNetwork * [NOD-386] Fix renaming errors * [NOD-386] Refactor network config to btcd level so APIserver and btcd could use it * [NOD-386] Refactor network config to config package * [NOD-386] Move ActiveNetParams to network section * [NOD-386] Explictly return nil * [NOD-386] Reuse activeNetParams from netwrok config * [NOD-386] Set ActiveNetworkFlags instance to be global * [NOD-386] Remove redundant newline * [NOD-386] Init ActiveNetParams in address manager test * [NOD-386] Add dnsseeder network config * [NOD-386] Use ActiveConfig() method to access configuration
129 lines
3.4 KiB
Go
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/daglabs/btcd/btcjson"
|
|
)
|
|
|
|
// 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 btcjson.Response
|
|
if err := json.Unmarshal(respBytes, &resp); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if resp.Error != nil {
|
|
return nil, resp.Error
|
|
}
|
|
return resp.Result, nil
|
|
}
|