mirror of
https://github.com/nezhahq/nezha.git
synced 2025-01-22 04:38:14 -05:00
fix windows ci (#934)
* fix windows ci * perm * use custom writer * remove patches * fuck codeql
This commit is contained in:
parent
7662471c2f
commit
3c72d6ce64
5
.github/workflows/release.yml
vendored
5
.github/workflows/release.yml
vendored
@ -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
|
||||
|
15
.github/workflows/test.yml
vendored
15
.github/workflows/test.yml
vendored
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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.
|
@ -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.
|
Loading…
Reference in New Issue
Block a user