@ -12,16 +12,32 @@ import (
"time"
"github.com/pkg/errors"
"golang.org/x/net/netutil"
types "github.com/tendermint/tendermint/rpc/lib/types"
"github.com/tendermint/tmlibs/log"
)
func StartHTTPServer ( listenAddr string , handler http . Handler , logger log . Logger ) ( listener net . Listener , err error ) {
// Config is an RPC server configuration.
type Config struct {
MaxOpenConnections int
}
// StartHTTPServer starts an HTTP server on listenAddr with the given handler.
// It wraps handler with RecoverAndLogHandler.
func StartHTTPServer (
listenAddr string ,
handler http . Handler ,
logger log . Logger ,
config Config ,
) ( listener net . Listener , err error ) {
var proto , addr string
parts := strings . SplitN ( listenAddr , "://" , 2 )
if len ( parts ) != 2 {
return nil , errors . Errorf ( "Invalid listening address %s (use fully formed addresses, including the tcp:// or unix:// prefix)" , listenAddr )
return nil , errors . Errorf (
"Invalid listening address %s (use fully formed addresses, including the tcp:// or unix:// prefix)" ,
listenAddr ,
)
}
proto , addr = parts [ 0 ] , parts [ 1 ]
@ -30,6 +46,9 @@ func StartHTTPServer(listenAddr string, handler http.Handler, logger log.Logger)
if err != nil {
return nil , errors . Errorf ( "Failed to listen on %v: %v" , listenAddr , err )
}
if config . MaxOpenConnections > 0 {
listener = netutil . LimitListener ( listener , config . MaxOpenConnections )
}
go func ( ) {
err := http . Serve (
@ -41,19 +60,41 @@ func StartHTTPServer(listenAddr string, handler http.Handler, logger log.Logger)
return listener , nil
}
func StartHTTPAndTLSServer ( listenAddr string , handler http . Handler , certFile , keyFile string , logger log . Logger ) ( listener net . Listener , err error ) {
// StartHTTPAndTLSServer starts an HTTPS server on listenAddr with the given
// handler.
// It wraps handler with RecoverAndLogHandler.
func StartHTTPAndTLSServer (
listenAddr string ,
handler http . Handler ,
certFile , keyFile string ,
logger log . Logger ,
config Config ,
) ( listener net . Listener , err error ) {
var proto , addr string
parts := strings . SplitN ( listenAddr , "://" , 2 )
if len ( parts ) != 2 {
return nil , errors . Errorf ( "Invalid listening address %s (use fully formed addresses, including the tcp:// or unix:// prefix)" , listenAddr )
return nil , errors . Errorf (
"Invalid listening address %s (use fully formed addresses, including the tcp:// or unix:// prefix)" ,
listenAddr ,
)
}
proto , addr = parts [ 0 ] , parts [ 1 ]
logger . Info ( fmt . Sprintf ( "Starting RPC HTTPS server on %s (cert: %q, key: %q)" , listenAddr , certFile , keyFile ) )
logger . Info (
fmt . Sprintf (
"Starting RPC HTTPS server on %s (cert: %q, key: %q)" ,
listenAddr ,
certFile ,
keyFile ,
) ,
)
listener , err = net . Listen ( proto , addr )
if err != nil {
return nil , errors . Errorf ( "Failed to listen on %v: %v" , listenAddr , err )
}
if config . MaxOpenConnections > 0 {
listener = netutil . LimitListener ( listener , config . MaxOpenConnections )
}
go func ( ) {
err := http . ServeTLS (
@ -67,7 +108,11 @@ func StartHTTPAndTLSServer(listenAddr string, handler http.Handler, certFile, ke
return listener , nil
}
func WriteRPCResponseHTTPError ( w http . ResponseWriter , httpCode int , res types . RPCResponse ) {
func WriteRPCResponseHTTPError (
w http . ResponseWriter ,
httpCode int ,
res types . RPCResponse ,
) {
jsonBytes , err := json . MarshalIndent ( res , "" , " " )
if err != nil {
panic ( err )
@ -117,7 +162,10 @@ func RecoverAndLogHandler(handler http.Handler, logger log.Logger) http.Handler
WriteRPCResponseHTTP ( rww , res )
} else {
// For the rest,
logger . Error ( "Panic in RPC HTTP handler" , "err" , e , "stack" , string ( debug . Stack ( ) ) )
logger . Error (
"Panic in RPC HTTP handler" , "err" , e , "stack" ,
string ( debug . Stack ( ) ) ,
)
rww . WriteHeader ( http . StatusInternalServerError )
WriteRPCResponseHTTP ( rww , types . RPCInternalError ( "" , e . ( error ) ) )
}