diff --git a/internal/storage/FileServing.go b/internal/storage/FileServing.go index 64ce9f70..e0b76788 100644 --- a/internal/storage/FileServing.go +++ b/internal/storage/FileServing.go @@ -384,6 +384,7 @@ func ReplaceFile(fileId, newFileContentId string, delete bool) (models.File, err return models.File{}, ErrorReplaceE2EFile } + previousContent := file file.Name = newFileContent.Name file.Size = newFileContent.Size file.SHA1 = newFileContent.SHA1 @@ -392,12 +393,27 @@ func ReplaceFile(fileId, newFileContentId string, delete bool) (models.File, err file.SizeBytes = newFileContent.SizeBytes file.Encryption = newFileContent.Encryption database.SaveMetaData(file) + deleteUnreferencedSource(previousContent) if delete { DeleteFile(newFileContent.Id, true) } return file, nil } +// deleteUnreferencedSource deletes the stored data of a file that no metadata entry points at anymore. +// CleanUp only reaches sources that are still referenced by an entry, so the content a replaced file +// used to hold would otherwise stay in storage for good. +func deleteUnreferencedSource(file models.File) { + for _, metadata := range database.GetAllMetadata() { + if metadata.SHA1 == file.SHA1 { + return + } + } + if FileExists(file, configuration.Get().DataDir) { + deleteSource(file, configuration.Get().DataDir) + } +} + func isChangeRequested(parametersToChange, parameter int) bool { return parametersToChange¶meter != 0 } diff --git a/internal/storage/FileServing_test.go b/internal/storage/FileServing_test.go index d8369d62..1cfdddd5 100644 --- a/internal/storage/FileServing_test.go +++ b/internal/storage/FileServing_test.go @@ -895,6 +895,44 @@ func TestReplaceFile(t *testing.T) { _, ok = GetFile(newFile.Id) test.IsEqualBool(t, ok, false) } +func TestReplaceFileDeletesPreviousContent(t *testing.T) { + dataDir := configuration.Get().DataDir + previousSha1 := "replacedoldcontent" + newSha1 := "replacednewcontent" + test.IsNil(t, os.WriteFile(dataDir+"/"+previousSha1, []byte("old"), 0600)) + test.IsNil(t, os.WriteFile(dataDir+"/"+newSha1, []byte("new"), 0600)) + + original := models.File{ + Id: "replacesourceoriginal", + Name: "old.txt", + Size: "3 B", + SHA1: previousSha1, + ContentType: "text/plain", + UnlimitedDownloads: true, + UnlimitedTime: true, + SizeBytes: 3, + } + replacement := models.File{ + Id: "replacesourcenew", + Name: "new.txt", + Size: "3 B", + SHA1: newSha1, + ContentType: "text/plain", + UnlimitedDownloads: true, + UnlimitedTime: true, + SizeBytes: 3, + } + database.SaveMetaData(original) + database.SaveMetaData(replacement) + + _, err := ReplaceFile(original.Id, replacement.Id, false) + test.IsNil(t, err) + + _, err = os.Stat(dataDir + "/" + previousSha1) + test.IsEqualBool(t, os.IsNotExist(err), true) + test.FileExists(t, dataDir+"/"+newSha1) +} + func TestParallelDownloads(t *testing.T) { const allowedDownloads = 5