github.com/decred/politeia@v1.4.0/politeiawww/legacy/politeiad.go (about)

     1  // Copyright (c) 2020 The Decred developers
     2  // Use of this source code is governed by an ISC
     3  // license that can be found in the LICENSE file.
     4  
     5  package legacy
     6  
     7  import (
     8  	"bytes"
     9  	"context"
    10  	"encoding/json"
    11  	"fmt"
    12  	"net/http"
    13  
    14  	"github.com/decred/politeia/util"
    15  )
    16  
    17  // pdErrorReply represents the request body that is returned from politeaid
    18  // when an error occurs. PluginID will be populated if this is a plugin error.
    19  type pdErrorReply struct {
    20  	ErrorCode    int
    21  	ErrorContext []string
    22  	Plugin       string
    23  }
    24  
    25  // pdError represents a politeiad error.
    26  type pdError struct {
    27  	HTTPCode   int
    28  	ErrorReply pdErrorReply
    29  }
    30  
    31  // Error satisfies the error interface.
    32  func (e pdError) Error() string {
    33  	return fmt.Sprintf("error from politeiad: %v %v",
    34  		e.HTTPCode, e.ErrorReply.ErrorCode)
    35  }
    36  
    37  // makeRequest makes a politeiad http request to the method and route provided,
    38  // serializing the provided object as the request body. A pdError is returned
    39  // if politeiad does not respond with a 200.
    40  //
    41  // This method has been DEPRECATED. The politeiad client on the politeiawww
    42  // context should be used instead. This method can be removed once all of the
    43  // cms invocations have been switched over to use the politeaid client.
    44  func (p *Politeiawww) makeRequest(ctx context.Context, method string, route string, v interface{}) ([]byte, error) {
    45  	var (
    46  		reqBody []byte
    47  		err     error
    48  	)
    49  	if v != nil {
    50  		reqBody, err = json.Marshal(v)
    51  		if err != nil {
    52  			return nil, err
    53  		}
    54  	}
    55  
    56  	fullRoute := p.cfg.RPCHost + route
    57  
    58  	log.Debugf("%v %v", method, fullRoute)
    59  
    60  	req, err := http.NewRequestWithContext(ctx, method,
    61  		fullRoute, bytes.NewReader(reqBody))
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  	req.SetBasicAuth(p.cfg.RPCUser, p.cfg.RPCPass)
    66  	r, err := p.http.Do(req)
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  	defer r.Body.Close()
    71  
    72  	if r.StatusCode != http.StatusOK {
    73  		var e pdErrorReply
    74  		decoder := json.NewDecoder(r.Body)
    75  		if err := decoder.Decode(&e); err != nil {
    76  			return nil, fmt.Errorf("status code %v: %v", r.StatusCode, err)
    77  		}
    78  
    79  		return nil, pdError{
    80  			HTTPCode:   r.StatusCode,
    81  			ErrorReply: e,
    82  		}
    83  	}
    84  
    85  	responseBody := util.ConvertBodyToByteArray(r.Body, false)
    86  	return responseBody, nil
    87  }