storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/rpc/json2/client.go (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Copyright 2012 The Gorilla Authors. All rights reserved.
     3  // Use of this source code is governed by a BSD-style
     4  // license that can be found in the LICENSE file.
     5  
     6  // Copyright 2020 MinIO, Inc. All rights reserved.
     7  // forked from https://github.com/gorilla/rpc/v2
     8  // modified to be used with MinIO under Apache
     9  // 2.0 license that can be found in the LICENSE file.
    10  
    11  package json2
    12  
    13  import (
    14  	"io"
    15  	"math/rand"
    16  
    17  	jsoniter "github.com/json-iterator/go"
    18  )
    19  
    20  // ----------------------------------------------------------------------------
    21  // Request and Response
    22  // ----------------------------------------------------------------------------
    23  
    24  // clientRequest represents a JSON-RPC request sent by a client.
    25  type clientRequest struct {
    26  	// JSON-RPC protocol.
    27  	Version string `json:"jsonrpc"`
    28  
    29  	// A String containing the name of the method to be invoked.
    30  	Method string `json:"method"`
    31  
    32  	// Object to pass as request parameter to the method.
    33  	Params interface{} `json:"params"`
    34  
    35  	// The request id. This can be of any type. It is used to match the
    36  	// response with the request that it is replying to.
    37  	Id uint64 `json:"id"`
    38  }
    39  
    40  // clientResponse represents a JSON-RPC response returned to a client.
    41  type clientResponse struct {
    42  	Version string               `json:"jsonrpc"`
    43  	Result  *jsoniter.RawMessage `json:"result"`
    44  	Error   *jsoniter.RawMessage `json:"error"`
    45  }
    46  
    47  // EncodeClientRequest encodes parameters for a JSON-RPC client request.
    48  func EncodeClientRequest(method string, args interface{}) ([]byte, error) {
    49  	c := &clientRequest{
    50  		Version: "2.0",
    51  		Method:  method,
    52  		Params:  args,
    53  		Id:      uint64(rand.Int63()),
    54  	}
    55  	var json = jsoniter.ConfigCompatibleWithStandardLibrary
    56  	return json.Marshal(c)
    57  }
    58  
    59  // DecodeClientResponse decodes the response body of a client request into
    60  // the interface reply.
    61  func DecodeClientResponse(r io.Reader, reply interface{}) error {
    62  	var c clientResponse
    63  	var json = jsoniter.ConfigCompatibleWithStandardLibrary
    64  	if err := json.NewDecoder(r).Decode(&c); err != nil {
    65  		return err
    66  	}
    67  	if c.Error != nil {
    68  		jsonErr := &Error{}
    69  		if err := json.Unmarshal(*c.Error, jsonErr); err != nil {
    70  			return &Error{
    71  				Code:    E_SERVER,
    72  				Message: string(*c.Error),
    73  			}
    74  		}
    75  		return jsonErr
    76  	}
    77  
    78  	if c.Result == nil {
    79  		return ErrNullResult
    80  	}
    81  
    82  	return json.Unmarshal(*c.Result, reply)
    83  }