liyujie
2025-08-28 d9927380ed7c8366f762049be9f3fee225860833
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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))
}