fix:introduce buffered response writer for webdav, fix status/error return failed. (#2544)

* fix: introduce buffered response writer for webdav, fix webdav status/error return failed.

* fix: bypass buffered writer for GET/HEAD/POST requests
pull/2443/head
Ovear 2022-12-02 17:59:59 +08:00 committed by GitHub
parent ae791c8634
commit 0838feeb82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 9 deletions

View File

@ -0,0 +1,46 @@
package webdav
import (
"net/http"
)
type bufferedResponseWriter struct {
statusCode int
data []byte
header http.Header
}
func (w *bufferedResponseWriter) Header() http.Header {
if w.header == nil {
w.header = make(http.Header)
}
return w.header
}
func (w *bufferedResponseWriter) Write(bytes []byte) (int, error) {
w.data = append(w.data, bytes...)
return len(bytes), nil
}
func (w *bufferedResponseWriter) WriteHeader(statusCode int) {
if w.statusCode == 0 {
w.statusCode = statusCode
}
}
func (w *bufferedResponseWriter) WriteToResponse(rw http.ResponseWriter) (int, error) {
h := rw.Header()
for k, vs := range w.header {
for _, v := range vs {
h.Add(k, v)
}
}
rw.WriteHeader(w.statusCode)
return rw.Write(w.data)
}
func newBufferedResponseWriter() *bufferedResponseWriter {
return &bufferedResponseWriter{
statusCode: 0,
}
}

View File

@ -45,30 +45,33 @@ func (h *Handler) stripPrefix(p string) (string, int, error) {
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
status, err := http.StatusBadRequest, errUnsupportedMethod
brw := newBufferedResponseWriter()
useBufferedWriter := true
if h.LockSystem == nil {
status, err = http.StatusInternalServerError, errNoLockSystem
} else {
switch r.Method {
case "OPTIONS":
status, err = h.handleOptions(w, r)
status, err = h.handleOptions(brw, r)
case "GET", "HEAD", "POST":
useBufferedWriter = false
status, err = h.handleGetHeadPost(w, r)
case "DELETE":
status, err = h.handleDelete(w, r)
status, err = h.handleDelete(brw, r)
case "PUT":
status, err = h.handlePut(w, r)
status, err = h.handlePut(brw, r)
case "MKCOL":
status, err = h.handleMkcol(w, r)
status, err = h.handleMkcol(brw, r)
case "COPY", "MOVE":
status, err = h.handleCopyMove(w, r)
status, err = h.handleCopyMove(brw, r)
case "LOCK":
status, err = h.handleLock(w, r)
status, err = h.handleLock(brw, r)
case "UNLOCK":
status, err = h.handleUnlock(w, r)
status, err = h.handleUnlock(brw, r)
case "PROPFIND":
status, err = h.handlePropfind(w, r)
status, err = h.handlePropfind(brw, r)
case "PROPPATCH":
status, err = h.handleProppatch(w, r)
status, err = h.handleProppatch(brw, r)
}
}
@ -77,6 +80,8 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if status != http.StatusNoContent {
w.Write([]byte(StatusText(status)))
}
} else if useBufferedWriter {
brw.WriteToResponse(w)
}
if h.Logger != nil && err != nil {
h.Logger(r, err)