moonstream/nodes/node_balancer/cmd/routes.go

57 wiersze
1.5 KiB
Go

/*
Handle routes for load balancer API.
*/
package cmd
import (
"encoding/json"
"fmt"
"net/http"
"strings"
)
// pingRoute response with status of load balancer server itself
func pingRoute(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
response := PingResponse{Status: "ok"}
json.NewEncoder(w).Encode(response)
}
// lbHandler load balances the incoming requests to nodes
func lbHandler(w http.ResponseWriter, r *http.Request) {
var blockchain string
switch {
case strings.HasPrefix(r.URL.Path, "/lb/ethereum"):
blockchain = "ethereum"
case strings.HasPrefix(r.URL.Path, "/lb/polygon"):
blockchain = "polygon"
default:
http.Error(w, fmt.Sprintf("Unacceptable blockchain provided %s", blockchain), http.StatusBadRequest)
return
}
// Chose one node
peer := blockchainPool.GetNextPeer(blockchain)
if peer == nil {
http.Error(w, "There are no nodes available", http.StatusServiceUnavailable)
return
}
// Save origin path, to use in proxyErrorHandler if node will not response
r.Header.Add("X-Origin-Path", r.URL.Path)
switch {
case strings.HasPrefix(r.URL.Path, fmt.Sprintf("/lb/%s/ping", blockchain)):
r.URL.Path = "/ping"
peer.StatusReverseProxy.ServeHTTP(w, r)
return
case strings.HasPrefix(r.URL.Path, fmt.Sprintf("/lb/%s/rpc", blockchain)):
r.URL.Path = "/"
peer.GethReverseProxy.ServeHTTP(w, r)
return
default:
http.Error(w, fmt.Sprintf("Unacceptable path for %s blockchain %s", blockchain, r.URL.Path), http.StatusBadRequest)
return
}
}