From 3c72d6ce6415a83688fe84c51b78b339886326b3 Mon Sep 17 00:00:00 2001 From: UUBulb <35923940+uubulb@users.noreply.github.com> Date: Wed, 1 Jan 2025 00:58:57 +0800 Subject: [PATCH] fix windows ci (#934) * fix windows ci * perm * use custom writer * remove patches * fuck codeql --- .github/workflows/release.yml | 5 -- .github/workflows/test.yml | 15 ++-- cmd/dashboard/controller/controller.go | 27 ++++++- script/patch/fs.patch | 102 ------------------------- script/patch/gin-context.patch | 11 --- 5 files changed, 29 insertions(+), 131 deletions(-) delete mode 100644 script/patch/fs.patch delete mode 100644 script/patch/gin-context.patch diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 545b951..26e6b55 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -50,11 +50,6 @@ jobs: with: go-version: "1.23.1" - - name: patch net/http/fs.go - run: | - patch -p0 --forward `go env GOROOT`/src/net/http/fs.go < ./script/patch/fs.patch || true - patch -p0 --forward `go env GOMODCACHE`/github.com/gin-gonic/gin@v1.10.0/context.go < ./script/patch/gin-context.patch || true - - name: generate swagger docs run: | go install github.com/swaggo/swag/cmd/swag@latest diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 268a0d2..9e837e0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -18,36 +18,31 @@ jobs: fail-fast: true matrix: os: [ubuntu, windows, macos] - + runs-on: ${{ matrix.os }}-latest env: GO111MODULE: on steps: - uses: actions/checkout@v4 - + - uses: actions/setup-go@v5 with: go-version: "1.23.1" - - name: patch net/http/fs.go - run: | - patch -p0 --forward `go env GOROOT`/src/net/http/fs.go < ./script/patch/fs.patch || true - patch -p0 --forward `go env GOMODCACHE`/github.com/gin-gonic/gin@v1.10.0/context.go < ./script/patch/gin-context.patch || true - - name: generate swagger docs run: | go install github.com/swaggo/swag/cmd/swag@latest touch ./cmd/dashboard/user-dist/a touch ./cmd/dashboard/admin-dist/a swag init --pd -d . -g ./cmd/dashboard/main.go -o ./cmd/dashboard/docs --parseGoList=false - + - name: Unit test run: | go test -v ./... - + - name: Build test run: go build -v ./cmd/dashboard - + - name: Run Gosec Security Scanner if: runner.os == 'Linux' uses: securego/gosec@master diff --git a/cmd/dashboard/controller/controller.go b/cmd/dashboard/controller/controller.go index b1192ff..1d3e680 100644 --- a/cmd/dashboard/controller/controller.go +++ b/cmd/dashboard/controller/controller.go @@ -285,10 +285,31 @@ func getUid(c *gin.Context) uint64 { return user.ID } +type ginCustomWriter struct { + gin.ResponseWriter + + customCode int +} + +func newCustomWriter(c *gin.Context, code int) *ginCustomWriter { + return &ginCustomWriter{ + ResponseWriter: c.Writer, + customCode: code, + } +} + +func (w *ginCustomWriter) WriteHeader(code int) { + w.ResponseWriter.WriteHeader(w.customCode) +} + +func fileWithCustomStatusCode(c *gin.Context, filepath string, customCode int) { + http.ServeFile(newCustomWriter(c, customCode), c.Request, path.Clean(filepath)) +} + func fallbackToFrontend(frontendDist fs.FS) func(*gin.Context) { checkLocalFileOrFs := func(c *gin.Context, fs fs.FS, path string, customStatusCode int) bool { if _, err := os.Stat(path); err == nil { - c.FileWithCustomStatusCode(path, customStatusCode) + fileWithCustomStatusCode(c, path, customStatusCode) return true } f, err := fs.Open(path) @@ -303,7 +324,7 @@ func fallbackToFrontend(frontendDist fs.FS) func(*gin.Context) { if fileStat.IsDir() { return false } - http.ServeContentCustomStatusCode(c.Writer, c.Request, path, fileStat.ModTime(), f.(io.ReadSeeker), customStatusCode) + http.ServeContent(newCustomWriter(c, customStatusCode), c.Request, path, fileStat.ModTime(), f.(io.ReadSeeker)) return true } return func(c *gin.Context) { @@ -323,7 +344,7 @@ func fallbackToFrontend(frontendDist fs.FS) func(*gin.Context) { } return } - localFilePath := path.Join(singleton.Conf.UserTemplate, c.Request.URL.Path) + localFilePath := path.Join(singleton.Conf.UserTemplate, path.Clean(c.Request.URL.Path)) if checkLocalFileOrFs(c, frontendDist, localFilePath, http.StatusOK) { return } diff --git a/script/patch/fs.patch b/script/patch/fs.patch deleted file mode 100644 index f379c55..0000000 --- a/script/patch/fs.patch +++ /dev/null @@ -1,102 +0,0 @@ -@@ -249,9 +249,24 @@ - } - return size, nil - } -- serveContent(w, req, name, modtime, sizeFunc, content) -+ serveContent(w, req, name, modtime, sizeFunc, content, StatusOK) - } - -+func ServeContentCustomStatusCode(w ResponseWriter, req *Request, name string, modtime time.Time, content io.ReadSeeker, code int) { -+ 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, code) -+} -+ - // errSeeker is returned by ServeContent's sizeFunc when the content - // 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 -@@ -266,15 +281,13 @@ - // if modtime.IsZero(), modtime is unknown. - // content must be seeked to the beginning of the file. - // The sizeFunc is called at most once. Its error, if any, is sent in the HTTP response. --func serveContent(w ResponseWriter, r *Request, name string, modtime time.Time, sizeFunc func() (int64, error), content io.ReadSeeker) { -+func serveContent(w ResponseWriter, r *Request, name string, modtime time.Time, sizeFunc func() (int64, error), content io.ReadSeeker, code int) { - setLastModified(w, modtime) - done, rangeReq := checkPreconditions(w, r, modtime) - if done { - return - } - -- code := StatusOK -- - // If Content-Type isn't set, use the file's extension to find it, but - // if the Content-Type is unset explicitly, do not sniff the type. - ctypes, haveType := w.Header()["Content-Type"] -@@ -671,7 +684,7 @@ - } - - // name is '/'-separated, not filepath.Separator. --func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirect bool) { -+func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirect bool, statusCode int) { - const indexPage = "/index.html" - - // redirect .../index.html to .../ -@@ -753,7 +766,7 @@ - - // serveContent will check modification time - sizeFunc := func() (int64, error) { return d.Size(), nil } -- serveContent(w, r, d.Name(), d.ModTime(), sizeFunc, f) -+ serveContent(w, r, d.Name(), d.ModTime(), sizeFunc, f, statusCode) - } - - // toHTTPError returns a non-specific HTTP error message and status code -@@ -814,7 +827,21 @@ - return - } - dir, file := filepath.Split(name) -- serveFile(w, r, Dir(dir), file, false) -+ serveFile(w, r, Dir(dir), file, false, StatusOK) -+} -+ -+func ServeFileWithCustomStatusCode(w ResponseWriter, r *Request, name string, statusCode int) { -+ if containsDotDot(r.URL.Path) { -+ // Too many programs use r.URL.Path to construct the argument to -+ // serveFile. Reject the request under the assumption that happened -+ // here and ".." may not be wanted. -+ // Note that name might not contain "..", for example if code (still -+ // incorrectly) used filepath.Join(myDir, r.URL.Path). -+ serveError(w, "invalid URL path", StatusBadRequest) -+ return -+ } -+ dir, file := filepath.Split(name) -+ serveFile(w, r, Dir(dir), file, false, statusCode) - } - - // ServeFileFS replies to the request with the contents -@@ -847,7 +874,7 @@ - serveError(w, "invalid URL path", StatusBadRequest) - return - } -- serveFile(w, r, FS(fsys), name, false) -+ serveFile(w, r, FS(fsys), name, false, StatusOK) - } - - func containsDotDot(v string) bool { -@@ -983,7 +1010,7 @@ - upath = "/" + upath - r.URL.Path = upath - } -- serveFile(w, r, f.root, path.Clean(upath), true) -+ serveFile(w, r, f.root, path.Clean(upath), true, StatusOK) - } - - // httpRange specifies the byte range to be sent to the client. diff --git a/script/patch/gin-context.patch b/script/patch/gin-context.patch deleted file mode 100644 index 866c414..0000000 --- a/script/patch/gin-context.patch +++ /dev/null @@ -1,11 +0,0 @@ -@@ -1073,6 +1073,10 @@ - // File writes the specified file into the body stream in an efficient way. - func (c *Context) File(filepath string) { - http.ServeFile(c.Writer, c.Request, filepath) -+} -+ -+func (c *Context) FileWithCustomStatusCode(filepath string, statusCode int) { -+ http.ServeFileWithCustomStatusCode(c.Writer, c.Request, filepath, statusCode) - } - - // FileFromFS writes the specified file from http.FileSystem into the body stream in an efficient way.