|
@@ -0,0 +1,102 @@
|
|
|
|
|
+package handler
|
|
|
|
|
+
|
|
|
|
|
+import (
|
|
|
|
|
+ "fmt"
|
|
|
|
|
+ "net/http"
|
|
|
|
|
+ "os"
|
|
|
|
|
+ "path"
|
|
|
|
|
+ "strings"
|
|
|
|
|
+
|
|
|
|
|
+ "git.i2edu.net/i2/go-zero/rest"
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+const INDEX = "index.html"
|
|
|
|
|
+
|
|
|
|
|
+type ServeFileSystem interface {
|
|
|
|
|
+ http.FileSystem
|
|
|
|
|
+ Exists(prefix string, path string) bool
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+type neuteredReaddirFile struct {
|
|
|
|
|
+ http.File
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+type onlyFilesFS struct {
|
|
|
|
|
+ fs http.FileSystem
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// Open conforms to http.Filesystem.
|
|
|
|
|
+func (fs onlyFilesFS) Open(name string) (http.File, error) {
|
|
|
|
|
+ f, err := fs.fs.Open(name)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
|
|
+ return neuteredReaddirFile{f}, nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+type localFileSystem struct {
|
|
|
|
|
+ http.FileSystem
|
|
|
|
|
+ root string
|
|
|
|
|
+ indexes bool
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func Dir(root string, listDirectory bool) http.FileSystem {
|
|
|
|
|
+ fs := http.Dir(root)
|
|
|
|
|
+ if listDirectory {
|
|
|
|
|
+ return fs
|
|
|
|
|
+ }
|
|
|
|
|
+ return &onlyFilesFS{fs}
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func LocalFile(root string, indexes bool) *localFileSystem {
|
|
|
|
|
+ return &localFileSystem{
|
|
|
|
|
+ FileSystem: Dir(root, indexes),
|
|
|
|
|
+ root: root,
|
|
|
|
|
+ indexes: indexes,
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (l *localFileSystem) Exists(prefix string, filepath string) bool {
|
|
|
|
|
+ if p := strings.TrimPrefix(filepath, prefix); len(p) < len(filepath) {
|
|
|
|
|
+ name := path.Join(l.root, p)
|
|
|
|
|
+ stats, err := os.Stat(name)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+ if stats.IsDir() {
|
|
|
|
|
+ if !l.indexes {
|
|
|
|
|
+ index := path.Join(name, INDEX)
|
|
|
|
|
+ _, err := os.Stat(index)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return true
|
|
|
|
|
+ }
|
|
|
|
|
+ return false
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// Static returns a middleware handler that serves static files in the given directory.
|
|
|
|
|
+func Static(urlPrefix string, fs ServeFileSystem) (r []rest.Route) {
|
|
|
|
|
+ fileserver := http.FileServer(fs)
|
|
|
|
|
+ if urlPrefix != "" {
|
|
|
|
|
+ fileserver = http.StripPrefix(urlPrefix, fileserver)
|
|
|
|
|
+ }
|
|
|
|
|
+ h := func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
+ if fs.Exists(urlPrefix, r.URL.Path) {
|
|
|
|
|
+ fileserver.ServeHTTP(w, r)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ dirlevel := []string{":1", ":2", ":3", ":4", ":5", ":6", ":7", ":8"}
|
|
|
|
|
+ for i := 1; i < len(dirlevel); i++ {
|
|
|
|
|
+ path := urlPrefix + strings.Join(dirlevel[:i], "/")
|
|
|
|
|
+ r = append(r, rest.Route{
|
|
|
|
|
+ Method: http.MethodGet,
|
|
|
|
|
+ Path: path,
|
|
|
|
|
+ Handler: h,
|
|
|
|
|
+ })
|
|
|
|
|
+ fmt.Println(path)
|
|
|
|
|
+ }
|
|
|
|
|
+ return
|
|
|
|
|
+}
|