From e39a74006e2289b1d991e0a68c2add3279045b53 Mon Sep 17 00:00:00 2001 From: Ishank Arora Date: Thu, 24 Sep 2020 13:45:48 +0200 Subject: [PATCH] Forward POST request to data server only for non-zero files --- internal/http/services/owncloud/ocdav/tus.go | 72 ++++++++++++-------- pkg/storage/utils/localfs/upload.go | 4 ++ 2 files changed, 47 insertions(+), 29 deletions(-) diff --git a/internal/http/services/owncloud/ocdav/tus.go b/internal/http/services/owncloud/ocdav/tus.go index b4d6d69cf8..48cbfb5fb0 100644 --- a/internal/http/services/owncloud/ocdav/tus.go +++ b/internal/http/services/owncloud/ocdav/tus.go @@ -21,6 +21,7 @@ package ocdav import ( "net/http" "path" + "strconv" "strings" "time" @@ -167,44 +168,57 @@ func (s *svc) handleTusPost(w http.ResponseWriter, r *http.Request, ns string) { // TODO check this really streams if r.Header.Get("Content-Type") == "application/offset+octet-stream" { - httpClient := rhttp.GetHTTPClient( - rhttp.Context(ctx), - rhttp.Timeout(time.Duration(s.c.Timeout*int64(time.Second))), - rhttp.Insecure(s.c.Insecure), - ) - httpReq, err := rhttp.NewRequest(ctx, "PATCH", uRes.UploadEndpoint, r.Body) + length, err := strconv.ParseInt(r.Header.Get("Content-Length"), 10, 64) if err != nil { log.Err(err).Msg("wrong request") - w.WriteHeader(http.StatusInternalServerError) + w.WriteHeader(http.StatusBadRequest) return } - httpReq.Header.Set("Content-Type", r.Header.Get("Content-Type")) - httpReq.Header.Set("Content-Length", r.Header.Get("Content-Length")) - if r.Header.Get("Upload-Offset") != "" { - httpReq.Header.Set("Upload-Offset", r.Header.Get("Upload-Offset")) - } else { - httpReq.Header.Set("Upload-Offset", "0") - } - httpReq.Header.Set("Tus-Resumable", r.Header.Get("Tus-Resumable")) + var httpRes *http.Response - httpRes, err := httpClient.Do(httpReq) - if err != nil { - log.Err(err).Msg("error doing GET request to data service") - w.WriteHeader(http.StatusInternalServerError) - return - } - defer httpRes.Body.Close() + if length != 0 { + httpClient := rhttp.GetHTTPClient( + rhttp.Context(ctx), + rhttp.Timeout(time.Duration(s.c.Timeout*int64(time.Second))), + rhttp.Insecure(s.c.Insecure), + ) + httpReq, err := rhttp.NewRequest(ctx, "PATCH", uRes.UploadEndpoint, r.Body) + if err != nil { + log.Err(err).Msg("wrong request") + w.WriteHeader(http.StatusInternalServerError) + return + } - w.Header().Set("Upload-Offset", httpRes.Header.Get("Upload-Offset")) - w.Header().Set("Tus-Resumable", httpRes.Header.Get("Tus-Resumable")) - if httpRes.StatusCode != http.StatusNoContent { - w.WriteHeader(httpRes.StatusCode) - return + httpReq.Header.Set("Content-Type", r.Header.Get("Content-Type")) + httpReq.Header.Set("Content-Length", r.Header.Get("Content-Length")) + if r.Header.Get("Upload-Offset") != "" { + httpReq.Header.Set("Upload-Offset", r.Header.Get("Upload-Offset")) + } else { + httpReq.Header.Set("Upload-Offset", "0") + } + httpReq.Header.Set("Tus-Resumable", r.Header.Get("Tus-Resumable")) + + httpRes, err = httpClient.Do(httpReq) + if err != nil { + log.Err(err).Msg("error doing GET request to data service") + w.WriteHeader(http.StatusInternalServerError) + return + } + defer httpRes.Body.Close() + + w.Header().Set("Upload-Offset", httpRes.Header.Get("Upload-Offset")) + w.Header().Set("Tus-Resumable", httpRes.Header.Get("Tus-Resumable")) + if httpRes.StatusCode != http.StatusNoContent { + w.WriteHeader(httpRes.StatusCode) + return + } + } else { + log.Info().Msg("Skipping sending a Patch request as body is empty") } // check if upload was fully completed - if httpRes.Header.Get("Upload-Offset") == r.Header.Get("Upload-Length") { + if length == 0 || httpRes.Header.Get("Upload-Offset") == r.Header.Get("Upload-Length") { // get uploaded file metadata sRes, err := client.Stat(ctx, sReq) if err != nil { @@ -226,7 +240,7 @@ func (s *svc) handleTusPost(w http.ResponseWriter, r *http.Request, ns string) { w.WriteHeader(http.StatusInternalServerError) return } - if httpRes.Header.Get("X-OC-Mtime") != "" { + if httpRes != nil && httpRes.Header != nil && httpRes.Header.Get("X-OC-Mtime") != "" { // set the "accepted" value if returned in the upload response headers w.Header().Set("X-OC-Mtime", httpRes.Header.Get("X-OC-Mtime")) } diff --git a/pkg/storage/utils/localfs/upload.go b/pkg/storage/utils/localfs/upload.go index 019d3e7c47..301fd51e57 100644 --- a/pkg/storage/utils/localfs/upload.go +++ b/pkg/storage/utils/localfs/upload.go @@ -169,6 +169,7 @@ func (fs *localfs) NewUpload(ctx context.Context, info tusd.FileInfo) (upload tu binPath: binPath, infoPath: binPath + ".info", fs: fs, + ctx: ctx, } if !info.SizeIsDeferred && info.Size == 0 { @@ -316,6 +317,9 @@ func (upload *fileUpload) FinishUpload(ctx context.Context) error { } err := os.Rename(upload.binPath, np) + if err != nil { + return err + } // only delete the upload if it was successfully written to the fs if err := os.Remove(upload.infoPath); err != nil {