mirror of
https://github.com/nezhahq/nezha.git
synced 2025-02-02 09:38:13 -05:00
103 lines
3.6 KiB
Diff
103 lines
3.6 KiB
Diff
|
@@ -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.
|