aboutsummaryrefslogtreecommitdiff
path: root/internal/bunny/api_delete.go
diff options
context:
space:
mode:
authortsne <tsne.dev@outlook.com>2026-07-06 16:52:20 +0200
committertsne <tsne.dev@outlook.com>2026-07-06 19:21:15 +0200
commit2c41acab4c97f584e8e199b31dc456194b8d7e6c (patch)
tree42381deb6c4f6da0f32945432207a31b4d86664e /internal/bunny/api_delete.go
downloadhopper-2c41acab4c97f584e8e199b31dc456194b8d7e6c.tar.gz
initial
Diffstat (limited to 'internal/bunny/api_delete.go')
-rw-r--r--internal/bunny/api_delete.go46
1 files changed, 46 insertions, 0 deletions
diff --git a/internal/bunny/api_delete.go b/internal/bunny/api_delete.go
new file mode 100644
index 0000000..868b0f3
--- /dev/null
+++ b/internal/bunny/api_delete.go
@@ -0,0 +1,46 @@
+package bunny
+
+import (
+ "context"
+ "fmt"
+ "io"
+ "net/http"
+ "strings"
+)
+
+// Delete removes a single object with a raw DELETE, applying the shared retry
+// policy.
+func (api *API) Delete(ctx context.Context, path string) error {
+ return api.delete(ctx, api.url(path))
+}
+
+// DeleteDir removes a directory. Bunny's storage endpoints identify a directory
+// by a trailing slash on the URL (the same quirk listDir relies on), so we
+// append it here rather than leak the convention to callers. The delete is
+// recursive.
+//
+// CAUTION: The delete is recursive AND prune decides emptiness from the
+// pre-delete listing snapshot. If another actor uploads a file under this directory
+// between the snapshot and this call, the recursive delete will remove it.
+func (api *API) DeleteDir(ctx context.Context, path string) error {
+ u := api.url(path)
+ if !strings.HasSuffix(u, "/") {
+ u += "/"
+ }
+ return api.delete(ctx, u)
+}
+
+func (api *API) delete(ctx context.Context, u string) error {
+ req, err := http.NewRequestWithContext(ctx, http.MethodDelete, u, nil)
+ if err != nil {
+ return fmt.Errorf("build request: %w", err)
+ }
+
+ resp, err := api.do(ctx, req)
+ if err != nil {
+ return err
+ }
+ io.Copy(io.Discard, resp.Body)
+ resp.Body.Close()
+ return nil
+}