fs/main.go

78 lines
1.4 KiB
Go

package main
import (
"flag"
"fmt"
"log"
"net/http"
"os"
"path/filepath"
"strings"
"text/template"
_ "embed"
)
type Entry struct {
Name string
IsDir bool
}
type Result struct {
Err string
Entries []Entry
}
//go:embed index.html
var index string
var tpl = template.Must(template.New("index.html").Parse(index))
func Render(w http.ResponseWriter, data interface{}) {
w.Header().Set("Content-Type", "text/html;charset=utf8")
if err := tpl.Execute(w, data); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
func View(w http.ResponseWriter, r *http.Request) {
log.Println(r.URL.Path)
path := filepath.Join(*dir, filepath.Clean(r.URL.Path))
if !strings.HasSuffix(r.URL.Path, "/") {
w.Header().Add("Content-Disposition", fmt.Sprintf("attachment;filename=%s", filepath.Base(path)))
http.ServeFile(w, r, path)
return
}
entries, err := os.ReadDir(path)
if err != nil {
Render(w, &Result{Err: err.Error()})
return
}
items := make([]Entry, 0)
for _, entry := range entries {
items = append(items, Entry{
Name: entry.Name(),
IsDir: entry.IsDir(),
})
}
Render(w, &Result{Entries: items})
}
var (
dir = flag.String("dir", "./", "server file directory")
listen = flag.String("listen", ":3000", "listen address")
)
func main() {
flag.Parse()
http.HandleFunc("/", View)
log.Printf("server listen at %s", *listen)
log.Fatal(http.ListenAndServe(*listen, nil))
}