83 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			83 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
| package upstream
 | |
| 
 | |
| import (
 | |
| 	"net/http"
 | |
| 	"net/url"
 | |
| 	"runtime"
 | |
| 	"strings"
 | |
| 
 | |
| 	"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
 | |
| 
 | |
| 	"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/middleware"
 | |
| )
 | |
| 
 | |
| const fileScheme = "file"
 | |
| 
 | |
| // newFileServer creates a new fileServer that can serve requests
 | |
| // to a file system location.
 | |
| func newFileServer(upstream options.Upstream, fileSystemPath string) http.Handler {
 | |
| 	handler := newFileServerForPath(fileSystemPath)
 | |
| 
 | |
| 	if upstream.RewriteTarget == "" {
 | |
| 		// if the upstream does not have a rewrite target, strip off the Path prefix
 | |
| 		// (so e.g. a request for /static/some-file.html looks for some-file.html
 | |
| 		// relative to the fileSystemPath rather than static/some-file.html).
 | |
| 		handler = http.StripPrefix(upstream.Path, handler)
 | |
| 	} else {
 | |
| 		// if the upstream *does* have a rewrite target then that means the target
 | |
| 		// path relative to the fileSystemPath will be the one in the (rewritten)
 | |
| 		// RequestURI.
 | |
| 		handler = requestURIToURL(handler)
 | |
| 	}
 | |
| 	return &fileServer{
 | |
| 		upstream: upstream.ID,
 | |
| 		handler:  handler,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // newFileServerForPath creates a http.Handler to serve files from the filesystem
 | |
| func newFileServerForPath(filesystemPath string) http.Handler {
 | |
| 	// Windows fileSSystemPath will be be prefixed with `/`, eg`/C:/...,
 | |
| 	// if they were parsed by url.Parse`
 | |
| 	if runtime.GOOS == "windows" {
 | |
| 		filesystemPath = strings.TrimPrefix(filesystemPath, "/")
 | |
| 	}
 | |
| 
 | |
| 	return http.FileServer(http.Dir(filesystemPath))
 | |
| }
 | |
| 
 | |
| // requestURIToURL returns a Handler that replaces the URL in its request with
 | |
| // the result of parsing req.RequestURI.  This is necessary for file handlers
 | |
| // that have a rewrite target, since http.FileServer uses req.URL.Path when
 | |
| // looking for the target file, but the rewrite handler only updates the
 | |
| // RequestURI, leaving the original path in the URL.
 | |
| func requestURIToURL(handler http.Handler) http.Handler {
 | |
| 	return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
 | |
| 		reqURL, err := url.ParseRequestURI(req.RequestURI)
 | |
| 		if err != nil {
 | |
| 			http.Error(rw, "500 Internal Server Error", http.StatusInternalServerError)
 | |
| 			return
 | |
| 		}
 | |
| 
 | |
| 		req.URL = reqURL
 | |
| 		handler.ServeHTTP(rw, req)
 | |
| 	})
 | |
| }
 | |
| 
 | |
| // fileServer represents a single filesystem upstream proxy
 | |
| type fileServer struct {
 | |
| 	upstream string
 | |
| 	handler  http.Handler
 | |
| }
 | |
| 
 | |
| // ServeHTTP proxies requests to the upstream provider while signing the
 | |
| // request headers
 | |
| func (u *fileServer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 | |
| 	scope := middleware.GetRequestScope(req)
 | |
| 	// If scope is nil, this will panic.
 | |
| 	// A scope should always be injected before this handler is called.
 | |
| 	scope.Upstream = u.upstream
 | |
| 
 | |
| 	u.handler.ServeHTTP(rw, req)
 | |
| }
 |