@ -6,11 +6,12 @@ import (
"encoding/json"
"encoding/json"
"errors"
"errors"
"fmt"
"fmt"
"html/template"
"io"
"io"
"net/http"
"net/http"
"reflect"
"reflect"
"sort"
"strconv"
"strconv"
"strings"
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/libs/log"
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
@ -222,40 +223,51 @@ func (z *int64String) UnmarshalText(data []byte) error {
// writes a list of available rpc endpoints as an html page
// writes a list of available rpc endpoints as an html page
func writeListOfEndpoints ( w http . ResponseWriter , r * http . Request , funcMap map [ string ] * RPCFunc ) {
func writeListOfEndpoints ( w http . ResponseWriter , r * http . Request , funcMap map [ string ] * RPCFunc ) {
noArgNames := [ ] string { }
argNames := [ ] string { }
for name , funcData := range funcMap {
if len ( funcData . args ) == 0 {
noArgNames = append ( noArgNames , name )
hasArgs := make ( map [ string ] string )
noArgs := make ( map [ string ] string )
for name , rf := range funcMap {
base := fmt . Sprintf ( "//%s/%s" , r . Host , name )
// N.B. Check argNames, not args, since the type list includes the type
// of the leading context argument.
if len ( rf . argNames ) == 0 {
noArgs [ name ] = base
} else {
} else {
argNames = append ( argNames , name )
}
}
sort . Strings ( noArgNames )
sort . Strings ( argNames )
buf := new ( bytes . Buffer )
buf . WriteString ( "<html><body>" )
buf . WriteString ( "<br>Available endpoints:<br>" )
for _ , name := range noArgNames {
link := fmt . Sprintf ( "//%s/%s" , r . Host , name )
buf . WriteString ( fmt . Sprintf ( "<a href=\"%s\">%s</a></br>" , link , link ) )
}
buf . WriteString ( "<br>Endpoints that require arguments:<br>" )
for _ , name := range argNames {
link := fmt . Sprintf ( "//%s/%s?" , r . Host , name )
funcData := funcMap [ name ]
for i , argName := range funcData . argNames {
link += argName + "=_"
if i < len ( funcData . argNames ) - 1 {
link += "&"
query := append ( [ ] string ( nil ) , rf . argNames ... )
for i , arg := range query {
query [ i ] = arg + "=_"
}
}
hasArgs [ name ] = base + "?" + strings . Join ( query , "&" )
}
}
buf . WriteString ( fmt . Sprintf ( "<a href=\"%s\">%s</a></br>" , link , link ) )
}
}
buf . WriteString ( "</body></html>" )
w . Header ( ) . Set ( "Content-Type" , "text/html" )
w . Header ( ) . Set ( "Content-Type" , "text/html" )
w . WriteHeader ( 200 )
w . Write ( buf . Bytes ( ) ) // nolint: errcheck
_ = listOfEndpoints . Execute ( w , map [ string ] map [ string ] string {
"NoArgs" : noArgs ,
"HasArgs" : hasArgs ,
} )
}
}
var listOfEndpoints = template . Must ( template . New ( "list" ) . Parse ( ` < html >
< head > < title > List of RPC Endpoints < / title > < / head >
< body >
< h1 > Available RPC endpoints : < / h1 >
{ { if . NoArgs } }
< hr / >
< h2 > Endpoints with no arguments : < / h2 >
< ul >
{ { range $ link := . NoArgs } } < li > < a href = "{{$link}}" > { { $ link } } < / a > < / li >
{ { end - } }
< / ul > { { end } }
{ { if . HasArgs } }
< hr / >
< h2 > Endpoints that require arguments : < / h2 >
< ul >
{ { range $ link := . HasArgs } } < li > < a href = "{{$link}}" > { { $ link } } < / a > < / li >
{ { end - } }
< / ul > { { end } }
< / body > < / html > ` ) )