github.com/cloudreve/Cloudreve/v3@v3.0.0-20240224133659-3edb00a6484c/pkg/aria2/rpc/json2.go (about)

     1  package rpc
     2  
     3  // based on "github.com/gorilla/rpc/v2/json2"
     4  
     5  // Copyright 2009 The Go Authors. All rights reserved.
     6  // Copyright 2012 The Gorilla Authors. All rights reserved.
     7  // Use of this source code is governed by a BSD-style
     8  // license that can be found in the LICENSE file.
     9  
    10  import (
    11  	"bytes"
    12  	"encoding/json"
    13  	"errors"
    14  	"io"
    15  )
    16  
    17  // ----------------------------------------------------------------------------
    18  // Request and Response
    19  // ----------------------------------------------------------------------------
    20  
    21  // clientRequest represents a JSON-RPC request sent by a client.
    22  type clientRequest struct {
    23  	// JSON-RPC protocol.
    24  	Version string `json:"jsonrpc"`
    25  
    26  	// A String containing the name of the method to be invoked.
    27  	Method string `json:"method"`
    28  
    29  	// Object to pass as request parameter to the method.
    30  	Params interface{} `json:"params"`
    31  
    32  	// The request id. This can be of any type. It is used to match the
    33  	// response with the request that it is replying to.
    34  	Id uint64 `json:"id"`
    35  }
    36  
    37  // clientResponse represents a JSON-RPC response returned to a client.
    38  type clientResponse struct {
    39  	Version string           `json:"jsonrpc"`
    40  	Result  *json.RawMessage `json:"result"`
    41  	Error   *json.RawMessage `json:"error"`
    42  	Id      *uint64          `json:"id"`
    43  }
    44  
    45  // EncodeClientRequest encodes parameters for a JSON-RPC client request.
    46  func EncodeClientRequest(method string, args interface{}) (*bytes.Buffer, error) {
    47  	var buf bytes.Buffer
    48  	c := &clientRequest{
    49  		Version: "2.0",
    50  		Method:  method,
    51  		Params:  args,
    52  		Id:      reqid(),
    53  	}
    54  	if err := json.NewEncoder(&buf).Encode(c); err != nil {
    55  		return nil, err
    56  	}
    57  	return &buf, nil
    58  }
    59  
    60  func (c clientResponse) decode(reply interface{}) error {
    61  	if c.Error != nil {
    62  		jsonErr := &Error{}
    63  		if err := json.Unmarshal(*c.Error, jsonErr); err != nil {
    64  			return &Error{
    65  				Code:    E_SERVER,
    66  				Message: string(*c.Error),
    67  			}
    68  		}
    69  		return jsonErr
    70  	}
    71  
    72  	if c.Result == nil {
    73  		return ErrNullResult
    74  	}
    75  
    76  	return json.Unmarshal(*c.Result, reply)
    77  }
    78  
    79  // DecodeClientResponse decodes the response body of a client request into
    80  // the interface reply.
    81  func DecodeClientResponse(r io.Reader, reply interface{}) error {
    82  	var c clientResponse
    83  	if err := json.NewDecoder(r).Decode(&c); err != nil {
    84  		return err
    85  	}
    86  	return c.decode(reply)
    87  }
    88  
    89  type ErrorCode int
    90  
    91  const (
    92  	E_PARSE       ErrorCode = -32700
    93  	E_INVALID_REQ ErrorCode = -32600
    94  	E_NO_METHOD   ErrorCode = -32601
    95  	E_BAD_PARAMS  ErrorCode = -32602
    96  	E_INTERNAL    ErrorCode = -32603
    97  	E_SERVER      ErrorCode = -32000
    98  )
    99  
   100  var ErrNullResult = errors.New("result is null")
   101  
   102  type Error struct {
   103  	// A Number that indicates the error type that occurred.
   104  	Code ErrorCode `json:"code"` /* required */
   105  
   106  	// A String providing a short description of the error.
   107  	// The message SHOULD be limited to a concise single sentence.
   108  	Message string `json:"message"` /* required */
   109  
   110  	// A Primitive or Structured value that contains additional information about the error.
   111  	Data interface{} `json:"data"` /* optional */
   112  }
   113  
   114  func (e *Error) Error() string {
   115  	return e.Message
   116  }