From a793dd2ea81539c8bac8facf241e37e22d41a7a0 Mon Sep 17 00:00:00 2001
From: Kinopio <125463022+jacy1101@users.noreply.github.com>
Date: Tue, 25 Nov 2025 16:24:14 +0800
Subject: [PATCH] Feat: add addressing style config for S3-compatible storage
(#11510)
### Type of change
* [x] New Feature (non-breaking change which adds functionality)
Add support for Virtual Hosted Style and Path Style URL addressing in
S3_COMPATIBLE storage connector. Default to Virtual Hosted Style for
better compatibility with COS and other S3-compatible services.
- Add addressing_style field to credentials (virtual/path)
- Update frontend form with selection dropdown
- Add validation and tooltips for S3 Compatible endpoint URL
---------
Co-authored-by: Kevin Hu
---
common/data_source/blob_connector.py | 2 +-
common/data_source/utils.py | 5 ++++-
web/src/locales/en.ts | 2 ++
web/src/locales/ru.ts | 2 ++
.../pages/user-setting/data-source/contant.tsx | 16 ++++++++++++++++
5 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/common/data_source/blob_connector.py b/common/data_source/blob_connector.py
index 9e74a5394..4cc893649 100644
--- a/common/data_source/blob_connector.py
+++ b/common/data_source/blob_connector.py
@@ -90,7 +90,7 @@ class BlobStorageConnector(LoadConnector, PollConnector):
elif self.bucket_type == BlobType.S3_COMPATIBLE:
if not all(
credentials.get(key)
- for key in ["endpoint_url", "aws_access_key_id", "aws_secret_access_key"]
+ for key in ["endpoint_url", "aws_access_key_id", "aws_secret_access_key", "addressing_style"]
):
raise ConnectorMissingCredentialError("S3 Compatible Storage")
diff --git a/common/data_source/utils.py b/common/data_source/utils.py
index c079b2b9a..cba05b062 100644
--- a/common/data_source/utils.py
+++ b/common/data_source/utils.py
@@ -312,12 +312,15 @@ def create_s3_client(bucket_type: BlobType, credentials: dict[str, Any], europea
region_name=credentials["region"],
)
elif bucket_type == BlobType.S3_COMPATIBLE:
+ addressing_style = credentials.get("addressing_style", "virtual")
+
return boto3.client(
"s3",
endpoint_url=credentials["endpoint_url"],
aws_access_key_id=credentials["aws_access_key_id"],
aws_secret_access_key=credentials["aws_secret_access_key"],
- )
+ config=Config(s3={'addressing_style': addressing_style}),
+ )
else:
raise ValueError(f"Unsupported bucket type: {bucket_type}")
diff --git a/web/src/locales/en.ts b/web/src/locales/en.ts
index 168395d22..fa3db20ee 100644
--- a/web/src/locales/en.ts
+++ b/web/src/locales/en.ts
@@ -715,6 +715,8 @@ This auto-tagging feature enhances retrieval by adding another layer of domain-s
Example: general/v2/`,
S3CompatibleEndpointUrlTip: `Required for S3 compatible Storage Box. Specify the S3-compatible endpoint URL.
Example: https://fsn1.your-objectstorage.com`,
+ S3CompatibleAddressingStyleTip: `Required for S3 compatible Storage Box. Specify the S3-compatible addressing style.
+Example: Virtual Hosted Style`,
addDataSourceModalTital: 'Create your {{name}} connector',
deleteSourceModalTitle: 'Delete data source',
deleteSourceModalContent: `
diff --git a/web/src/locales/ru.ts b/web/src/locales/ru.ts
index b4bbd43d9..c29d2301a 100644
--- a/web/src/locales/ru.ts
+++ b/web/src/locales/ru.ts
@@ -715,6 +715,8 @@ export default {
Пример: general/v2/`,
S3CompatibleEndpointUrlTip: `Требуется для S3 совместимого Storage Box. Укажите URL конечной точки, совместимой с S3.
Пример: https://fsn1.your-objectstorage.com`,
+ S3CompatibleAddressingStyleTip: `Требуется для S3 совместимого Storage Box. Укажите стиль адресации, совместимый с S3.
+Пример: Virtual Hosted Style`,
addDataSourceModalTital: 'Создайте ваш коннектор {{name}}',
deleteSourceModalTitle: 'Удалить источник данных',
deleteSourceModalContent: `
diff --git a/web/src/pages/user-setting/data-source/contant.tsx b/web/src/pages/user-setting/data-source/contant.tsx
index a39614177..6bbb64c6c 100644
--- a/web/src/pages/user-setting/data-source/contant.tsx
+++ b/web/src/pages/user-setting/data-source/contant.tsx
@@ -121,6 +121,21 @@ export const DataSourceFormFields = {
],
required: true,
},
+ {
+ label: 'Addressing Style',
+ name: 'config.credentials.addressing_style',
+ type: FormFieldType.Select,
+ options: [
+ { label: 'Virtual Hosted Style', value: 'virtual' },
+ { label: 'Path Style', value: 'path' },
+ ],
+ required: false,
+ placeholder: 'Virtual Hosted Style',
+ tooltip: t('setting.S3CompatibleAddressingStyleTip'),
+ shouldRender: (formValues: any) => {
+ return formValues?.config?.bucket_type === 's3_compatible';
+ },
+ },
{
label: 'Endpoint URL',
name: 'config.credentials.endpoint_url',
@@ -444,6 +459,7 @@ export const DataSourceFormDefaultValues = {
aws_access_key_id: '',
aws_secret_access_key: '',
endpoint_url: '',
+ addressing_style: 'virtual',
},
},
},