From 65195a726d9ceff4bbf870b7baa7eff20cf35381 Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Mon, 20 May 2019 23:48:43 -0600 Subject: Implement rewrite middleware; fix middleware stack bugs --- modules/caddyhttp/rewrite/rewrite.go | 71 ++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 modules/caddyhttp/rewrite/rewrite.go (limited to 'modules/caddyhttp/rewrite') diff --git a/modules/caddyhttp/rewrite/rewrite.go b/modules/caddyhttp/rewrite/rewrite.go new file mode 100644 index 0000000..1afb8a4 --- /dev/null +++ b/modules/caddyhttp/rewrite/rewrite.go @@ -0,0 +1,71 @@ +package headers + +import ( + "net/http" + "net/url" + "strings" + + "bitbucket.org/lightcodelabs/caddy2" + "bitbucket.org/lightcodelabs/caddy2/modules/caddyhttp" +) + +func init() { + caddy2.RegisterModule(caddy2.Module{ + Name: "http.middleware.rewrite", + New: func() (interface{}, error) { return new(Rewrite), nil }, + }) +} + +// Rewrite is a middleware which can rewrite HTTP requests. +type Rewrite struct { + Method string `json:"method"` + URI string `json:"uri"` + Rehandle bool `json:"rehandle"` +} + +func (rewr Rewrite) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error { + repl := r.Context().Value(caddy2.ReplacerCtxKey).(caddy2.Replacer) + var rehandleNeeded bool + + if rewr.Method != "" { + method := r.Method + r.Method = strings.ToUpper(repl.ReplaceAll(rewr.Method, "")) + if r.Method != method { + rehandleNeeded = true + } + } + + if rewr.URI != "" { + // TODO: clean this all up, I don't think it's right + + oldURI := r.RequestURI + newURI := repl.ReplaceAll(rewr.URI, "") + u, err := url.Parse(newURI) + if err != nil { + return caddyhttp.Error(http.StatusInternalServerError, err) + } + + r.RequestURI = newURI + + r.URL.Path = u.Path + if u.RawQuery != "" { + r.URL.RawQuery = u.RawQuery + } + if u.Fragment != "" { + r.URL.Fragment = u.Fragment + } + + if newURI != oldURI { + rehandleNeeded = true + } + } + + if rehandleNeeded && rewr.Rehandle { + return caddyhttp.ErrRehandle + } + + return next.ServeHTTP(w, r) +} + +// Interface guard +var _ caddyhttp.MiddlewareHandler = (*Rewrite)(nil) -- cgit v1.2.3