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 image image --------- 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', }, }, },