From e6bfd061c71ef7ef06e559a6d1d041b997ea633f Mon Sep 17 00:00:00 2001
From: chrislu <chris.lu@gmail.com>
Date: Mon, 29 Apr 2024 06:25:06 -0700
Subject: [PATCH] AllowEmptyFolder checks during object deletion

---
 weed/s3api/s3api_object_handlers_delete.go | 34 +++++++++++++++++-----
 weed/s3api/s3api_object_handlers_list.go   |  6 ++--
 2 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/weed/s3api/s3api_object_handlers_delete.go b/weed/s3api/s3api_object_handlers_delete.go
index f189d4ce4..197522d0c 100644
--- a/weed/s3api/s3api_object_handlers_delete.go
+++ b/weed/s3api/s3api_object_handlers_delete.go
@@ -27,16 +27,36 @@ func (s3a *S3ApiServer) DeleteObjectHandler(w http.ResponseWriter, r *http.Reque
 	bucket, object := s3_constants.GetBucketAndObject(r)
 	glog.V(3).Infof("DeleteObjectHandler %s %s", bucket, object)
 
-	destUrl := s3a.toFilerUrl(bucket, object)
+	object = urlPathEscape(removeDuplicateSlashes(object))
 
-	s3a.proxyToFiler(w, r, destUrl, true, func(proxyResponse *http.Response, w http.ResponseWriter) (statusCode int) {
-		statusCode = http.StatusNoContent
-		for k, v := range proxyResponse.Header {
-			w.Header()[k] = v
+	s3a.WithFilerClient(false, func(client filer_pb.SeaweedFilerClient) error {
+
+		err := doDeleteEntry(client, s3a.option.BucketsPath+"/"+bucket, object, true, false)
+		if err != nil {
+			// skip deletion error, usually the file is not found
+			return nil
+		}
+
+		if s3a.option.AllowEmptyFolder {
+			return nil
 		}
-		w.WriteHeader(statusCode)
-		return statusCode
+
+		directoriesWithDeletion := make(map[string]int)
+		lastSeparator := strings.LastIndex(object, "/")
+		if lastSeparator > 0 {
+			parentDirectoryPath := fmt.Sprintf("%s/%s", s3a.option.BucketsPath, bucket)
+			directoriesWithDeletion[parentDirectoryPath]++
+
+			// purge empty folders, only checking folders with deletions
+			for len(directoriesWithDeletion) > 0 {
+				directoriesWithDeletion = s3a.doDeleteEmptyDirectories(client, directoriesWithDeletion)
+			}
+		}
+
+		return nil
 	})
+
+	w.WriteHeader(http.StatusNoContent)
 }
 
 // / ObjectIdentifier carries key name for the object to delete.
diff --git a/weed/s3api/s3api_object_handlers_list.go b/weed/s3api/s3api_object_handlers_list.go
index b00e4630d..38e7f6fef 100644
--- a/weed/s3api/s3api_object_handlers_list.go
+++ b/weed/s3api/s3api_object_handlers_list.go
@@ -415,9 +415,9 @@ func (s3a *S3ApiServer) doListFilerEntries(client filer_pb.SeaweedFilerClient, d
 			} else {
 				var isEmpty bool
 				if !s3a.option.AllowEmptyFolder && entry.IsOlderDir() {
-					if isEmpty, err = s3a.ensureDirectoryAllEmpty(client, dir, entry.Name); err != nil {
-						glog.Errorf("check empty folder %s: %v", dir, err)
-					}
+					//if isEmpty, err = s3a.ensureDirectoryAllEmpty(client, dir, entry.Name); err != nil {
+					//	glog.Errorf("check empty folder %s: %v", dir, err)
+					//}
 				}
 				if !isEmpty {
 					eachEntryFn(dir, entry)