| 12
 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
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 
 | func ServeMyFile(w http.ResponseWriter, r *http.Request, name string) {dir, baseName := filepath.Split(name)
 serveFile(w, r, http.Dir(dir), baseName)
 }
 
 func toHTTPError(err error) (msg string, httpStatus int) {
 if os.IsNotExist(err) {
 return "404 page not found", http.StatusNotFound
 }
 if os.IsPermission(err) {
 return "403 Forbidden", http.StatusForbidden
 }
 
 return "500 Internal Server Error", http.StatusInternalServerError
 }
 
 
 func serveFile(w http.ResponseWriter, r *http.Request, fs http.FileSystem, name string) {
 f, err := fs.Open(name)
 if err != nil {
 msg, code := toHTTPError(err)
 http.Error(w, msg, code)
 return
 }
 defer f.Close()
 
 d, err := f.Stat()
 if err != nil {
 msg, code := toHTTPError(err)
 http.Error(w, msg, code)
 return
 }
 
 buffer := bytes.NewBuffer(make([]byte, 0))
 bw := bufio.NewWriter(buffer)
 var size int64
 
 
 sizeFunc := func() (int64, error) { return size, nil }
 
 if d.IsDir() {
 
 
 dirs, err := f.Readdir(-1)
 if err != nil {
 http.Error(w, "Error reading directory", http.StatusInternalServerError)
 return
 }
 
 
 sort.Slice(dirs, func(i, j int) bool { return dirs[i].Name() < dirs[j].Name() })
 
 for _, ff := range dirs {
 if !ff.IsDir() {
 
 fi, err := fs.Open(path.Join(name, ff.Name()))
 if err != nil {
 msg, code := toHTTPError(err)
 http.Error(w, msg, code)
 return
 }
 
 io.Copy(bw, fi)
 size += ff.Size()
 }
 }
 
 serveContent(w, r, d.Name(), d.ModTime(), sizeFunc, bytes.NewReader(buffer.Bytes()))
 } else {
 size = d.Size()
 
 serveContent(w, r, d.Name(), d.ModTime(), sizeFunc, f)
 }
 }
 
 var unixEpochTime = time.Unix(0, 0)
 
 
 func isZeroTime(t time.Time) bool {
 return t.IsZero() || t.Equal(unixEpochTime)
 }
 
 func setLastModified(w http.ResponseWriter, modtime time.Time) {
 if !isZeroTime(modtime) {
 w.Header().Set("Last-Modified", modtime.UTC().Format(http.TimeFormat))
 }
 }
 
 func serveContent(w http.ResponseWriter, r *http.Request, name string, modtime time.Time, sizeFunc func() (int64, error), content io.ReadSeeker) {
 setLastModified(w, modtime)
 
 size, err := sizeFunc()
 if err != nil {
 http.Error(w, err.Error(), http.StatusInternalServerError)
 return
 }
 
 sendSize := size
 var sendContent io.Reader = content
 if size >= 0 {
 w.Header().Set("Accept-Ranges", "bytes")
 if w.Header().Get("Content-Encoding") == "" {
 w.Header().Set("Content-Length", strconv.FormatInt(sendSize, 10))
 }
 }
 
 w.WriteHeader(http.StatusOK)
 if r.Method != "HEAD" {
 io.CopyN(w, sendContent, sendSize)
 }
 }
 
 |