From 7acfa6acbca9468fd0ab859774d1eab5534148d4 Mon Sep 17 00:00:00 2001 From: Shane Neuerburg Date: Fri, 11 Nov 2016 16:17:54 -0700 Subject: [PATCH] Set up JSON RPC and WebSocket URLs to be configurable This also allows the two URLs to be disabled entirely. Also in this commit is rudimentary basic auth support for WebSockets --- cmd/cgr-engine/cgr-engine.go | 2 ++ config/config.go | 8 ++++++++ config/config_defaults.go | 8 +++++--- config/libconfig_json.go | 2 ++ data/conf/cgrates/cgrates.json | 8 +++++--- utils/server.go | 32 ++++++++++++++++++++++++++------ 6 files changed, 48 insertions(+), 12 deletions(-) diff --git a/cmd/cgr-engine/cgr-engine.go b/cmd/cgr-engine/cgr-engine.go index 298999d99..0594ea60c 100644 --- a/cmd/cgr-engine/cgr-engine.go +++ b/cmd/cgr-engine/cgr-engine.go @@ -532,6 +532,8 @@ func startRpc(server *utils.Server, internalRaterChan, go server.ServeGOB(cfg.RPCGOBListen) go server.ServeHTTP( cfg.HTTPListen, + cfg.HTTPJsonRPCURL, + cfg.HTTPWSURL, cfg.HTTPUseBasicAuth, cfg.HTTPAuthUsers, ) diff --git a/config/config.go b/config/config.go index 7485a7395..63e33de3e 100644 --- a/config/config.go +++ b/config/config.go @@ -203,6 +203,8 @@ type CGRConfig struct { RPCJSONListen string // RPC JSON listening address RPCGOBListen string // RPC GOB listening address HTTPListen string // HTTP listening address + HTTPJsonRPCURL string // JSON RPC relative URL ("" to disable) + HTTPWSURL string // WebSocket relative URL ("" to disable) HTTPUseBasicAuth bool // Use basic auth for HTTP API HTTPAuthUsers map[string]string // Basic auth user:password map (base64 passwords) DefaultReqType string // Use this request type if not defined on top @@ -787,6 +789,12 @@ func (self *CGRConfig) loadFromJsonCfg(jsnCfg *CgrJsonCfg) error { } if jsnHttpCfg != nil { + if jsnHttpCfg.Json_rpc_url != nil { + self.HTTPJsonRPCURL = *jsnHttpCfg.Json_rpc_url + } + if jsnHttpCfg.Ws_url != nil { + self.HTTPWSURL = *jsnHttpCfg.Ws_url + } if jsnHttpCfg.Use_basic_auth != nil { self.HTTPUseBasicAuth = *jsnHttpCfg.Use_basic_auth } diff --git a/config/config_defaults.go b/config/config_defaults.go index 280002de6..ce0b5b7cd 100644 --- a/config/config_defaults.go +++ b/config/config_defaults.go @@ -72,9 +72,11 @@ const CGRATES_CFG_JSON = ` }, -"http": { // HTTP API configuration - "use_basic_auth": false, // use basic authentication - "auth_users": {} // basic authentication usernames and base64-encoded passwords (eg: { "username1": "cGFzc3dvcmQ=", "username2": "cGFzc3dvcmQy "}) +"http": { // HTTP API configuration + "json_rpc_url": "/jsonrpc", // JSON RPC relative URL ("" to disable) + "ws_url": "/ws", // WebSockets relative URL ("" to disable) + "use_basic_auth": false, // use basic authentication + "auth_users": {} // basic authentication usernames and base64-encoded passwords (eg: { "username1": "cGFzc3dvcmQ=", "username2": "cGFzc3dvcmQy "}) }, diff --git a/config/libconfig_json.go b/config/libconfig_json.go index c2aee8e17..37890fe97 100644 --- a/config/libconfig_json.go +++ b/config/libconfig_json.go @@ -48,6 +48,8 @@ type ListenJsonCfg struct { // HTTP config section type HTTPJsonCfg struct { + Json_rpc_url *string + Ws_url *string Use_basic_auth *bool Auth_users *map[string]string } diff --git a/data/conf/cgrates/cgrates.json b/data/conf/cgrates/cgrates.json index 710f062d8..5cd043eb3 100644 --- a/data/conf/cgrates/cgrates.json +++ b/data/conf/cgrates/cgrates.json @@ -51,9 +51,11 @@ // }, -// "http": { // HTTP API configuration -// "use_basic_auth": false, // use basic authentication -// "auth_users": {} // basic authentication usernames and base64-encoded passwords (eg: { "username1": "cGFzc3dvcmQ=", "username2": "cGFzc3dvcmQy "}) +// "http": { // HTTP API configuration +// "json_rpc_url": "/jsonrpc", // JSON RPC relative URL ("" to disable) +// "ws_url": "/ws", // WebSockets relative URL ("" to disable) +// "use_basic_auth": false, // use basic authentication +// "auth_users": {} // basic authentication usernames and base64-encoded passwords (eg: { "username1": "cGFzc3dvcmQ=", "username2": "cGFzc3dvcmQy "}) // }, diff --git a/utils/server.go b/utils/server.go index 14d510485..6b506256c 100644 --- a/utils/server.go +++ b/utils/server.go @@ -29,9 +29,12 @@ import ( "reflect" "time" + "golang.org/x/net/websocket" + "github.com/cenk/rpc2" + + _ "net/http/pprof" ) -import _ "net/http/pprof" type Server struct { rpcEnabled bool @@ -146,19 +149,36 @@ func handleRequest(w http.ResponseWriter, r *http.Request) { io.Copy(w, res) } -func (s *Server) ServeHTTP(addr string, useBasicAuth bool, userList map[string]string) { - if s.rpcEnabled { +func (s *Server) ServeHTTP(addr string, jsonRPCURL string, wsRPCURL string, useBasicAuth bool, userList map[string]string) { + if s.rpcEnabled && jsonRPCURL != "" { + s.httpEnabled = true if useBasicAuth { Logger.Info("Configuring CGRateS HTTP server to use basic auth") - http.HandleFunc("/jsonrpc", use(handleRequest, basicAuth(userList))) + http.HandleFunc(jsonRPCURL, use(handleRequest, basicAuth(userList))) } else { - http.HandleFunc("/jsonrpc", handleRequest) + http.HandleFunc(jsonRPCURL, handleRequest) } - s.httpEnabled = true } + + if s.rpcEnabled && wsRPCURL != "" { + s.httpEnabled = true + Logger.Info("Configuring CGRateS HTTP server to handle WebSocket connections") + wsHandler := websocket.Handler(func(ws *websocket.Conn) { + jsonrpc.ServeConn(ws) + }) + if useBasicAuth { + http.HandleFunc(wsRPCURL, use(func(w http.ResponseWriter, r *http.Request) { + wsHandler.ServeHTTP(w, r) + }, basicAuth(userList))) + } else { + http.Handle(wsRPCURL, wsHandler) + } + } + if !s.httpEnabled { return } + Logger.Info(fmt.Sprintf("Starting CGRateS HTTP server at %s.", addr)) http.ListenAndServe(addr, nil) }