From e12d46f619fe97aef1d90521cc8686c818166474 Mon Sep 17 00:00:00 2001 From: Dreamacro <305009791@qq.com> Date: Sat, 27 Oct 2018 12:36:33 +0800 Subject: [PATCH] Fix: unescape proxy name in /proixes --- hub/proxies.go | 26 ++++++++++++++++++++------ hub/server.go | 6 ++++++ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/hub/proxies.go b/hub/proxies.go index c0fe062ba..3a54ed8bf 100644 --- a/hub/proxies.go +++ b/hub/proxies.go @@ -1,8 +1,10 @@ package hub import ( + "context" "fmt" "net/http" + "net/url" "strconv" "time" @@ -16,12 +18,24 @@ import ( func proxyRouter() http.Handler { r := chi.NewRouter() r.Get("/", getProxies) - r.Get("/{name}", getProxy) - r.Get("/{name}/delay", getProxyDelay) - r.Put("/{name}", updateProxy) + r.With(parseProxyName).Get("/{name}", getProxy) + r.With(parseProxyName).Get("/{name}/delay", getProxyDelay) + r.With(parseProxyName).Put("/{name}", updateProxy) return r } +// When name is composed of a partial escape string, Golang does not unescape it +func parseProxyName(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + name := chi.URLParam(r, "name") + if newName, err := url.PathUnescape(name); err == nil { + name = newName + } + ctx := context.WithValue(r.Context(), contextKey("proxy name"), name) + next.ServeHTTP(w, r.WithContext(ctx)) + }) +} + type SampleProxy struct { Type string `json:"type"` } @@ -83,7 +97,7 @@ func getProxies(w http.ResponseWriter, r *http.Request) { } func getProxy(w http.ResponseWriter, r *http.Request) { - name := chi.URLParam(r, "name") + name := r.Context().Value(contextKey("proxy name")).(string) proxies := cfg.Proxies() proxy, exist := proxies[name] if !exist { @@ -110,7 +124,7 @@ func updateProxy(w http.ResponseWriter, r *http.Request) { return } - name := chi.URLParam(r, "name") + name := r.Context().Value(contextKey("proxy name")).(string) proxies := cfg.Proxies() proxy, exist := proxies[name] if !exist { @@ -162,7 +176,7 @@ func getProxyDelay(w http.ResponseWriter, r *http.Request) { return } - name := chi.URLParam(r, "name") + name := r.Context().Value(contextKey("proxy name")).(string) proxies := cfg.Proxies() proxy, exist := proxies[name] if !exist { diff --git a/hub/server.go b/hub/server.go index b85b9c2fa..304f991e8 100644 --- a/hub/server.go +++ b/hub/server.go @@ -100,6 +100,12 @@ func authentication(next http.Handler) http.Handler { return http.HandlerFunc(fn) } +type contextKey string + +func (c contextKey) String() string { + return "clash context key " + string(c) +} + func traffic(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK)