From 9bc1fdea394a25db32bf9837f1e327828276193d Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 6 Nov 2018 15:46:28 +0000 Subject: [PATCH] Add optino to disable automatic directory indexes --- README.md | 6 ++++-- enhanced-file-server.go | 19 ++++++++++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index c09e2b2..87cb0a1 100644 --- a/README.md +++ b/README.md @@ -4,5 +4,7 @@ This package is designed to enhance Go's built-in http file server function and Where the native function's file listing was just an alphabetical set of files, this one adds file size, date, owner/group, and sorting capability. -This should be a drop-in replacement and is largely based on the original code. See the included example for a simple use, -or https://gitto.work/shortcut/httphere for something more practical. \ No newline at end of file +This can be a drop-in replacement and is largely based on the original code. See the included example for a simple use, +or https://gitto.work/shortcut/httphere for something more practical. + +Optionally, you can elect to not generate an automatic directory index by using FileServerNoIndex() in place of FileServer(). \ No newline at end of file diff --git a/enhanced-file-server.go b/enhanced-file-server.go index 8156ba9..5f89aa9 100644 --- a/enhanced-file-server.go +++ b/enhanced-file-server.go @@ -497,7 +497,7 @@ func checkPreconditions(w http.ResponseWriter, r *http.Request, modtime time.Tim } // name is '/'-separated, not filepath.Separator. -func serveFile(w http.ResponseWriter, r *http.Request, fs http.FileSystem, name string, redirect bool) { +func serveFile(w http.ResponseWriter, r *http.Request, fs http.FileSystem, name string, redirect bool, index bool) { const indexPage = "/index.html" // redirect .../index.html to .../ @@ -565,7 +565,7 @@ func serveFile(w http.ResponseWriter, r *http.Request, fs http.FileSystem, name } // Still a directory? (we didn't find an index.html file) - if d.IsDir() { + if d.IsDir() && index { if checkIfModifiedSince(r, d.ModTime()) == condFalse { writeNotModified(w) return @@ -573,6 +573,10 @@ func serveFile(w http.ResponseWriter, r *http.Request, fs http.FileSystem, name w.Header().Set("Last-Modified", d.ModTime().UTC().Format(http.TimeFormat)) dirList(w, r, f) return + } else if d.IsDir() { + + http.Error(w, "Forbidden", http.StatusForbidden) + return } // serveContent will check modification time @@ -648,7 +652,8 @@ func containsDotDot(v string) bool { func isSlashRune(r rune) bool { return r == '/' || r == '\\' } type fileHandler struct { - root http.FileSystem + root http.FileSystem + index bool } // FileServer returns a handler that serves HTTP requests @@ -663,7 +668,11 @@ type fileHandler struct { // ending in "/index.html" to the same path, without the final // "index.html". func FileServer(root http.FileSystem) http.Handler { - return &fileHandler{root} + return &fileHandler{root, true} +} + +func FileServerNoIndex(root http.FileSystem) http.Handler { + return &fileHandler{root, false} } func (f *fileHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { @@ -672,7 +681,7 @@ func (f *fileHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { upath = "/" + upath r.URL.Path = upath } - serveFile(w, r, f.root, path.Clean(upath), true) + serveFile(w, r, f.root, path.Clean(upath), true, f.index) } // httpRange specifies the byte range to be sent to the client.