@@ -2,9 +2,12 @@ package upstream
9+ "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
8 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/middleware"
11 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/middleware"
@@ -12,22 +15,53 @@ const fileScheme = "file"
13// newFileServer creates a new fileServer that can serve requests
16// newFileServer creates a new fileServer that can serve requests
14// to a file system location.
17// to a file system location.
15−func newFileServer(id, path, fileSystemPath string) http.Handler {
18+func newFileServer(upstream options.Upstream, fileSystemPath string) http.Handler {
19+ handler := newFileServerForPath(fileSystemPath)
21+ if upstream.RewriteTarget == "" {
22+ // if the upstream does not have a rewrite target, strip off the Path prefix
23+ // (so e.g. a request for /static/some-file.html looks for some-file.html
24+ // relative to the fileSystemPath rather than static/some-file.html).
25+ handler = http.StripPrefix(upstream.Path, handler)
27+ // if the upstream *does* have a rewrite target then that means the target
28+ // path relative to the fileSystemPath will be the one in the (rewritten)
30+ handler = requestURIToURL(handler)
16 return &fileServer{
32 return &fileServer{
17− upstream: id,
33+ upstream: upstream.ID,
18− handler: newFileServerForPath(path, fileSystemPath),
34+ handler: handler,
22// newFileServerForPath creates a http.Handler to serve files from the filesystem
38// newFileServerForPath creates a http.Handler to serve files from the filesystem
23−func newFileServerForPath(path string, filesystemPath string) http.Handler {
39+func newFileServerForPath(filesystemPath string) http.Handler {
24 // Windows fileSSystemPath will be be prefixed with `/`, eg`/C:/...,
40 // Windows fileSSystemPath will be be prefixed with `/`, eg`/C:/...,
25 // if they were parsed by url.Parse`
41 // if they were parsed by url.Parse`
26 if runtime.GOOS == "windows" {
42 if runtime.GOOS == "windows" {
27 filesystemPath = strings.TrimPrefix(filesystemPath, "/")
43 filesystemPath = strings.TrimPrefix(filesystemPath, "/")
30− return http.StripPrefix(path, http.FileServer(http.Dir(filesystemPath)))
46+ return http.FileServer(http.Dir(filesystemPath))
49+// requestURIToURL returns a Handler that replaces the URL in its request with
50+// the result of parsing req.RequestURI. This is necessary for file handlers
51+// that have a rewrite target, since http.FileServer uses req.URL.Path when
52+// looking for the target file, but the rewrite handler only updates the
53+// RequestURI, leaving the original path in the URL.
54+func requestURIToURL(handler http.Handler) http.Handler {
55+ return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
56+ reqURL, err := url.ParseRequestURI(req.RequestURI)
58+ http.Error(rw, "500 Internal Server Error", http.StatusInternalServerError)
63+ handler.ServeHTTP(rw, req)
33// fileServer represents a single filesystem upstream proxy
67// fileServer represents a single filesystem upstream proxy