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)
// look up the virtualhost; if no match, serve error
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 {
// check for ACME challenge even if vhost is nil;
......
......@@ -7,7 +7,6 @@ package staticfiles
import (
"math/rand"
"net/http"
"net/url"
"os"
"path"
"path/filepath"
......@@ -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
// considering cases where a site is defined with a path prefix that gets stripped)
u := r.Context().Value(caddy.CtxKey("original_url")).(url.URL)
if u.Path == "" {
u.Path = "/"
urlCopy := *r.URL
pathPrefix, _ := r.Context().Value(caddy.CtxKey("path_prefix")).(string)
if pathPrefix != "/" {
urlCopy.Path = pathPrefix + urlCopy.Path
}
if urlCopy.Path == "" {
urlCopy.Path = "/"
}
if d.IsDir() {
// ensure there is a trailing slash
if u.Path[len(u.Path)-1] != '/' {
u.Path += "/"
http.Redirect(w, r, u.String(), http.StatusMovedPermanently)
if urlCopy.Path[len(urlCopy.Path)-1] != '/' {
urlCopy.Path += "/"
http.Redirect(w, r, urlCopy.String(), http.StatusMovedPermanently)
return http.StatusMovedPermanently, nil
}
} else {
// ensure no trailing slash
redir := false
if u.Path[len(u.Path)-1] == '/' {
u.Path = u.Path[:len(u.Path)-1]
if urlCopy.Path[len(urlCopy.Path)-1] == '/' {
urlCopy.Path = urlCopy.Path[:len(urlCopy.Path)-1]
redir = true
}
// if an index file was explicitly requested, strip file name from the request
// ("/foo/index.html" -> "/foo/")
for _, indexPage := range IndexPages {
if strings.HasSuffix(u.Path, indexPage) {
u.Path = u.Path[:len(u.Path)-len(indexPage)]
if strings.HasSuffix(urlCopy.Path, indexPage) {
urlCopy.Path = urlCopy.Path[:len(urlCopy.Path)-len(indexPage)]
redir = true
break
}
}
if redir {
http.Redirect(w, r, u.String(), http.StatusMovedPermanently)
http.Redirect(w, r, urlCopy.String(), http.StatusMovedPermanently)
return http.StatusMovedPermanently, nil
}
}
......
......@@ -230,9 +230,11 @@ func TestServeHTTP(t *testing.T) {
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)
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)
......
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