diff --git a/changelog/unreleased/fix-decomposedfs-upload.md b/changelog/unreleased/fix-decomposedfs-upload.md new file mode 100644 index 0000000000..c0a49f6ca7 --- /dev/null +++ b/changelog/unreleased/fix-decomposedfs-upload.md @@ -0,0 +1,5 @@ +Bugfix: fix decomposedfs upload + +The FS.Upload() implementation needs to handle direct uploads that did not initiate a unpload. + +https://github.com/cs3org/reva/pull/2330 \ No newline at end of file diff --git a/pkg/rhttp/datatx/manager/spaces/spaces.go b/pkg/rhttp/datatx/manager/spaces/spaces.go index 120697e7dd..2a314a0993 100644 --- a/pkg/rhttp/datatx/manager/spaces/spaces.go +++ b/pkg/rhttp/datatx/manager/spaces/spaces.go @@ -20,8 +20,6 @@ package spaces import ( "net/http" - "path" - "strings" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" "github.com/cs3org/reva/pkg/appctx" @@ -78,10 +76,8 @@ func (m *manager) Handler(fs storage.FS) (http.Handler, error) { case "GET", "HEAD": download.GetOrHeadFile(w, r, fs, spaceID) case "PUT": - // make a clean relative path - fn := path.Clean(strings.TrimLeft(r.URL.Path, "/")) + fn := utils.MakeRelativePath(r.URL.Path) defer r.Body.Close() - // TODO refactor: pass Reference to Upload & GetOrHeadFile // build a storage space reference storageid, opaqeid := utils.SplitStorageSpaceID(spaceID) diff --git a/pkg/storage/utils/decomposedfs/upload.go b/pkg/storage/utils/decomposedfs/upload.go index f9f2a1bf99..9075c3d5da 100644 --- a/pkg/storage/utils/decomposedfs/upload.go +++ b/pkg/storage/utils/decomposedfs/upload.go @@ -58,7 +58,19 @@ var defaultFilePerm = os.FileMode(0664) func (fs *Decomposedfs) Upload(ctx context.Context, ref *provider.Reference, r io.ReadCloser) (err error) { upload, err := fs.GetUpload(ctx, ref.GetPath()) if err != nil { - return errors.Wrap(err, "Decomposedfs: error retrieving upload") + // Upload corresponding to this ID was not found. + // Assume that this corresponds to the resource path to which the file has to be uploaded. + + // Set the length to 0 and set SizeIsDeferred to true + metadata := map[string]string{"sizedeferred": "true"} + uploadIDs, err := fs.InitiateUpload(ctx, ref, 0, metadata) + if err != nil { + return err + } + upload, err = fs.GetUpload(ctx, uploadIDs["simple"]) + if err != nil { + return errors.Wrap(err, "Decomposedfs: error retrieving upload") + } } uploadInfo := upload.(*fileUpload) diff --git a/pkg/storage/utils/decomposedfs/upload_test.go b/pkg/storage/utils/decomposedfs/upload_test.go index 1ad307b18f..e2c163c70b 100644 --- a/pkg/storage/utils/decomposedfs/upload_test.go +++ b/pkg/storage/utils/decomposedfs/upload_test.go @@ -117,7 +117,7 @@ var _ = Describe("File uploads", func() { Expect(err).ToNot(HaveOccurred()) Expect(resp.Status.Code).To(Equal(v1beta11.Code_CODE_OK)) spaceID = resp.StorageSpace.Id.OpaqueId - ref.ResourceId = &provider.ResourceId{StorageId: spaceID} + ref.ResourceId = &provider.ResourceId{StorageId: spaceID, OpaqueId: spaceID} }) Context("the user's quota is exceeded", func() { @@ -308,5 +308,36 @@ var _ = Describe("File uploads", func() { }) }) + When("the user directly uploads a file with a relative reference", func() { + It("succeeds", func() { + var ( + fileContent = []byte("0123456789") + ) + + uploadRef := &provider.Reference{ResourceId: ref.ResourceId, Path: "./newfile.txt"} + + bs.On("Upload", mock.AnythingOfType("string"), mock.AnythingOfType("*os.File")). + Return(nil). + Run(func(args mock.Arguments) { + reader := args.Get(1).(io.Reader) + data, err := ioutil.ReadAll(reader) + + Expect(err).ToNot(HaveOccurred()) + Expect(data).To(Equal(fileContent)) + }) + + err := fs.Upload(ctx, uploadRef, ioutil.NopCloser(bytes.NewReader(fileContent))) + + Expect(err).ToNot(HaveOccurred()) + bs.AssertCalled(GinkgoT(), "Upload", mock.Anything, mock.Anything) + + relativeListRef := &provider.Reference{ResourceId: ref.ResourceId, Path: "."} + resources, err := fs.ListFolder(ctx, relativeListRef, []string{}) + Expect(err).ToNot(HaveOccurred()) + Expect(len(resources)).To(Equal(2)) // .space folder + newfile.txt + Expect(resources[0].Path).To(Or(Equal("newfile.txt"), Equal(".space"))) + Expect(resources[1].Path).To(Or(Equal("newfile.txt"), Equal(".space"))) + }) + }) }) })