Skip to content

Commit

Permalink
Hacky fix for /%2F bug
Browse files Browse the repository at this point in the history
  • Loading branch information
tomwilkie committed Jan 11, 2016
1 parent 35b6a10 commit 505f39e
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 23 deletions.
10 changes: 8 additions & 2 deletions app/api_report_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package app_test

import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"

Expand All @@ -13,8 +14,13 @@ import (

func topologyServer() *httptest.Server {
router := mux.NewRouter()
app.RegisterTopologyRoutes(StaticReport{}, router)
return httptest.NewServer(router)
collector := StaticReport{}
app.RegisterTopologyRoutes(collector, router)
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !app.HandleNode(collector, w, r) {
router.ServeHTTP(w, r)
}
}))
}

func TestAPIReport(t *testing.T) {
Expand Down
4 changes: 2 additions & 2 deletions app/api_topologies.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,9 @@ func (r *registry) captureRenderer(rep Reporter, f reportRenderHandler) http.Han
}
}

func (r *registry) captureRendererWithoutFilters(rep Reporter, f reportRenderHandler) http.HandlerFunc {
func (r *registry) captureRendererWithoutFilters(rep Reporter, topologyID string, f reportRenderHandler) http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
topology, ok := r.get(mux.Vars(req)["topology"])
topology, ok := r.get(topologyID)
if !ok {
http.NotFound(w, req)
return
Expand Down
23 changes: 11 additions & 12 deletions app/api_topology.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"net/http"
"time"

"github.com/gorilla/mux"
"github.com/gorilla/websocket"

"github.com/weaveworks/scope/render"
Expand Down Expand Up @@ -50,18 +49,18 @@ func handleWs(rep Reporter, renderer render.Renderer, w http.ResponseWriter, r *
}

// Individual nodes.
func handleNode(rep Reporter, renderer render.Renderer, w http.ResponseWriter, r *http.Request) {
var (
vars = mux.Vars(r)
nodeID = vars["id"]
rpt = rep.Report()
node, ok = renderer.Render(rep.Report())[nodeID]
)
if !ok {
http.NotFound(w, r)
return
func handleNode(nodeID string) func(Reporter, render.Renderer, http.ResponseWriter, *http.Request) {
return func(rep Reporter, renderer render.Renderer, w http.ResponseWriter, r *http.Request) {
var (
rpt = rep.Report()
node, ok = renderer.Render(rep.Report())[nodeID]
)
if !ok {
http.NotFound(w, r)
return
}
respondWith(w, http.StatusOK, APINode{Node: render.MakeDetailedNode(rpt, node)})
}
respondWith(w, http.StatusOK, APINode{Node: render.MakeDetailedNode(rpt, node)})
}

var upgrader = websocket.Upgrader{
Expand Down
21 changes: 19 additions & 2 deletions app/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,28 @@ func RegisterTopologyRoutes(c Reporter, router *mux.Router) {
gzipHandler(topologyRegistry.captureRenderer(c, handleTopology)))
get.HandleFunc("/api/topology/{topology}/ws",
topologyRegistry.captureRenderer(c, handleWs)) // NB not gzip!
get.MatcherFunc(URLMatcher("/api/topology/{topology}/{id}")).HandlerFunc(
gzipHandler(topologyRegistry.captureRendererWithoutFilters(c, handleNode)))
get.HandleFunc("/api/report", gzipHandler(makeRawReportHandler(c)))
}

// HandleNode - Special case handling for some paths that go & gorilla choke on.
// Should be called before deferring to the router for the rest. Returns true
// means the request has been handled.
func HandleNode(c Reporter, w http.ResponseWriter, r *http.Request) bool {
matcher := URLMatcher("/api/topology/{topology}/{id}")
rm := mux.RouteMatch{}
if !matcher(r, &rm) {
return false
}
topologyID := rm.Vars["topology"]
nodeID := rm.Vars["id"]
if nodeID == "ws" {
return false
}
handler := gzipHandler(topologyRegistry.captureRendererWithoutFilters(c, topologyID, handleNode(nodeID)))
handler.ServeHTTP(w, r)
return true
}

// RegisterReportPostHandler registers the handler for report submission
func RegisterReportPostHandler(a Adder, router *mux.Router) {
post := router.Methods("POST").Subrouter()
Expand Down
17 changes: 12 additions & 5 deletions prog/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,21 @@ import (
)

// Router creates the mux for all the various app components.
func router(c app.Collector) *mux.Router {
func router(c app.Collector) http.Handler {
router := mux.NewRouter()
app.RegisterTopologyRoutes(c, router)
app.RegisterReportPostHandler(c, router)
app.RegisterControlRoutes(router)
app.RegisterPipeRoutes(router)
app.RegisterTopologyRoutes(c, router)
router.Methods("GET").PathPrefix("/").Handler(http.FileServer(FS(false)))
return router

// need to handle some routes in a completely custom way, because
// https://github.com/weaveworks/scope/issues/804
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !app.HandleNode(c, w, r) {
router.ServeHTTP(w, r)
}
})
}

// Main runs the app
Expand All @@ -48,10 +55,10 @@ func appMain() {
app.UniqueID = strconv.FormatInt(rand.Int63(), 16)
app.Version = version
log.Printf("app starting, version %s, ID %s", app.Version, app.UniqueID)
http.Handle("/", router(app.NewCollector(*window)))
handler := router(app.NewCollector(*window))
go func() {
log.Printf("listening on %s", *listen)
log.Print(http.ListenAndServe(*listen, nil))
log.Print(http.ListenAndServe(*listen, handler))
}()

common.SignalHandlerLoop()
Expand Down

0 comments on commit 505f39e

Please sign in to comment.