]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: add an example of creating a custom FileSystem
authorMarcus Willock <crazcalm@gmail.com>
Fri, 3 Aug 2018 15:13:14 +0000 (15:13 +0000)
committerBrad Fitzpatrick <bradfitz@golang.org>
Tue, 21 Aug 2018 04:55:04 +0000 (04:55 +0000)
The existing documentation of http.Dir is clear in that, if you want to hide
your files and directories that start with a period, you must create
a custom FileSystem. However, there are currently no example on how
to create a custom FileSystem. This commit provides an example.

Fixes #20759

Change-Id: I5a350675536f81412af384d1a316fd6cd6241563
GitHub-Last-Rev: 8b0b644cd02c59fe2461908304c44d64e8be431e
GitHub-Pull-Request: golang/go#26768
Reviewed-on: https://go-review.googlesource.com/127576
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/net/http/example_filesystem_test.go [new file with mode: 0644]

diff --git a/src/net/http/example_filesystem_test.go b/src/net/http/example_filesystem_test.go
new file mode 100644 (file)
index 0000000..e1fd42d
--- /dev/null
@@ -0,0 +1,71 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package http_test
+
+import (
+       "log"
+       "net/http"
+       "os"
+       "strings"
+)
+
+// containsDotFile reports whether name contains a path element starting with a period.
+// The name is assumed to be a delimited by forward slashes, as guaranteed
+// by the http.FileSystem interface.
+func containsDotFile(name string) bool {
+       parts := strings.Split(name, "/")
+       for _, part := range parts {
+               if strings.HasPrefix(part, ".") {
+                       return true
+               }
+       }
+       return false
+}
+
+// dotFileHidingFile is the http.File use in dotFileHidingFileSystem.
+// It is used to wrap the Readdir method of http.File so that we can
+// remove files and directories that start with a period from its output.
+type dotFileHidingFile struct {
+       http.File
+}
+
+// Readdir is a wrapper around the Readdir method of the embedded File
+// that filters out all files that start with a period in their name.
+func (f dotFileHidingFile) Readdir(n int) (fis []os.FileInfo, err error) {
+       files, err := f.File.Readdir(n)
+       for _, file := range files { // Filters out the dot files
+               if !strings.HasPrefix(file.Name(), ".") {
+                       fis = append(fis, file)
+               }
+       }
+       return
+}
+
+// dotFileHidingFileSystem is an http.FileSystem that hides
+// hidden "dot files" from being served.
+type dotFileHidingFileSystem struct {
+       http.FileSystem
+}
+
+// Open is a wrapper around the Open method of the embedded FileSystem
+// that serves a 403 permission error when name has a file or directory
+// with whose name starts with a period in its path.
+func (fs dotFileHidingFileSystem) Open(name string) (http.File, error) {
+       if containsDotFile(name) { // If dot file, return 403 response
+               return nil, os.ErrPermission
+       }
+
+       file, err := fs.FileSystem.Open(name)
+       if err != nil {
+               return nil, err
+       }
+       return dotFileHidingFile{file}, err
+}
+
+func ExampleFileServer_dotFileHiding() {
+       fs := dotFileHidingFileSystem{http.Dir(".")}
+       http.Handle("/", http.FileServer(fs))
+       log.Fatal(http.ListenAndServe(":8080", nil))
+}