From be97a9430ad23752d8c345cf332a24806aa415be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Fri, 29 Sep 2017 08:34:07 +0100 Subject: [PATCH] main: register net/http/pprof on reloads too We didn't need to in the past as we layered the routers, meaning that we never fully replaced the main router. Now that we do, we must set it up. Otherwise, its routes will be 404s after any reload. Do it in loadAPIEndpoints, since it is run in the same scenarios and we want to put the pprof stuff in the control router anyway, since it's Tyk's endpoint and not the user's. Add a test too, ensuring that it survives reloads and that it won't be on the non-control router. Also a small file closing fix. --- gateway_test.go | 16 ++++++++++++++++ main.go | 27 ++++++++++++++------------- mw_js_plugin.go | 2 +- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/gateway_test.go b/gateway_test.go index 9803c628ebc..c85920116af 100644 --- a/gateway_test.go +++ b/gateway_test.go @@ -935,6 +935,22 @@ func TestControlListener(t *testing.T) { testHttp(t, tests, true) } +func TestHttpPprof(t *testing.T) { + old := httpProfile + defer func() { httpProfile = old }() + + testHttp(t, []tykHttpTest{ + {method: "GET", path: "/debug/pprof/", code: 404}, + {method: "GET", path: "/debug/pprof/", code: 404, controlRequest: true}, + }, true) + httpProfile = true + doReload() + testHttp(t, []tykHttpTest{ + {method: "GET", path: "/debug/pprof/", code: 404}, + {method: "GET", path: "/debug/pprof/", code: 200, controlRequest: true}, + }, true) +} + func TestManagementNodeRedisEvents(t *testing.T) { defer func() { config.Global.ManagementNode = false diff --git a/main.go b/main.go index 7e6064444d3..4a31af15cb1 100644 --- a/main.go +++ b/main.go @@ -284,16 +284,22 @@ func loadAPIEndpoints(muxer *mux.Router) { if config.Global.ControlAPIHostname != "" { hostname = config.Global.ControlAPIHostname } - r := mux.NewRouter() - muxer.PathPrefix("/tyk/").Handler(http.StripPrefix("/tyk", - checkIsAPIOwner(InstrumentationMW(r)), - )) + var subr *mux.Router if hostname != "" { - r = r.Host(hostname).Subrouter() + subr = muxer.Host(hostname).Subrouter() log.WithFields(logrus.Fields{ "prefix": "main", }).Info("Control API hostname set: ", hostname) + } else { + subr = muxer.NewRoute().Subrouter() } + if httpProfile { + subr.HandleFunc("/debug/pprof/{_:.*}", pprof_http.Index) + } + r := mux.NewRouter() + subr.PathPrefix("/tyk/").Handler(http.StripPrefix("/tyk", + checkIsAPIOwner(InstrumentationMW(r)), + )) log.WithFields(logrus.Fields{ "prefix": "main", }).Info("Initialising Tyk REST API Endpoints") @@ -1010,7 +1016,10 @@ func main() { time.Sleep(time.Second) } +var httpProfile = false + func start(arguments map[string]interface{}) { + httpProfile = arguments["--httpprofile"] == true if arguments["--memprofile"] == true { log.WithFields(logrus.Fields{ "prefix": "main", @@ -1032,13 +1041,6 @@ func start(arguments map[string]interface{}) { pprof.StartCPUProfile(cpuProfFile) defer pprof.StopCPUProfile() } - if arguments["--httpprofile"] == true { - log.WithFields(logrus.Fields{ - "prefix": "main", - }).Debug("Adding pprof endpoints") - - mainRouter.HandleFunc("/debug/pprof/{_:.*}", pprof_http.Index) - } // Set up a default org manager so we can traverse non-live paths if !config.Global.SupressDefaultOrgStore { @@ -1050,7 +1052,6 @@ func start(arguments map[string]interface{}) { //DefaultQuotaStore.Init(getGlobalStorageHandler(CloudHandler, "orgkey.", false)) DefaultQuotaStore.Init(getGlobalStorageHandler("orgkey.", false)) } - if config.Global.ControlAPIPort == 0 { loadAPIEndpoints(mainRouter) } diff --git a/mw_js_plugin.go b/mw_js_plugin.go index 7cd798e7273..3419533974c 100644 --- a/mw_js_plugin.go +++ b/mw_js_plugin.go @@ -295,13 +295,13 @@ func (j *JSVM) Init() { }).Error("Could not open TykJS: ", err) return } + defer f.Close() if _, err := vm.Run(f); err != nil { log.WithFields(logrus.Fields{ "prefix": "jsvm", }).Error("Could not load TykJS: ", err) return } - f.Close() j.VM = vm