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
This commit is contained in:
parent
ae791c8634
commit
0838feeb82
46
server/webdav/buffered_response_writer.go
Normal file
46
server/webdav/buffered_response_writer.go
Normal 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,
|
||||||
|
}
|
||||||
|
}
|
@ -45,30 +45,33 @@ func (h *Handler) stripPrefix(p string) (string, int, error) {
|
|||||||
|
|
||||||
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
status, err := http.StatusBadRequest, errUnsupportedMethod
|
status, err := http.StatusBadRequest, errUnsupportedMethod
|
||||||
|
brw := newBufferedResponseWriter()
|
||||||
|
useBufferedWriter := true
|
||||||
if h.LockSystem == nil {
|
if h.LockSystem == nil {
|
||||||
status, err = http.StatusInternalServerError, errNoLockSystem
|
status, err = http.StatusInternalServerError, errNoLockSystem
|
||||||
} else {
|
} else {
|
||||||
switch r.Method {
|
switch r.Method {
|
||||||
case "OPTIONS":
|
case "OPTIONS":
|
||||||
status, err = h.handleOptions(w, r)
|
status, err = h.handleOptions(brw, r)
|
||||||
case "GET", "HEAD", "POST":
|
case "GET", "HEAD", "POST":
|
||||||
|
useBufferedWriter = false
|
||||||
status, err = h.handleGetHeadPost(w, r)
|
status, err = h.handleGetHeadPost(w, r)
|
||||||
case "DELETE":
|
case "DELETE":
|
||||||
status, err = h.handleDelete(w, r)
|
status, err = h.handleDelete(brw, r)
|
||||||
case "PUT":
|
case "PUT":
|
||||||
status, err = h.handlePut(w, r)
|
status, err = h.handlePut(brw, r)
|
||||||
case "MKCOL":
|
case "MKCOL":
|
||||||
status, err = h.handleMkcol(w, r)
|
status, err = h.handleMkcol(brw, r)
|
||||||
case "COPY", "MOVE":
|
case "COPY", "MOVE":
|
||||||
status, err = h.handleCopyMove(w, r)
|
status, err = h.handleCopyMove(brw, r)
|
||||||
case "LOCK":
|
case "LOCK":
|
||||||
status, err = h.handleLock(w, r)
|
status, err = h.handleLock(brw, r)
|
||||||
case "UNLOCK":
|
case "UNLOCK":
|
||||||
status, err = h.handleUnlock(w, r)
|
status, err = h.handleUnlock(brw, r)
|
||||||
case "PROPFIND":
|
case "PROPFIND":
|
||||||
status, err = h.handlePropfind(w, r)
|
status, err = h.handlePropfind(brw, r)
|
||||||
case "PROPPATCH":
|
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 {
|
if status != http.StatusNoContent {
|
||||||
w.Write([]byte(StatusText(status)))
|
w.Write([]byte(StatusText(status)))
|
||||||
}
|
}
|
||||||
|
} else if useBufferedWriter {
|
||||||
|
brw.WriteToResponse(w)
|
||||||
}
|
}
|
||||||
if h.Logger != nil && err != nil {
|
if h.Logger != nil && err != nil {
|
||||||
h.Logger(r, err)
|
h.Logger(r, err)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user