Handle invalid json returned from backend

This commit is contained in:
Martin Boehm 2018-06-13 11:58:25 +02:00
parent 5da3972d73
commit e7e73947bd

View File

@ -694,6 +694,25 @@ func (b *BitcoinRPC) GetMempoolEntry(txid string) (*bchain.MempoolEntry, error)
return res.Result, nil return res.Result, nil
} }
func safeDecodeResponse(body io.ReadCloser, res interface{}) (err error) {
var data []byte
defer func() {
if r := recover(); r != nil {
glog.Error("unmarshal json recovered from panic: ", r, "; data: ", string(data))
if len(data) > 0 && len(data) < 2048 {
err = errors.Errorf("Error: ", string(data))
} else {
err = errors.New("Internal error")
}
}
}()
data, err = ioutil.ReadAll(body)
if err != nil {
return err
}
return json.Unmarshal(data, &res)
}
func (b *BitcoinRPC) Call(req interface{}, res interface{}) error { func (b *BitcoinRPC) Call(req interface{}, res interface{}) error {
httpData, err := b.RPCMarshaler.Marshal(req) httpData, err := b.RPCMarshaler.Marshal(req)
if err != nil { if err != nil {
@ -713,19 +732,16 @@ func (b *BitcoinRPC) Call(req interface{}, res interface{}) error {
if err != nil { if err != nil {
return err return err
} }
// read the entire response body until the end to avoid memory leak when reusing http connection
// see http://devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang/
defer io.Copy(ioutil.Discard, httpRes.Body)
// if server returns HTTP error code it might not return json with response // if server returns HTTP error code it might not return json with response
// handle both cases // handle both cases
if httpRes.StatusCode != 200 { if httpRes.StatusCode != 200 {
err = json.NewDecoder(httpRes.Body).Decode(&res) err = safeDecodeResponse(httpRes.Body, &res)
if err != nil { if err != nil {
return errors.New(httpRes.Status) return errors.Errorf("%v %v", httpRes.Status, err)
} }
return nil return nil
} }
return json.NewDecoder(httpRes.Body).Decode(&res) return safeDecodeResponse(httpRes.Body, &res)
} }
// GetChainParser returns BlockChainParser // GetChainParser returns BlockChainParser