github.com/okex/exchain@v1.8.0/libs/tendermint/rpc/jsonrpc/client/cm39_http_json_client.go (about) 1 package client 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "io/ioutil" 7 "net/http" 8 9 "github.com/okex/exchain/libs/cosmos-sdk/codec" 10 "github.com/okex/exchain/libs/cosmos-sdk/types/errors" 11 coretypes "github.com/okex/exchain/libs/tendermint/rpc/core/types" 12 "github.com/okex/exchain/libs/tendermint/rpc/jsonrpc/types" 13 ) 14 15 type decoder interface { 16 decode(cdc *codec.Codec, id types.JSONRPCIntID, data []byte, result interface{}) (interface{}, error) 17 } 18 19 type Cm39HttpJSONClientAdapter struct { 20 decoders map[string]decoder 21 *Client 22 } 23 24 func NewCm39HttpJSONClient(remote string, client *http.Client) (*Cm39HttpJSONClientAdapter, error) { 25 p, err := NewWithHTTPClient(remote, client) 26 if nil != err { 27 return nil, err 28 } 29 ret := &Cm39HttpJSONClientAdapter{Client: p} 30 ret.seal() 31 return ret, nil 32 } 33 34 var ( 35 _ decoder = (*defaultFuncDecoder)(nil) 36 ) 37 38 type defaultFuncDecoder struct { 39 secondChance func() interface{} 40 convSecondToFirst func(s interface{}, f interface{}) 41 } 42 43 func newDefaultFuncDecoder(secondChance func() interface{}, convSecondToFirst func(s interface{}, f interface{})) *defaultFuncDecoder { 44 return &defaultFuncDecoder{secondChance: secondChance, convSecondToFirst: convSecondToFirst} 45 } 46 47 func (d defaultFuncDecoder) decode(cdc *codec.Codec, id types.JSONRPCIntID, data []byte, result interface{}) (ret interface{}, err error) { 48 ret, err = unmarshalResponseBytes(cdc, data, id, result) 49 if nil == err { 50 return 51 } 52 another := d.secondChance() 53 ret2, err2 := unmarshalResponseBytes(cdc, data, id, another) 54 if nil != err2 { 55 err = errors.Wrap(err, "second error:"+err2.Error()) 56 return 57 } 58 d.convSecondToFirst(ret2, result) 59 ret = result 60 err = nil 61 return 62 } 63 64 func (c *Cm39HttpJSONClientAdapter) seal() { 65 c.decoders = make(map[string]decoder) 66 c.decoders["tx"] = newDefaultFuncDecoder(func() interface{} { 67 return new(CM39ResultTx) 68 }, func(s interface{}, f interface{}) { 69 cm39 := s.(*CM39ResultTx) 70 cm4 := f.(*coretypes.ResultTx) 71 ConvTCM392CM4(cm39, cm4) 72 }) 73 c.decoders["abci_query"] = newDefaultFuncDecoder(func() interface{} { 74 return new(CM39ResultABCIQuery) 75 }, func(s interface{}, f interface{}) { 76 cm39 := s.(*CM39ResultABCIQuery) 77 cm4 := f.(*coretypes.ResultABCIQuery) 78 ConvTCM39ResultABCIQuery2CM4(cm39, cm4) 79 }) 80 c.decoders["broadcast_tx_commit"] = newDefaultFuncDecoder(func() interface{} { 81 return new(CM39ResultBroadcastTxCommit) 82 }, func(s interface{}, f interface{}) { 83 cm39 := s.(*CM39ResultBroadcastTxCommit) 84 cm4 := f.(*coretypes.ResultBroadcastTxCommit) 85 ConvTCM39BroadcastCommitTx2CM4(cm39, cm4) 86 }) 87 c.decoders["block"] = newDefaultFuncDecoder(func() interface{} { 88 return new(coretypes.CM40ResultBlock) 89 }, func(s interface{}, f interface{}) { 90 cm4 := s.(*coretypes.CM40ResultBlock) 91 cm39 := f.(*coretypes.ResultBlock) 92 ret := cm4.ToCM39ResultBlock() 93 cm39.BlockID = ret.BlockID 94 cm39.Block = ret.Block 95 }) 96 } 97 98 func (c *Cm39HttpJSONClientAdapter) Call(method string, params map[string]interface{}, result interface{}) (ret interface{}, err error) { 99 return c.call(method, params, result, c.decoders[method]) 100 } 101 102 func (c *Cm39HttpJSONClientAdapter) call(method string, params map[string]interface{}, result interface{}, dec decoder) (interface{}, error) { 103 id := c.nextRequestID() 104 105 request, err := types.MapToRequest(c.cdc, id, method, params) 106 if err != nil { 107 return nil, errors.Wrap(err, "failed to encode params") 108 } 109 110 requestBytes, err := json.Marshal(request) 111 if err != nil { 112 return nil, errors.Wrap(err, "failed to marshal request") 113 } 114 115 requestBuf := bytes.NewBuffer(requestBytes) 116 httpRequest, err := http.NewRequest(http.MethodPost, c.address, requestBuf) 117 if err != nil { 118 return nil, errors.Wrap(err, "Request failed") 119 } 120 httpRequest.Header.Set("Content-Type", "text/json") 121 if c.username != "" || c.password != "" { 122 httpRequest.SetBasicAuth(c.username, c.password) 123 } 124 httpResponse, err := c.client.Do(httpRequest) 125 if err != nil { 126 return nil, errors.Wrap(err, "Post failed") 127 } 128 defer httpResponse.Body.Close() // nolint: errcheck 129 130 responseBytes, err := ioutil.ReadAll(httpResponse.Body) 131 if err != nil { 132 return nil, errors.Wrap(err, "failed to read response body") 133 } 134 135 if dec != nil { 136 return dec.decode(c.cdc, id, responseBytes, result) 137 } 138 return unmarshalResponseBytes(c.cdc, responseBytes, id, result) 139 }