-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
net/http: add an example of creating a custom FileSystem
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 examples on how to create a custom FileSystem. This commit provides an example. Fixes golang#20759
- Loading branch information
Showing
1 changed file
with
71 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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)) | ||
} |