Browse Source

feat: 添加文件服务

double.huang 4 năm trước cách đây
mục cha
commit
866c5f5b07
4 tập tin đã thay đổi với 104 bổ sung1 xóa
  1. 0 1
      README.md
  2. BIN
      asserts/zero.png
  3. 2 0
      i2bill.go
  4. 102 0
      internal/handler/static.go

+ 0 - 1
README.md

@@ -10,6 +10,5 @@ goctl model mysql ddl -c -src model/user.sql -dir model
 ### RUN API GATEWAY
 go run i2bill.go -f etc/i2bill-api.yaml
 
-
 ### TEST
 https://api-test-bill.i2edu.net/api/users/id/1

BIN
asserts/zero.png


+ 2 - 0
i2bill.go

@@ -25,6 +25,8 @@ func main() {
 	defer server.Stop()
 
 	handler.RegisterHandlers(server, ctx)
+	// Register asserts routes
+	server.AddRoutes(handler.Static("/asserts/", handler.LocalFile("asserts", false)))
 	fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
 	server.Start()
 }

+ 102 - 0
internal/handler/static.go

@@ -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
+}