From d8421bcddcfc93e38fc0b5f2d789b80bf329519b Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Thu, 16 Feb 2017 17:32:20 +0000 Subject: [PATCH] Add basic routing based on matched paths --- .../dendrite/clientapi/clientapi.go | 16 +----- .../dendrite/clientapi/routing/routing.go | 56 +++++++++++++++++++ 2 files changed, 58 insertions(+), 14 deletions(-) create mode 100644 src/github.com/matrix-org/dendrite/clientapi/routing/routing.go diff --git a/src/github.com/matrix-org/dendrite/clientapi/clientapi.go b/src/github.com/matrix-org/dendrite/clientapi/clientapi.go index 989dbf3b2..b646904d9 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/clientapi.go +++ b/src/github.com/matrix-org/dendrite/clientapi/clientapi.go @@ -1,31 +1,19 @@ package main import ( + "github.com/matrix-org/dendrite/clientapi/routing" "net/http" "os" log "github.com/Sirupsen/logrus" - - "github.com/matrix-org/dendrite/clientapi/readers" - "github.com/matrix-org/dendrite/clientapi/writers" - "github.com/matrix-org/util" - "github.com/prometheus/client_golang/prometheus" ) -// setup registers HTTP handlers with the given ServeMux. It also supplies the given http.Client -// to clients which need to make outbound HTTP requests. -func setup(mux *http.ServeMux, httpClient *http.Client) { - mux.Handle("/metrics", prometheus.Handler()) - mux.Handle("/api/send", prometheus.InstrumentHandler("send_message", util.MakeJSONAPI(&writers.SendMessage{}))) - mux.Handle("/api/sync", prometheus.InstrumentHandler("sync", util.MakeJSONAPI(&readers.Sync{}))) -} - func main() { bindAddr := os.Getenv("BIND_ADDRESS") if bindAddr == "" { log.Panic("No BIND_ADDRESS environment variable found.") } log.Info("Starting clientapi") - setup(http.DefaultServeMux, http.DefaultClient) + routing.Setup(http.DefaultServeMux, http.DefaultClient) log.Fatal(http.ListenAndServe(bindAddr, nil)) } diff --git a/src/github.com/matrix-org/dendrite/clientapi/routing/routing.go b/src/github.com/matrix-org/dendrite/clientapi/routing/routing.go new file mode 100644 index 000000000..177187a2b --- /dev/null +++ b/src/github.com/matrix-org/dendrite/clientapi/routing/routing.go @@ -0,0 +1,56 @@ +package routing + +import ( + "github.com/matrix-org/dendrite/clientapi/readers" + _ "github.com/matrix-org/dendrite/clientapi/writers" + "github.com/matrix-org/util" + "github.com/prometheus/client_golang/prometheus" + "net/http" + "strings" +) + +const pathPrefixR0 = "/_matrix/client/r0" + +// Return true if this path should be handled by this handler +type matcher func(path string) bool + +type lookup struct { + Matches matcher + Handler http.Handler +} + +func newLookup(name string, m matcher, h util.JSONRequestHandler) lookup { + return lookup{ + Matches: m, + Handler: prometheus.InstrumentHandler(name, util.MakeJSONAPI(h)), + } +} + +func matchesString(str string) func(path string) bool { + return func(path string) bool { + return path == str + } +} + +// Setup registers HTTP handlers with the given ServeMux. It also supplies the given http.Client +// to clients which need to make outbound HTTP requests. +func Setup(mux *http.ServeMux, httpClient *http.Client) { + var r0lookups []lookup + r0lookups = append(r0lookups, newLookup("sync", matchesString("/sync"), &readers.Sync{})) + + mux.Handle("/metrics", prometheus.Handler()) + mux.HandleFunc("/api/", func(w http.ResponseWriter, req *http.Request) { + clientServerPath := strings.TrimPrefix(req.URL.Path, "/api") + if strings.HasPrefix(clientServerPath, pathPrefixR0) { + apiPath := strings.TrimPrefix(clientServerPath, pathPrefixR0) + for _, lookup := range r0lookups { + if lookup.Matches(apiPath) { + lookup.Handler.ServeHTTP(w, req) + return + } + } + } + w.WriteHeader(404) + w.Write([]byte(`{"error":"Not found","errcode":"M_NOT_FOUND"}`)) + }) +}