diff --git a/caddy.go b/caddy.go index 8814bad75..c5ff88ca0 100644 --- a/caddy.go +++ b/caddy.go @@ -870,16 +870,5 @@ var ( DefaultConfigFile = "Caddyfile" ) -// CtxKey is a value for use with context.WithValue. -// TODO: Ideally CtxKey and consts will be moved to httpserver package. -// currently blocked by circular import with staticfiles. +// CtxKey is a value type for use with context.WithValue. type CtxKey string - -// URLPathCtxKey is a context key. It can be used in HTTP handlers with -// context.WithValue to access the original request URI that accompanied the -// server request. The associated value will be of type string. -const URLPathCtxKey CtxKey = "url_path" - -// URIxRewriteCtxKey is a context key used to store original unrewritten -// URI in context.WithValue -const URIxRewriteCtxKey CtxKey = "caddy_rewrite_original_uri" diff --git a/caddyhttp/basicauth/basicauth.go b/caddyhttp/basicauth/basicauth.go index 49c0cb14f..5661a017d 100644 --- a/caddyhttp/basicauth/basicauth.go +++ b/caddyhttp/basicauth/basicauth.go @@ -19,7 +19,6 @@ import ( "sync" "github.com/jimstudt/http-authentication/basic" - "github.com/mholt/caddy" "github.com/mholt/caddy/caddyhttp/httpserver" ) @@ -62,8 +61,10 @@ func (a BasicAuth) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error // by this point, authentication was successful isAuthenticated = true - // let upstream middleware (e.g. fastcgi and cgi) know about authenticated user - r = r.WithContext(context.WithValue(r.Context(), caddy.CtxKey("remote_user"), username)) + // let upstream middleware (e.g. fastcgi and cgi) know about authenticated + // user; this replaces the request with a wrapped instance + r = r.WithContext(context.WithValue(r.Context(), + httpserver.RemoteUserCtxKey, username)) } } diff --git a/caddyhttp/basicauth/basicauth_test.go b/caddyhttp/basicauth/basicauth_test.go index 18c79aec2..3f0113b2e 100644 --- a/caddyhttp/basicauth/basicauth_test.go +++ b/caddyhttp/basicauth/basicauth_test.go @@ -10,7 +10,6 @@ import ( "path/filepath" "testing" - "github.com/mholt/caddy" "github.com/mholt/caddy/caddyhttp/httpserver" ) @@ -19,7 +18,7 @@ func TestBasicAuth(t *testing.T) { // This handler is registered for tests in which the only authorized user is // "okuser" upstreamHandler := func(w http.ResponseWriter, r *http.Request) (int, error) { - remoteUser, _ := r.Context().Value(caddy.CtxKey("remote_user")).(string) + remoteUser, _ := r.Context().Value(httpserver.RemoteUserCtxKey).(string) if remoteUser != "okuser" { t.Errorf("Test %d: expecting remote user 'okuser', got '%s'", i, remoteUser) } diff --git a/caddyhttp/fastcgi/fastcgi.go b/caddyhttp/fastcgi/fastcgi.go index dfbd7db80..99d5e9cc5 100644 --- a/caddyhttp/fastcgi/fastcgi.go +++ b/caddyhttp/fastcgi/fastcgi.go @@ -15,7 +15,6 @@ import ( "strings" "time" - "github.com/mholt/caddy" "github.com/mholt/caddy/caddyhttp/httpserver" ) @@ -219,13 +218,13 @@ func (h Handler) buildEnv(r *http.Request, rule Rule, fpath string) (map[string] // If it was rewritten, there will be a context value with the original URL, // which is needed to get the correct RequestURI value for PHP apps. reqURI := r.URL.RequestURI() - if origURI, _ := r.Context().Value(caddy.URIxRewriteCtxKey).(string); origURI != "" { + if origURI, _ := r.Context().Value(httpserver.URIxRewriteCtxKey).(string); origURI != "" { reqURI = origURI } // Retrieve name of remote user that was set by some downstream middleware, // possibly basicauth. - remoteUser, _ := r.Context().Value(caddy.CtxKey("remote_user")).(string) // Blank if not set + remoteUser, _ := r.Context().Value(httpserver.RemoteUserCtxKey).(string) // Blank if not set // Some variables are unused but cleared explicitly to prevent // the parent environment from interfering. diff --git a/caddyhttp/httpserver/context.go b/caddyhttp/httpserver/context.go index 050e18306..3cf43965e 100644 --- a/caddyhttp/httpserver/context.go +++ b/caddyhttp/httpserver/context.go @@ -14,7 +14,6 @@ import ( "os" - "github.com/mholt/caddy" "github.com/russross/blackfriday" ) @@ -349,7 +348,7 @@ func (c Context) Files(name string) ([]string, error) { // IsMITM returns true if it seems likely that the TLS connection // is being intercepted. func (c Context) IsMITM() bool { - if val, ok := c.Req.Context().Value(caddy.CtxKey("mitm")).(bool); ok { + if val, ok := c.Req.Context().Value(MitmCtxKey).(bool); ok { return val } return false diff --git a/caddyhttp/httpserver/middleware.go b/caddyhttp/httpserver/middleware.go index e6b8ff963..c6ffa22de 100644 --- a/caddyhttp/httpserver/middleware.go +++ b/caddyhttp/httpserver/middleware.go @@ -197,3 +197,16 @@ var EmptyNext = HandlerFunc(func(w http.ResponseWriter, r *http.Request) (int, e func SameNext(next1, next2 Handler) bool { return fmt.Sprintf("%v", next1) == fmt.Sprintf("%v", next2) } + +// Context key constants +const ( + // URIxRewriteCtxKey is a context key used to store original unrewritten + // URI in context.WithValue + URIxRewriteCtxKey caddy.CtxKey = "caddy_rewrite_original_uri" + + // RemoteUserCtxKey is a context key used to store remote user for request + RemoteUserCtxKey caddy.CtxKey = "remote_user" + + // MitmCtxKey stores Mitm result + MitmCtxKey caddy.CtxKey = "mitm" +) diff --git a/caddyhttp/httpserver/mitm.go b/caddyhttp/httpserver/mitm.go index a40865096..6b18fd3e8 100644 --- a/caddyhttp/httpserver/mitm.go +++ b/caddyhttp/httpserver/mitm.go @@ -9,8 +9,6 @@ import ( "net/http" "strings" "sync" - - "github.com/mholt/caddy" ) // tlsHandler is a http.Handler that will inject a value @@ -74,7 +72,7 @@ func (h *tlsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } if checked { - r = r.WithContext(context.WithValue(r.Context(), caddy.CtxKey("mitm"), mitm)) + r = r.WithContext(context.WithValue(r.Context(), MitmCtxKey, mitm)) } if mitm && h.closeOnMITM { diff --git a/caddyhttp/httpserver/mitm_test.go b/caddyhttp/httpserver/mitm_test.go index a262a1af6..669de707f 100644 --- a/caddyhttp/httpserver/mitm_test.go +++ b/caddyhttp/httpserver/mitm_test.go @@ -7,8 +7,6 @@ import ( "net/http/httptest" "reflect" "testing" - - "github.com/mholt/caddy" ) func TestParseClientHello(t *testing.T) { @@ -287,7 +285,7 @@ func TestHeuristicFunctionsAndHandler(t *testing.T) { want := ch.interception handler := &tlsHandler{ next: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - got, checked = r.Context().Value(caddy.CtxKey("mitm")).(bool) + got, checked = r.Context().Value(MitmCtxKey).(bool) }), listener: newTLSListener(nil, nil), } diff --git a/caddyhttp/httpserver/replacer.go b/caddyhttp/httpserver/replacer.go index 0816734dd..9b466c9ab 100644 --- a/caddyhttp/httpserver/replacer.go +++ b/caddyhttp/httpserver/replacer.go @@ -241,7 +241,7 @@ func (r *replacer) getSubstitution(key string) string { // if a rewrite has happened, the original URI should be used as the path // rather than the rewritten URI var path string - origpath, _ := r.request.Context().Value(caddy.URIxRewriteCtxKey).(string) + origpath, _ := r.request.Context().Value(URIxRewriteCtxKey).(string) if origpath == "" { path = r.request.URL.Path } else { @@ -251,7 +251,7 @@ func (r *replacer) getSubstitution(key string) string { return path case "{path_escaped}": var path string - origpath, _ := r.request.Context().Value(caddy.URIxRewriteCtxKey).(string) + origpath, _ := r.request.Context().Value(URIxRewriteCtxKey).(string) if origpath == "" { path = r.request.URL.Path } else { @@ -284,13 +284,13 @@ func (r *replacer) getSubstitution(key string) string { } return port case "{uri}": - uri, _ := r.request.Context().Value(caddy.URIxRewriteCtxKey).(string) + uri, _ := r.request.Context().Value(URIxRewriteCtxKey).(string) if uri == "" { uri = r.request.URL.RequestURI() } return uri case "{uri_escaped}": - uri, _ := r.request.Context().Value(caddy.URIxRewriteCtxKey).(string) + uri, _ := r.request.Context().Value(URIxRewriteCtxKey).(string) if uri == "" { uri = r.request.URL.RequestURI() } diff --git a/caddyhttp/httpserver/replacer_test.go b/caddyhttp/httpserver/replacer_test.go index 70ab6d4f7..f7cb4b658 100644 --- a/caddyhttp/httpserver/replacer_test.go +++ b/caddyhttp/httpserver/replacer_test.go @@ -8,8 +8,6 @@ import ( "strings" "testing" "time" - - "github.com/mholt/caddy" ) func TestNewReplacer(t *testing.T) { @@ -164,7 +162,7 @@ func TestPathRewrite(t *testing.T) { t.Fatalf("Request Formation Failed: %s\n", err.Error()) } - ctx := context.WithValue(request.Context(), caddy.URIxRewriteCtxKey, "a/custom/path.php?key=value") + ctx := context.WithValue(request.Context(), URIxRewriteCtxKey, "a/custom/path.php?key=value") request = request.WithContext(ctx) repl := NewReplacer(request, recordRequest, "") diff --git a/caddyhttp/httpserver/server.go b/caddyhttp/httpserver/server.go index 2a3ed7c9b..5aab81b09 100644 --- a/caddyhttp/httpserver/server.go +++ b/caddyhttp/httpserver/server.go @@ -292,7 +292,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { }() w.Header().Set("Server", "Caddy") - c := context.WithValue(r.Context(), caddy.URLPathCtxKey, r.URL.Path) + c := context.WithValue(r.Context(), staticfiles.URLPathCtxKey, r.URL.Path) r = r.WithContext(c) sanitizePath(r) diff --git a/caddyhttp/rewrite/to.go b/caddyhttp/rewrite/to.go index 66eea9b01..45434da34 100644 --- a/caddyhttp/rewrite/to.go +++ b/caddyhttp/rewrite/to.go @@ -8,7 +8,6 @@ import ( "path" "strings" - "github.com/mholt/caddy" "github.com/mholt/caddy/caddyhttp/httpserver" ) @@ -51,7 +50,7 @@ func To(fs http.FileSystem, r *http.Request, to string, replacer httpserver.Repl // take note of this rewrite for internal use by fastcgi // all we need is the URI, not full URL - *r = *r.WithContext(context.WithValue(r.Context(), caddy.URIxRewriteCtxKey, r.URL.RequestURI())) + *r = *r.WithContext(context.WithValue(r.Context(), httpserver.URIxRewriteCtxKey, r.URL.RequestURI())) // perform rewrite r.URL.Path = u.Path diff --git a/caddyhttp/staticfiles/fileserver.go b/caddyhttp/staticfiles/fileserver.go index 6db0d8ea3..091090fcf 100644 --- a/caddyhttp/staticfiles/fileserver.go +++ b/caddyhttp/staticfiles/fileserver.go @@ -98,7 +98,7 @@ func (fs FileServer) serveFile(w http.ResponseWriter, r *http.Request, name stri if !strings.HasSuffix(r.URL.Path, "/") { toURL, _ := url.Parse(r.URL.String()) - path, ok := r.Context().Value(caddy.URLPathCtxKey).(string) + path, ok := r.Context().Value(URLPathCtxKey).(string) if ok && !strings.HasSuffix(path, "/") { toURL.Path = path } @@ -113,7 +113,7 @@ func (fs FileServer) serveFile(w http.ResponseWriter, r *http.Request, name stri if strings.HasSuffix(r.URL.Path, "/") { toURL, _ := url.Parse(r.URL.String()) - path, ok := r.Context().Value(caddy.URLPathCtxKey).(string) + path, ok := r.Context().Value(URLPathCtxKey).(string) if ok && strings.HasSuffix(path, "/") { toURL.Path = path } @@ -300,3 +300,8 @@ func mapFSRootOpenErr(originalErr error) error { } return originalErr } + +// URLPathCtxKey is a context key. It can be used in HTTP handlers with +// context.WithValue to access the original request URI that accompanied the +// server request. The associated value will be of type string. +const URLPathCtxKey caddy.CtxKey = "url_path" diff --git a/caddyhttp/staticfiles/fileserver_test.go b/caddyhttp/staticfiles/fileserver_test.go index 103d9265b..0645a8cba 100644 --- a/caddyhttp/staticfiles/fileserver_test.go +++ b/caddyhttp/staticfiles/fileserver_test.go @@ -12,8 +12,6 @@ import ( "strings" "testing" "time" - - "github.com/mholt/caddy" ) var ( @@ -265,7 +263,7 @@ func TestServeHTTP(t *testing.T) { for i, test := range tests { responseRecorder := httptest.NewRecorder() request, err := http.NewRequest("GET", test.url, nil) - ctx := context.WithValue(request.Context(), caddy.URLPathCtxKey, request.URL.Path) + ctx := context.WithValue(request.Context(), URLPathCtxKey, request.URL.Path) request = request.WithContext(ctx) request.Header.Add("Accept-Encoding", test.acceptEncoding)