From 04b7616d26f7fc1f88e99b9d1d14775268e37632 Mon Sep 17 00:00:00 2001
From: Xuanwo <github@xuanwo.io>
Date: Thu, 14 Nov 2024 17:38:29 +0800
Subject: [PATCH] Add oss

Signed-off-by: Xuanwo <github@xuanwo.io>
---
 core/src/services/oss/backend.rs |  3 +++
 core/src/services/oss/core.rs    | 17 +++++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/core/src/services/oss/backend.rs b/core/src/services/oss/backend.rs
index a627e1d4a0d8..1ed309e4e810 100644
--- a/core/src/services/oss/backend.rs
+++ b/core/src/services/oss/backend.rs
@@ -445,6 +445,9 @@ impl Access for OssBackend {
                 write_with_cache_control: true,
                 write_with_content_type: true,
                 write_with_content_disposition: true,
+                // TODO: set this to false while version has been enabled.
+                write_with_if_not_exists: true,
+
                 // The min multipart size of OSS is 100 KiB.
                 //
                 // ref: <https://www.alibabacloud.com/help/en/oss/user-guide/multipart-upload-12>
diff --git a/core/src/services/oss/core.rs b/core/src/services/oss/core.rs
index 2a471ef8ce10..480ab13987d1 100644
--- a/core/src/services/oss/core.rs
+++ b/core/src/services/oss/core.rs
@@ -41,6 +41,7 @@ use serde::Deserialize;
 use serde::Serialize;
 
 use crate::raw::*;
+use crate::services::oss::core::constants::X_OSS_FORBID_OVERWRITE;
 use crate::*;
 
 pub mod constants {
@@ -48,6 +49,8 @@ pub mod constants {
 
     pub const X_OSS_SERVER_SIDE_ENCRYPTION_KEY_ID: &str = "x-oss-server-side-encryption-key-id";
 
+    pub const X_OSS_FORBID_OVERWRITE: &str = "x-oss-forbid-overwrite";
+
     pub const RESPONSE_CONTENT_DISPOSITION: &str = "response-content-disposition";
 
     pub const OSS_QUERY_VERSION_ID: &str = "versionId";
@@ -181,6 +184,20 @@ impl OssCore {
             req = req.header(CACHE_CONTROL, cache_control);
         }
 
+        // TODO: disable if not exists while version has been enabled.
+        //
+        // Specifies whether the object that is uploaded by calling the PutObject operation
+        // overwrites the existing object that has the same name. When versioning is enabled
+        // or suspended for the bucket to which you want to upload the object, the
+        // x-oss-forbid-overwrite header does not take effect. In this case, the object that
+        // is uploaded by calling the PutObject operation overwrites the existing object that
+        // has the same name.
+        //
+        // ref: https://www.alibabacloud.com/help/en/oss/developer-reference/putobject?spm=a2c63.p38356.0.0.39ef75e93o0Xtz
+        if args.if_not_exists() {
+            req = req.header(X_OSS_FORBID_OVERWRITE, "true");
+        }
+
         if let Some(user_metadata) = args.user_metadata() {
             for (key, value) in user_metadata {
                 // before insert user defined metadata header, add prefix to the header name