Skip to content

Commit

Permalink
net/http: add an example of creating a custom FileSystem
Browse files Browse the repository at this point in the history
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
crazcalm committed Aug 3, 2018
1 parent b3b2f5d commit 8b0b644
Showing 1 changed file with 71 additions and 0 deletions.
71 changes: 71 additions & 0 deletions src/net/http/example_filesystem_test.go
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))
}

0 comments on commit 8b0b644

Please sign in to comment.