Skip to content

Commit

Permalink
feat: add proxy for unhandled requests (#67)
Browse files Browse the repository at this point in the history
  • Loading branch information
javiersuweijie authored Jan 7, 2023
1 parent 77bb98e commit 62ca995
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 0 deletions.
7 changes: 7 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type Config struct {
ChainID string
RPCEndpoints []string
WSEndpoints []string
LCDEndpoints []string
MantlemintDB string
IndexerDB string
DisableSync bool
Expand Down Expand Up @@ -67,6 +68,12 @@ func newConfig() Config {
return strings.Split(endpoints, ",")
}(),

// LCDEndpoints is where to forward unhandled queries to a node
LCDEndpoints: func() []string {
endpoints := getValidEnv("LCD_ENDPOINTS")
return strings.Split(endpoints, ",")
}(),

// MantlemintDB is the db name for mantlemint. Defaults to mantlemint
MantlemintDB: func() string {
mantlemintDB := getValidEnv("MANTLEMINT_DB")
Expand Down
43 changes: 43 additions & 0 deletions rpc/proxy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package rpc

import (
"github.com/tendermint/tendermint/libs/rand"
"net/http"
"net/http/httptest"
"net/http/httputil"
"net/url"
)

type ProxyMiddleware struct {
lcdUrls []string
proxies []*httputil.ReverseProxy
}

func NewProxyMiddleware(lcdUrls []string) ProxyMiddleware {
var proxies []*httputil.ReverseProxy
for _, u := range lcdUrls {
lcdUrl, err := url.Parse(u)
if err != nil {
panic(err)
}
proxies = append(proxies, httputil.NewSingleHostReverseProxy(lcdUrl))
}
return ProxyMiddleware{
lcdUrls: lcdUrls,
proxies: proxies,
}
}

func (pm ProxyMiddleware) HandleRequest(writer http.ResponseWriter, request *http.Request, handler http.Handler) {
recorder := httptest.NewRecorder()
handler.ServeHTTP(recorder, request)
if recorder.Code != http.StatusOK {
// randomly pick a proxy from the list
proxyToUse := rand.NewRand().Intn(len(pm.proxies))
pm.proxies[proxyToUse].ServeHTTP(writer, request)
return
}
writer.WriteHeader(recorder.Code)
writer.Write(recorder.Body.Bytes())
return
}
8 changes: 8 additions & 0 deletions rpc/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,14 @@ func StartRPC(
})
})

pm := NewProxyMiddleware(mantlemintConfig.LCDEndpoints)
// proxy middleware to handle unimplemented queries
apiSrv.Router.Use(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
pm.HandleRequest(writer, request, next)
})
})

// start api server in goroutine
go func() {
if err := apiSrv.Start(cfg); err != nil {
Expand Down

0 comments on commit 62ca995

Please sign in to comment.