Commit f4b6f15e authored by Matthew Holt's avatar Matthew Holt

staticfiles: Build redirect based on rewritten URL (fixes #1706)

parent 95a62376
...@@ -352,6 +352,8 @@ func (s *Server) serveHTTP(w http.ResponseWriter, r *http.Request) (int, error) ...@@ -352,6 +352,8 @@ func (s *Server) serveHTTP(w http.ResponseWriter, r *http.Request) (int, error)
// look up the virtualhost; if no match, serve error // look up the virtualhost; if no match, serve error
vhost, pathPrefix := s.vhosts.Match(hostname + r.URL.Path) vhost, pathPrefix := s.vhosts.Match(hostname + r.URL.Path)
c := context.WithValue(r.Context(), caddy.CtxKey("path_prefix"), pathPrefix)
r = r.WithContext(c)
if vhost == nil { if vhost == nil {
// check for ACME challenge even if vhost is nil; // check for ACME challenge even if vhost is nil;
......
...@@ -7,7 +7,6 @@ package staticfiles ...@@ -7,7 +7,6 @@ package staticfiles
import ( import (
"math/rand" "math/rand"
"net/http" "net/http"
"net/url"
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
...@@ -82,37 +81,41 @@ func (fs FileServer) serveFile(w http.ResponseWriter, r *http.Request) (int, err ...@@ -82,37 +81,41 @@ func (fs FileServer) serveFile(w http.ResponseWriter, r *http.Request) (int, err
// redirect to canonical path (being careful to preserve other parts of URL and // redirect to canonical path (being careful to preserve other parts of URL and
// considering cases where a site is defined with a path prefix that gets stripped) // considering cases where a site is defined with a path prefix that gets stripped)
u := r.Context().Value(caddy.CtxKey("original_url")).(url.URL) urlCopy := *r.URL
if u.Path == "" { pathPrefix, _ := r.Context().Value(caddy.CtxKey("path_prefix")).(string)
u.Path = "/" if pathPrefix != "/" {
urlCopy.Path = pathPrefix + urlCopy.Path
}
if urlCopy.Path == "" {
urlCopy.Path = "/"
} }
if d.IsDir() { if d.IsDir() {
// ensure there is a trailing slash // ensure there is a trailing slash
if u.Path[len(u.Path)-1] != '/' { if urlCopy.Path[len(urlCopy.Path)-1] != '/' {
u.Path += "/" urlCopy.Path += "/"
http.Redirect(w, r, u.String(), http.StatusMovedPermanently) http.Redirect(w, r, urlCopy.String(), http.StatusMovedPermanently)
return http.StatusMovedPermanently, nil return http.StatusMovedPermanently, nil
} }
} else { } else {
// ensure no trailing slash // ensure no trailing slash
redir := false redir := false
if u.Path[len(u.Path)-1] == '/' { if urlCopy.Path[len(urlCopy.Path)-1] == '/' {
u.Path = u.Path[:len(u.Path)-1] urlCopy.Path = urlCopy.Path[:len(urlCopy.Path)-1]
redir = true redir = true
} }
// if an index file was explicitly requested, strip file name from the request // if an index file was explicitly requested, strip file name from the request
// ("/foo/index.html" -> "/foo/") // ("/foo/index.html" -> "/foo/")
for _, indexPage := range IndexPages { for _, indexPage := range IndexPages {
if strings.HasSuffix(u.Path, indexPage) { if strings.HasSuffix(urlCopy.Path, indexPage) {
u.Path = u.Path[:len(u.Path)-len(indexPage)] urlCopy.Path = urlCopy.Path[:len(urlCopy.Path)-len(indexPage)]
redir = true redir = true
break break
} }
} }
if redir { if redir {
http.Redirect(w, r, u.String(), http.StatusMovedPermanently) http.Redirect(w, r, urlCopy.String(), http.StatusMovedPermanently)
return http.StatusMovedPermanently, nil return http.StatusMovedPermanently, nil
} }
} }
......
...@@ -230,9 +230,11 @@ func TestServeHTTP(t *testing.T) { ...@@ -230,9 +230,11 @@ func TestServeHTTP(t *testing.T) {
continue continue
} }
// set the original URL on the context // set the original URL and path prefix on the context
ctx := context.WithValue(request.Context(), caddy.CtxKey("original_url"), *request.URL) ctx := context.WithValue(request.Context(), caddy.CtxKey("original_url"), *request.URL)
request = request.WithContext(ctx) request = request.WithContext(ctx)
ctx = context.WithValue(request.Context(), caddy.CtxKey("path_prefix"), test.stripPathPrefix)
request = request.WithContext(ctx)
request.Header.Add("Accept-Encoding", test.acceptEncoding) request.Header.Add("Accept-Encoding", test.acceptEncoding)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment