go-ethereum/consensus/bor/rest.go
2020-02-10 19:30:09 +05:30

87 lines
1.8 KiB
Go

package bor
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"path"
"time"
"github.com/maticnetwork/bor/log"
)
// ResponseWithHeight defines a response object type that wraps an original
// response with a height.
type ResponseWithHeight struct {
Height string `json:"height"`
Result json.RawMessage `json:"result"`
}
// internal fetch method
func internalFetch(client http.Client, u *url.URL) (*ResponseWithHeight, error) {
res, err := client.Get(u.String())
if err != nil {
return nil, err
}
defer res.Body.Close()
// check status code
if res.StatusCode != 200 {
return nil, fmt.Errorf("Error while fetching data from Heimdall")
}
// get response
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
// unmarshall data from buffer
var response ResponseWithHeight
if err := json.Unmarshal(body, &response); err != nil {
return nil, err
}
return &response, nil
}
// FetchFromHeimdallWithRetry returns data from heimdall with retry
func FetchFromHeimdallWithRetry(client http.Client, urlString string, paths ...string) (*ResponseWithHeight, error) {
u, err := url.Parse(urlString)
if err != nil {
return nil, err
}
for _, e := range paths {
if e != "" {
u.Path = path.Join(u.Path, e)
}
}
for {
res, err := internalFetch(client, u)
if err == nil && res != nil {
return res, nil
}
log.Info("Retrying again in 5 seconds for next Heimdall span", u.Path)
time.Sleep(5 * time.Second)
}
}
// FetchFromHeimdall returns data from heimdall
func FetchFromHeimdall(client http.Client, urlString string, paths ...string) (*ResponseWithHeight, error) {
u, err := url.Parse(urlString)
if err != nil {
return nil, err
}
for _, e := range paths {
if e != "" {
u.Path = path.Join(u.Path, e)
}
}
return internalFetch(client, u)
}