github.com/zjj1991/quorum@v0.0.0-20190524123704-ae4b0a1e1a19/private/constellation/node.go (about)

     1  package constellation
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/base64"
     6  	"encoding/json"
     7  	"errors"
     8  	"fmt"
     9  	"github.com/tv42/httpunix"
    10  	"io"
    11  	"io/ioutil"
    12  	"net/http"
    13  	"os"
    14  	"os/exec"
    15  	"strings"
    16  	"time"
    17  )
    18  
    19  func launchNode(cfgPath string) (*exec.Cmd, error) {
    20  	cmd := exec.Command("constellation-node", cfgPath)
    21  	stderr, err := cmd.StderrPipe()
    22  	if err != nil {
    23  		return nil, err
    24  	}
    25  	go io.Copy(os.Stderr, stderr)
    26  	if err := cmd.Start(); err != nil {
    27  		return nil, err
    28  	}
    29  	time.Sleep(100 * time.Millisecond)
    30  	return cmd, nil
    31  }
    32  
    33  func unixTransport(socketPath string) *httpunix.Transport {
    34  	t := &httpunix.Transport{
    35  		DialTimeout:           1 * time.Second,
    36  		RequestTimeout:        5 * time.Second,
    37  		ResponseHeaderTimeout: 5 * time.Second,
    38  	}
    39  	t.RegisterLocation("c", socketPath)
    40  	return t
    41  }
    42  
    43  func unixClient(socketPath string) *http.Client {
    44  	return &http.Client{
    45  		Transport: unixTransport(socketPath),
    46  	}
    47  }
    48  
    49  func RunNode(socketPath string) error {
    50  	c := unixClient(socketPath)
    51  	res, err := c.Get("http+unix://c/upcheck")
    52  	if err != nil {
    53  		return err
    54  	}
    55  	if res.StatusCode == 200 {
    56  		return nil
    57  	}
    58  	return errors.New("Constellation Node API did not respond to upcheck request")
    59  }
    60  
    61  type Client struct {
    62  	httpClient *http.Client
    63  }
    64  
    65  func (c *Client) doJson(path string, apiReq interface{}) (*http.Response, error) {
    66  	buf := new(bytes.Buffer)
    67  	err := json.NewEncoder(buf).Encode(apiReq)
    68  	if err != nil {
    69  		return nil, err
    70  	}
    71  	req, err := http.NewRequest("POST", "http+unix://c/"+path, buf)
    72  	if err != nil {
    73  		return nil, err
    74  	}
    75  	req.Header.Set("Content-Type", "application/json")
    76  	res, err := c.httpClient.Do(req)
    77  	if err == nil && res.StatusCode != 200 {
    78  		return nil, fmt.Errorf("Non-200 status code: %+v", res)
    79  	}
    80  	return res, err
    81  }
    82  
    83  func (c *Client) SendPayload(pl []byte, b64From string, b64To []string) ([]byte, error) {
    84  	buf := bytes.NewBuffer(pl)
    85  	req, err := http.NewRequest("POST", "http+unix://c/sendraw", buf)
    86  	if err != nil {
    87  		return nil, err
    88  	}
    89  	if b64From != "" {
    90  		req.Header.Set("c11n-from", b64From)
    91  	}
    92  	req.Header.Set("c11n-to", strings.Join(b64To, ","))
    93  	req.Header.Set("Content-Type", "application/octet-stream")
    94  	res, err := c.httpClient.Do(req)
    95  
    96  	if res != nil {
    97  		defer res.Body.Close()
    98  	}
    99  	if err != nil {
   100  		return nil, err
   101  	}
   102  	if res.StatusCode != 200 {
   103  		return nil, fmt.Errorf("Non-200 status code: %+v", res)
   104  	}
   105  
   106  	return ioutil.ReadAll(base64.NewDecoder(base64.StdEncoding, res.Body))
   107  }
   108  
   109  func (c *Client) SendSignedPayload(signedPayload []byte, b64To []string) ([]byte, error) {
   110  	buf := bytes.NewBuffer(signedPayload)
   111  	req, err := http.NewRequest("POST", "http+unix://c/sendsignedtx", buf)
   112  	if err != nil {
   113  		return nil, err
   114  	}
   115  
   116  	req.Header.Set("c11n-to", strings.Join(b64To, ","))
   117  	req.Header.Set("Content-Type", "application/octet-stream")
   118  	res, err := c.httpClient.Do(req)
   119  
   120  	if res != nil {
   121  		defer res.Body.Close()
   122  	}
   123  	if err != nil {
   124  		return nil, err
   125  	}
   126  	if res.StatusCode != 200 {
   127  		return nil, fmt.Errorf("Non-200 status code: %+v", res)
   128  	}
   129  
   130  	return ioutil.ReadAll(base64.NewDecoder(base64.StdEncoding, res.Body))
   131  }
   132  
   133  func (c *Client) ReceivePayload(key []byte) ([]byte, error) {
   134  	req, err := http.NewRequest("GET", "http+unix://c/receiveraw", nil)
   135  	if err != nil {
   136  		return nil, err
   137  	}
   138  	req.Header.Set("c11n-key", base64.StdEncoding.EncodeToString(key))
   139  	res, err := c.httpClient.Do(req)
   140  
   141  	if res != nil {
   142  		defer res.Body.Close()
   143  	}
   144  	if err != nil {
   145  		return nil, err
   146  	}
   147  	if res.StatusCode != 200 {
   148  		return nil, fmt.Errorf("Non-200 status code: %+v", res)
   149  	}
   150  
   151  	return ioutil.ReadAll(res.Body)
   152  }
   153  
   154  func NewClient(socketPath string) (*Client, error) {
   155  	return &Client{
   156  		httpClient: unixClient(socketPath),
   157  	}, nil
   158  }