diff --git a/.wordlist.txt b/.wordlist.txt index b80b5d5c1..52b8bef41 100644 --- a/.wordlist.txt +++ b/.wordlist.txt @@ -74,6 +74,7 @@ AppSystem Archlinux ArrayFacade AssociationField +AsyncAws AsyncPaymentTransactionStruct AsynchronousPaymentHandlerInterface AudienceContext diff --git a/guides/hosting/infrastructure/filesystem.md b/guides/hosting/infrastructure/filesystem.md index 1ef0fdfa9..f702eaa77 100644 --- a/guides/hosting/infrastructure/filesystem.md +++ b/guides/hosting/infrastructure/filesystem.md @@ -88,10 +88,10 @@ In this example, the `&s3_config` creates an anchor that can be referenced with ### Fallback adapter configuration -By default, the configuration for the theme, asset and sitemap filesystem will use the configuration from the `public` filesystem if they are not specifically configured. +By default, the configuration for the theme, asset, and sitemap filesystem will use the configuration from the `public` filesystem if they are not specifically configured. This means when you want to change the configuration used for the public filesystem, but the others should use the old configuration you have to set them explicitly. -E.g. before you had the following configuration: +E.g., before you had the following configuration: ```yaml shopware: @@ -104,7 +104,7 @@ shopware: ``` -Now you want to change the public filesystem to use an S3 adapter, but the theme, asset and sitemap filesystem should still use the local adapter. You have to set them explicitly: +Now you want to change the public filesystem to use an S3 adapter, but the theme, asset, and sitemap filesystem should still use the local adapter. You have to set them explicitly: ```yaml shopware: @@ -221,9 +221,121 @@ shopware: If your S3 provider does not use buckets as subdomain like Minio in default configuration, you need to set `use_path_style_endpoint` to `true` inside `config`. +#### Custom HTTP client for S3 + +:::info +Since Shopware 6.7.9.0, you can register a custom HTTP client for S3 operations. +::: + +By default, the underlying AsyncAws S3 client creates its own HTTP client internally, which includes a `RetryableHttpClient` with an AWS-specific retry strategy. This handles transient errors like throttling (HTTP 429), server errors (HTTP 5xx), and other AWS-specific error codes automatically. + +If you need to customize the HTTP behavior for S3 operations (e.g., timeouts, HTTP protocol version, or proxy settings), you can register a service with the ID `shopware.filesystem.s3.client`. When this service exists, Shopware injects it into both the filesystem adapter and pre-signed URL generation. + +::: info +When you provide a custom HTTP client, AsyncAws will **not** wrap it in its own `RetryableHttpClient`. If you need retry behavior, you must configure it yourself as shown below. +::: + +**Simple configuration** (custom timeouts, no retry handling): + +```yaml +# config/packages/framework.yaml +framework: + http_client: + scoped_clients: + s3.http_client: + base_uri: '{your-s3-endpoint}' + timeout: 30.0 + http_version: '1.1' +``` + +```php +// config/services.php +services(); + + $services->alias('shopware.filesystem.s3.client', 's3.http_client'); +}; +``` + +**Recommended configuration** (custom settings with AWS retry support): + +```yaml +# config/packages/framework.yaml +framework: + http_client: + scoped_clients: + s3.http_client: + base_uri: '{your-s3-endpoint}' + timeout: 30.0 + http_version: '1.1' +``` + +```php +// config/services.php +services(); + + $services->set(AwsRetryStrategy::class); + + $services->set('shopware.filesystem.s3.client', RetryableHttpClient::class) + ->args([ + service('s3.http_client'), + service(AwsRetryStrategy::class), + 3, // max retries + ]); +}; +``` + +This wraps your scoped client in a `RetryableHttpClient` with the same `AwsRetryStrategy` that AsyncAws uses by default, preserving retry behavior for AWS-specific transient errors while allowing you to control timeouts, HTTP version, and other transport-level settings. + +**Without scoped clients** (standalone service definition with retry support): + +```php +// config/services.php +services(); + + $services->set('s3.http_client', HttpClientInterface::class) + ->factory([HttpClient::class, 'create']) + ->args([ + ['timeout' => 30], + ]); + + $services->set('shopware.filesystem.s3.client', RetryableHttpClient::class) + ->args([ + service('s3.http_client'), + null, // default retry strategy + 3, // max retries + ]); +}; +``` + +This creates a plain HTTP client via `HttpClient::create()` with custom options and wraps it in a `RetryableHttpClient` with the default retry strategy. + ### Google Cloud Platform -In order to use the Google Cloud Platform adapter you need to install the `league/flysystem-google-cloud-storage` package. +To use the Google Cloud Platform adapter, you need to install the `league/flysystem-google-cloud-storage` package. ```bash composer require league/flysystem-google-cloud-storage @@ -262,12 +374,12 @@ class MyFlysystemAdapterFactory implements AdapterFactoryInterface { public function getType(): string { - return 'my-adapter-prefix'; // This must match with the type in the yaml file + return 'my-adapter-prefix'; // This must match with the type in the YAML file } public function create(array $config): AdapterInterface { - // $config contains the given config from the yaml + // $config contains the given config from the YAML return new MyFlysystemAdapter($config); } }