Removed locat copies of exported functions
This commit is contained in:
parent
9f2eea189b
commit
7064535a00
|
@ -25,31 +25,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Dir implements FileSystem using the native file system restricted to a
|
|
||||||
// specific directory tree.
|
|
||||||
//
|
|
||||||
// While the FileSystem.Open method takes '/'-separated paths, a Dir's string
|
|
||||||
// value is a filename on the native file system, not a URL, so it is separated
|
|
||||||
// by filepath.Separator, which isn't necessarily '/'.
|
|
||||||
//
|
|
||||||
// Note that Dir will allow access to files and directories starting with a
|
|
||||||
// period, which could expose sensitive directories like a .git directory or
|
|
||||||
// sensitive files like .htpasswd. To exclude files with a leading period,
|
|
||||||
// remove the files/directories from the server or create a custom FileSystem
|
|
||||||
// implementation.
|
|
||||||
//
|
|
||||||
// An empty Dir is treated as ".".
|
|
||||||
type Dir string
|
|
||||||
|
|
||||||
// A file list struct for sorting purposes
|
|
||||||
|
|
||||||
type FileList struct {
|
|
||||||
FileName string
|
|
||||||
FileSize int
|
|
||||||
User int
|
|
||||||
Group int
|
|
||||||
}
|
|
||||||
|
|
||||||
// mapDirOpenError maps the provided non-nil error from opening name
|
// mapDirOpenError maps the provided non-nil error from opening name
|
||||||
// to a possibly better non-nil error. In particular, it turns OS-specific errors
|
// to a possibly better non-nil error. In particular, it turns OS-specific errors
|
||||||
// about opening files in non-directories into os.ErrNotExist. See Issue 18984.
|
// about opening files in non-directories into os.ErrNotExist. See Issue 18984.
|
||||||
|
@ -74,42 +49,7 @@ func mapDirOpenError(originalErr error, name string) error {
|
||||||
return originalErr
|
return originalErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d Dir) Open(name string) (File, error) {
|
func dirList(w http.ResponseWriter, r *http.Request, f http.File) {
|
||||||
if filepath.Separator != '/' && strings.ContainsRune(name, filepath.Separator) {
|
|
||||||
return nil, errors.New("http: invalid character in file path")
|
|
||||||
}
|
|
||||||
dir := string(d)
|
|
||||||
if dir == "" {
|
|
||||||
dir = "."
|
|
||||||
}
|
|
||||||
fullName := filepath.Join(dir, filepath.FromSlash(path.Clean("/"+name)))
|
|
||||||
f, err := os.Open(fullName)
|
|
||||||
if err != nil {
|
|
||||||
return nil, mapDirOpenError(err, fullName)
|
|
||||||
}
|
|
||||||
return f, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// A FileSystem implements access to a collection of named files.
|
|
||||||
// The elements in a file path are separated by slash ('/', U+002F)
|
|
||||||
// characters, regardless of host operating system convention.
|
|
||||||
type FileSystem interface {
|
|
||||||
Open(name string) (File, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// A File is returned by a FileSystem's Open method and can be
|
|
||||||
// served by the FileServer implementation.
|
|
||||||
//
|
|
||||||
// The methods should behave the same as those on an *os.File.
|
|
||||||
type File interface {
|
|
||||||
io.Closer
|
|
||||||
io.Reader
|
|
||||||
io.Seeker
|
|
||||||
Readdir(count int) ([]os.FileInfo, error)
|
|
||||||
Stat() (os.FileInfo, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dirList(w http.ResponseWriter, r *http.Request, f File) {
|
|
||||||
dirs, err := f.Readdir(-1)
|
dirs, err := f.Readdir(-1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logf(r, "http: error reading directory: %v", err)
|
logf(r, "http: error reading directory: %v", err)
|
||||||
|
@ -136,46 +76,6 @@ func dirList(w http.ResponseWriter, r *http.Request, f File) {
|
||||||
fmt.Fprintf(w, "</pre>\n")
|
fmt.Fprintf(w, "</pre>\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServeContent replies to the request using the content in the
|
|
||||||
// provided ReadSeeker. The main benefit of ServeContent over io.Copy
|
|
||||||
// is that it handles Range requests properly, sets the MIME type, and
|
|
||||||
// handles If-Match, If-Unmodified-Since, If-None-Match, If-Modified-Since,
|
|
||||||
// and If-Range requests.
|
|
||||||
//
|
|
||||||
// If the response's Content-Type header is not set, ServeContent
|
|
||||||
// first tries to deduce the type from name's file extension and,
|
|
||||||
// if that fails, falls back to reading the first block of the content
|
|
||||||
// and passing it to DetectContentType.
|
|
||||||
// The name is otherwise unused; in particular it can be empty and is
|
|
||||||
// never sent in the response.
|
|
||||||
//
|
|
||||||
// If modtime is not the zero time or Unix epoch, ServeContent
|
|
||||||
// includes it in a Last-Modified header in the response. If the
|
|
||||||
// request includes an If-Modified-Since header, ServeContent uses
|
|
||||||
// modtime to decide whether the content needs to be sent at all.
|
|
||||||
//
|
|
||||||
// The content's Seek method must work: ServeContent uses
|
|
||||||
// a seek to the end of the content to determine its size.
|
|
||||||
//
|
|
||||||
// If the caller has set w's ETag header formatted per RFC 7232, section 2.3,
|
|
||||||
// ServeContent uses it to handle requests using If-Match, If-None-Match, or If-Range.
|
|
||||||
//
|
|
||||||
// Note that *os.File implements the io.ReadSeeker interface.
|
|
||||||
func ServeContent(w http.ResponseWriter, req *http.Request, name string, modtime time.Time, content io.ReadSeeker) {
|
|
||||||
sizeFunc := func() (int64, error) {
|
|
||||||
size, err := content.Seek(0, io.SeekEnd)
|
|
||||||
if err != nil {
|
|
||||||
return 0, errSeeker
|
|
||||||
}
|
|
||||||
_, err = content.Seek(0, io.SeekStart)
|
|
||||||
if err != nil {
|
|
||||||
return 0, errSeeker
|
|
||||||
}
|
|
||||||
return size, nil
|
|
||||||
}
|
|
||||||
serveContent(w, req, name, modtime, sizeFunc, content)
|
|
||||||
}
|
|
||||||
|
|
||||||
// errSeeker is returned by ServeContent's sizeFunc when the content
|
// errSeeker is returned by ServeContent's sizeFunc when the content
|
||||||
// doesn't seek properly. The underlying Seeker's error text isn't
|
// doesn't seek properly. The underlying Seeker's error text isn't
|
||||||
// included in the sizeFunc reply so it's not sent over HTTP to end
|
// included in the sizeFunc reply so it's not sent over HTTP to end
|
||||||
|
@ -550,7 +450,7 @@ func checkPreconditions(w http.ResponseWriter, r *http.Request, modtime time.Tim
|
||||||
}
|
}
|
||||||
|
|
||||||
// name is '/'-separated, not filepath.Separator.
|
// name is '/'-separated, not filepath.Separator.
|
||||||
func serveFile(w http.ResponseWriter, r *http.Request, fs FileSystem, name string, redirect bool) {
|
func serveFile(w http.ResponseWriter, r *http.Request, fs http.FileSystem, name string, redirect bool) {
|
||||||
const indexPage = "/index.html"
|
const indexPage = "/index.html"
|
||||||
|
|
||||||
// redirect .../index.html to .../
|
// redirect .../index.html to .../
|
||||||
|
@ -683,7 +583,7 @@ func ServeFile(w http.ResponseWriter, r *http.Request, name string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dir, file := filepath.Split(name)
|
dir, file := filepath.Split(name)
|
||||||
serveFile(w, r, Dir(dir), file, false)
|
serveFile(w, r, http.Dir(dir), file, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func containsDotDot(v string) bool {
|
func containsDotDot(v string) bool {
|
||||||
|
@ -701,7 +601,7 @@ func containsDotDot(v string) bool {
|
||||||
func isSlashRune(r rune) bool { return r == '/' || r == '\\' }
|
func isSlashRune(r rune) bool { return r == '/' || r == '\\' }
|
||||||
|
|
||||||
type fileHandler struct {
|
type fileHandler struct {
|
||||||
root FileSystem
|
root http.FileSystem
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileServer returns a handler that serves HTTP requests
|
// FileServer returns a handler that serves HTTP requests
|
||||||
|
@ -715,7 +615,7 @@ type fileHandler struct {
|
||||||
// As a special case, the returned file server redirects any request
|
// As a special case, the returned file server redirects any request
|
||||||
// ending in "/index.html" to the same path, without the final
|
// ending in "/index.html" to the same path, without the final
|
||||||
// "index.html".
|
// "index.html".
|
||||||
func FileServer(root FileSystem) http.Handler {
|
func FileServer(root http.FileSystem) http.Handler {
|
||||||
return &fileHandler{root}
|
return &fileHandler{root}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue