Unhack dealing with slashed in node names.

This commit is contained in:
Tom Wilkie
2016-04-06 14:35:41 +01:00
parent 50c8449c20
commit fd368e5e5f
6 changed files with 47 additions and 60 deletions

View File

@@ -12,8 +12,9 @@ import (
)
func topologyServer() *httptest.Server {
handler := app.TopologyHandler(StaticReport{}, mux.NewRouter(), nil)
return httptest.NewServer(handler)
router := mux.NewRouter()
app.RegisterTopologyRoutes(StaticReport{}, router)
return httptest.NewServer(router)
}
func TestAPIReport(t *testing.T) {

View File

@@ -307,9 +307,9 @@ func (r *registry) captureRenderer(rep Reporter, f reportRenderHandler) CtxHandl
}
}
func (r *registry) captureRendererWithoutFilters(rep Reporter, topologyID string, f reportRenderHandler) CtxHandlerFunc {
func (r *registry) captureRendererWithoutFilters(rep Reporter, f reportRenderHandler) CtxHandlerFunc {
return func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
topology, ok := r.get(topologyID)
topology, ok := r.get(mux.Vars(req)["topology"])
if !ok {
http.NotFound(w, req)
return

View File

@@ -54,8 +54,8 @@ func TestAPITopologyAddsKubernetes(t *testing.T) {
router := mux.NewRouter()
c := app.NewCollector(1 * time.Minute)
app.RegisterReportPostHandler(c, router)
handler := app.TopologyHandler(c, router, nil)
ts := httptest.NewServer(handler)
app.RegisterTopologyRoutes(c, router)
ts := httptest.NewServer(router)
defer ts.Close()
body := getRawJSON(t, ts, "/api/topology")

View File

@@ -5,6 +5,7 @@ import (
"time"
log "github.com/Sirupsen/logrus"
"github.com/gorilla/mux"
"golang.org/x/net/context"
"github.com/weaveworks/scope/common/xfer"
@@ -56,23 +57,24 @@ func handleWs(ctx context.Context, rep Reporter, renderer render.Renderer, w htt
}
// Individual nodes.
func handleNode(topologyID, nodeID string) func(context.Context, Reporter, render.Renderer, http.ResponseWriter, *http.Request) {
return func(ctx context.Context, rep Reporter, renderer render.Renderer, w http.ResponseWriter, r *http.Request) {
var (
report, err = rep.Report(ctx)
rendered = renderer.Render(report)
node, ok = rendered[nodeID]
)
if err != nil {
respondWith(w, http.StatusInternalServerError, err.Error())
return
}
if !ok {
http.NotFound(w, r)
return
}
respondWith(w, http.StatusOK, APINode{Node: detailed.MakeNode(topologyID, report, rendered, node)})
func handleNode(ctx context.Context, rep Reporter, renderer render.Renderer, w http.ResponseWriter, r *http.Request) {
var (
vars = mux.Vars(r)
topologyID = vars["topology"]
nodeID = vars["id"]
report, err = rep.Report(ctx)
rendered = renderer.Render(report)
node, ok = rendered[nodeID]
)
if err != nil {
respondWith(w, http.StatusInternalServerError, err.Error())
return
}
if !ok {
http.NotFound(w, r)
return
}
respondWith(w, http.StatusOK, APINode{Node: detailed.MakeNode(topologyID, report, rendered, node)})
}
func handleWebsocket(

View File

@@ -88,44 +88,20 @@ func gzipHandler(h http.HandlerFunc) http.HandlerFunc {
// Routes which should be matched before the topology routes should be added
// to a router and passed in preRoutes. Routes to be matches after topology
// routes should be added to a router and passed to postRoutes.
func TopologyHandler(c Reporter, preRoutes *mux.Router, postRoutes http.Handler) http.Handler {
get := preRoutes.Methods("GET").Subrouter()
get.HandleFunc("/api", gzipHandler(requestContextDecorator(apiHandler)))
get.HandleFunc("/api/topology", gzipHandler(requestContextDecorator(topologyRegistry.makeTopologyList(c))))
func RegisterTopologyRoutes(router *mux.Router, r Reporter) {
get := router.Methods("GET").Subrouter()
get.HandleFunc("/api",
gzipHandler(requestContextDecorator(apiHandler)))
get.HandleFunc("/api/topology",
gzipHandler(requestContextDecorator(topologyRegistry.makeTopologyList(r))))
get.HandleFunc("/api/topology/{topology}",
gzipHandler(requestContextDecorator(topologyRegistry.captureRenderer(c, handleTopology))))
gzipHandler(requestContextDecorator(topologyRegistry.captureRenderer(r, handleTopology))))
get.HandleFunc("/api/topology/{topology}/ws",
requestContextDecorator(topologyRegistry.captureRenderer(c, handleWs))) // NB not gzip!
get.HandleFunc("/api/report", gzipHandler(requestContextDecorator(makeRawReportHandler(c))))
// We pull in the http.DefaultServeMux to get the pprof routes
preRoutes.PathPrefix("/debug/pprof").Handler(http.DefaultServeMux)
if postRoutes != nil {
preRoutes.PathPrefix("/").Handler(postRoutes)
}
// We have to handle the node details path manually due to
// various bugs in gorilla.mux and Go URL parsing. See #804.
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
vars, match := matchURL(r, "/api/topology/{topology}/{id}")
if !match {
preRoutes.ServeHTTP(w, r)
return
}
topologyID := vars["topology"]
nodeID := vars["id"]
if nodeID == "ws" {
preRoutes.ServeHTTP(w, r)
return
}
handler := gzipHandler(requestContextDecorator(topologyRegistry.captureRendererWithoutFilters(
c, topologyID, handleNode(topologyID, nodeID),
)))
handler.ServeHTTP(w, r)
})
requestContextDecorator(topologyRegistry.captureRenderer(r, handleWs))) // NB not gzip!
get.MatcherFunc(URLMatcher("/api/topology/{topology}/{id}")).HandlerFunc(
gzipHandler(requestContextDecorator(topologyRegistry.captureRendererWithoutFilters(r, handleNode))))
get.HandleFunc("/api/report",
gzipHandler(requestContextDecorator(makeRawReportHandler(r))))
}
// RegisterReportPostHandler registers the handler for report submission

View File

@@ -28,11 +28,19 @@ import (
// Router creates the mux for all the various app components.
func router(collector app.Collector, controlRouter app.ControlRouter, pipeRouter app.PipeRouter) http.Handler {
router := mux.NewRouter()
router := mux.NewRouter().SkipClean(true)
// We pull in the http.DefaultServeMux to get the pprof routes
router.PathPrefix("/debug/pprof").Handler(http.DefaultServeMux)
app.RegisterReportPostHandler(collector, router)
app.RegisterControlRoutes(router, controlRouter)
app.RegisterPipeRoutes(router, pipeRouter)
return app.TopologyHandler(collector, router, http.FileServer(FS(false)))
app.RegisterTopologyRoutes(router, collector)
router.PathPrefix("/").Handler(http.FileServer(FS(false)))
return router
}
func awsConfigFromURL(url *url.URL) *aws.Config {