diff --git a/go.mod b/go.mod index fc83e42..3db9611 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,6 @@ require ( github.com/gofrs/uuid/v5 v5.3.2 github.com/golang-migrate/migrate/v4 v4.18.2 github.com/gophercloud/gophercloud/v2 v2.6.0 - github.com/gorilla/mux v1.8.1 github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/hashicorp/vault/api v1.16.0 github.com/lib/pq v1.10.9 diff --git a/go.sum b/go.sum index 34bf197..4a897e1 100644 --- a/go.sum +++ b/go.sum @@ -49,8 +49,6 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/gophercloud/gophercloud/v2 v2.6.0 h1:XJKQ0in3iHOZHVAFMXq/OhjCuvvG+BKR0unOqRfG1EI= github.com/gophercloud/gophercloud/v2 v2.6.0/go.mod h1:Ki/ILhYZr/5EPebrPL9Ej+tUg4lqx71/YH2JWVeU+Qk= -github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= -github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= diff --git a/httpapi/api.go b/httpapi/api.go index 6a56a76..f76cabe 100644 --- a/httpapi/api.go +++ b/httpapi/api.go @@ -20,8 +20,6 @@ package httpapi import ( "net/http" - - "github.com/gorilla/mux" ) // API is the interface that applications can use to plug their own API @@ -32,7 +30,7 @@ import ( // "Without..." are available that apply to the entire http.Handler returned by // Compose(), instead of just adding endpoints to it. type API interface { - AddTo(r *mux.Router) + AddTo(r *http.ServeMux) } // HealthCheckAPI is an API with one endpoint, "GET /healthcheck", that @@ -46,8 +44,8 @@ type HealthCheckAPI struct { } // AddTo implements the API interface. -func (h HealthCheckAPI) AddTo(r *mux.Router) { - r.Methods("GET", "HEAD").Path("/healthcheck").HandlerFunc(h.handleRequest) +func (h HealthCheckAPI) AddTo(s *http.ServeMux) { + s.HandleFunc("GET /healthcheck", h.handleRequest) } func (h HealthCheckAPI) handleRequest(w http.ResponseWriter, r *http.Request) { @@ -74,7 +72,7 @@ type pseudoAPI struct { configure func(*middleware) } -func (p pseudoAPI) AddTo(r *mux.Router) { +func (p pseudoAPI) AddTo(r *http.ServeMux) { // no-op, see above } diff --git a/httpapi/compose.go b/httpapi/compose.go index be9a327..2c9312a 100644 --- a/httpapi/compose.go +++ b/httpapi/compose.go @@ -20,8 +20,6 @@ package httpapi import ( "net/http" - - "github.com/gorilla/mux" ) // Compose constructs an http.Handler serving all the provided APIs. The Handler @@ -30,7 +28,7 @@ import ( func Compose(apis ...API) http.Handler { autoConfigureMetricsIfNecessary() - r := mux.NewRouter() + r := http.NewServeMux() m := middleware{inner: r} for _, a := range apis { diff --git a/httpapi/httpapi_test.go b/httpapi/httpapi_test.go index 7eca56a..ab4edb2 100644 --- a/httpapi/httpapi_test.go +++ b/httpapi/httpapi_test.go @@ -32,7 +32,6 @@ import ( "testing" "time" - "github.com/gorilla/mux" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" @@ -199,21 +198,19 @@ func TestMetrics(t *testing.T) { type metricsTestingAPI struct{} -func (m metricsTestingAPI) AddTo(r *mux.Router) { - r.Methods("POST").Path("/sleep/{secs}/return/{count}").HandlerFunc(m.handleRequest) +func (m metricsTestingAPI) AddTo(s *http.ServeMux) { + s.HandleFunc("POST /sleep/{secs}/return/{count}", m.handleRequest) } func (m metricsTestingAPI) handleRequest(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - - secs, err := strconv.ParseFloat(vars["secs"], 64) + secs, err := strconv.ParseFloat(r.PathValue("secs"), 64) if respondwith.ErrorText(w, err) { return } //NOTE: `time.Duration(secs)` does not work because all values < 1 would all be truncated to 0. time.Sleep(time.Duration(secs * float64(time.Second))) - count, err := strconv.Atoi(vars["count"]) + count, err := strconv.Atoi(r.PathValue("count")) if respondwith.ErrorText(w, err) { return } diff --git a/httpapi/pprofapi/pprofapi.go b/httpapi/pprofapi/pprofapi.go index b06a309..7bb8a28 100644 --- a/httpapi/pprofapi/pprofapi.go +++ b/httpapi/pprofapi/pprofapi.go @@ -30,8 +30,6 @@ import ( "os" "strconv" - "github.com/gorilla/mux" - "github.com/sapcc/go-bits/httpapi" "github.com/sapcc/go-bits/httpext" "github.com/sapcc/go-bits/logg" @@ -49,12 +47,12 @@ type API struct { } // AddTo implements the httpapi.API interface. -func (a API) AddTo(r *mux.Router) { +func (a API) AddTo(s *http.ServeMux) { if a.IsAuthorized == nil { panic("API.AddTo() called with IsAuthorized == nil!") } - r.Methods("GET").Path("/debug/pprof/{operation}").HandlerFunc(a.handler) + s.HandleFunc("GET /debug/pprof/{operation}", a.handler) } func (a API) handler(w http.ResponseWriter, r *http.Request) { @@ -65,7 +63,7 @@ func (a API) handler(w http.ResponseWriter, r *http.Request) { return } - switch mux.Vars(r)["operation"] { + switch r.PathValue("operation") { default: pprof.Index(w, r) case "cmdline": diff --git a/liquidapi/liquidapi.go b/liquidapi/liquidapi.go index 9f8f93f..7a2508e 100644 --- a/liquidapi/liquidapi.go +++ b/liquidapi/liquidapi.go @@ -31,7 +31,6 @@ import ( "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/openstack" - "github.com/gorilla/mux" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/sapcc/go-api-declarations/liquid" @@ -289,11 +288,11 @@ func limitRequestsMiddleware(maxRequests int) func(http.Handler) http.Handler { } // AddTo implements the httpapi.API interface. -func (rt *runtime) AddTo(r *mux.Router) { - r.Methods("GET").Path("/v1/info").HandlerFunc(rt.handleGetInfo) - r.Methods("POST").Path("/v1/report-capacity").HandlerFunc(rt.handleReportCapacity) - r.Methods("POST").Path("/v1/projects/{project_id}/report-usage").HandlerFunc(rt.handleReportUsage) - r.Methods("PUT").Path("/v1/projects/{project_id}/quota").HandlerFunc(rt.handleSetQuota) +func (rt *runtime) AddTo(s *http.ServeMux) { + s.HandleFunc("GET /v1/info", rt.handleGetInfo) + s.HandleFunc("POST /v1/report-capacity", rt.handleReportCapacity) + s.HandleFunc("POST /v1/projects/{project_id}/report-usage", rt.handleReportUsage) + s.HandleFunc("PUT /v1/projects/{project_id}/quota", rt.handleSetQuota) } func (rt *runtime) handleGetInfo(w http.ResponseWriter, r *http.Request) { @@ -328,14 +327,13 @@ func (rt *runtime) handleReportUsage(w http.ResponseWriter, r *http.Request) { if !rt.requireToken(w, r, "liquid:get_usage") { return } - vars := mux.Vars(r) var req liquid.ServiceUsageRequest if !requireJSON(w, r, &req) { return } - resp, err := rt.Logic.ScanUsage(r.Context(), vars["project_id"], req, rt.getServiceInfo()) + resp, err := rt.Logic.ScanUsage(r.Context(), r.PathValue("project_id"), req, rt.getServiceInfo()) if respondwith.ErrorText(w, err) { return } @@ -347,14 +345,13 @@ func (rt *runtime) handleSetQuota(w http.ResponseWriter, r *http.Request) { if !rt.requireToken(w, r, "liquid:set_quota") { return } - vars := mux.Vars(r) var req liquid.ServiceQuotaRequest if !requireJSON(w, r, &req) { return } - err := rt.Logic.SetQuota(r.Context(), vars["project_id"], req, rt.getServiceInfo()) + err := rt.Logic.SetQuota(r.Context(), r.PathValue("project_id"), req, rt.getServiceInfo()) if respondwith.ErrorText(w, err) { return } @@ -363,7 +360,7 @@ func (rt *runtime) handleSetQuota(w http.ResponseWriter, r *http.Request) { func (rt *runtime) requireToken(w http.ResponseWriter, r *http.Request, policyRule string) bool { t := rt.TokenValidator.CheckToken(r) - t.Context.Request = mux.Vars(r) + t.Context.LookupRequestValue = r.PathValue return t.Require(w, policyRule) }