Skip to content

Commit 83a69b8

Browse files
author
Arjan Lankhaar
committed
feat: added docs for custom HTTP client injection for S3 client creation
1 parent a27f8cc commit 83a69b8

File tree

2 files changed

+113
-4
lines changed

2 files changed

+113
-4
lines changed

.wordlist.txt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ ACLs
55
ADDR
66
ADR
77
ADRs
8+
AES
89
AOF
910
API's
1011
APIRequestContext
@@ -44,7 +45,6 @@ AdminWorker
4445
Adminer
4546
AdministrationNewField
4647
AdministrationNewModule
47-
AES
4848
Afile
4949
AfterLineItemAddedEvent
5050
AfterLineItemQuantityChangedEvent
@@ -74,6 +74,7 @@ AppSystem
7474
Archlinux
7575
ArrayFacade
7676
AssociationField
77+
AsyncAws
7778
AsyncPaymentTransactionStruct
7879
AsynchronousPaymentHandlerInterface
7980
AudienceContext
@@ -435,8 +436,8 @@ FroshDevelopmentHelper
435436
FroshPlatformTemplateMail
436437
FroshTools
437438
Fullstack
438-
GCM
439439
GBP
440+
GCM
440441
GDPR
441442
GIFs
442443
GLB
@@ -647,6 +648,7 @@ Nullsafe
647648
Nuxt
648649
Nvidia
649650
OAuth
651+
OData
650652
OIDC
651653
OPENSEARCH
652654
ORM
@@ -873,6 +875,7 @@ SPAs
873875
SQS
874876
SSHes
875877
SSL
878+
SSO
876879
STP
877880
SVG
878881
SVGs
@@ -952,7 +955,6 @@ StorefrontController
952955
StorefrontPage
953956
StorefrontResponse
954957
Storer
955-
SSO
956958
StringField
957959
StringFields
958960
Struct
@@ -978,7 +980,6 @@ Symfony's
978980
SyncApi
979981
SynchronousPaymentHandlerInterface
980982
Synopsys
981-
OData
982983
TCP
983984
TLS
984985
TTL

guides/hosting/infrastructure/filesystem.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,114 @@ shopware:
221221

222222
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`.
223223

224+
#### Custom HTTP client for S3
225+
226+
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.
227+
228+
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.
229+
230+
::: info
231+
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.
232+
:::
233+
234+
**Simple configuration** (custom timeouts, no retry handling):
235+
236+
```yaml
237+
# config/packages/framework.yaml
238+
framework:
239+
http_client:
240+
scoped_clients:
241+
s3.http_client:
242+
base_uri: '{your-s3-endpoint}'
243+
timeout: 30.0
244+
http_version: '1.1'
245+
```
246+
247+
```php
248+
// config/services.php
249+
<?php declare(strict_types=1);
250+
251+
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
252+
253+
return static function (ContainerConfigurator $configurator): void {
254+
$services = $configurator->services();
255+
256+
$services->alias('shopware.filesystem.s3.client', 's3.http_client');
257+
};
258+
```
259+
260+
**Recommended configuration** (custom settings with AWS retry support):
261+
262+
```yaml
263+
# config/packages/framework.yaml
264+
framework:
265+
http_client:
266+
scoped_clients:
267+
s3.http_client:
268+
base_uri: '{your-s3-endpoint}'
269+
timeout: 30.0
270+
http_version: '1.1'
271+
```
272+
273+
```php
274+
// config/services.php
275+
<?php declare(strict_types=1);
276+
277+
use AsyncAws\Core\HttpClient\AwsRetryStrategy;
278+
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
279+
use Symfony\Component\HttpClient\RetryableHttpClient;
280+
281+
use function Symfony\Component\DependencyInjection\Loader\Configurator\service;
282+
283+
return static function (ContainerConfigurator $configurator): void {
284+
$services = $configurator->services();
285+
286+
$services->set(AwsRetryStrategy::class);
287+
288+
$services->set('shopware.filesystem.s3.client', RetryableHttpClient::class)
289+
->args([
290+
service('s3.http_client'),
291+
service(AwsRetryStrategy::class),
292+
3, // max retries
293+
]);
294+
};
295+
```
296+
297+
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.
298+
299+
**Without scoped clients** (standalone service definition with retry support):
300+
301+
```php
302+
// config/services.php
303+
<?php declare(strict_types=1);
304+
305+
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
306+
use Symfony\Component\HttpClient\HttpClient;
307+
use Symfony\Component\HttpClient\RetryableHttpClient;
308+
use Symfony\Contracts\HttpClient\HttpClientInterface;
309+
310+
use function Symfony\Component\DependencyInjection\Loader\Configurator\service;
311+
312+
return static function (ContainerConfigurator $configurator): void {
313+
$services = $configurator->services();
314+
315+
$services->set('s3.http_client', HttpClientInterface::class)
316+
->factory([HttpClient::class, 'create'])
317+
->args([
318+
['timeout' => 30],
319+
]);
320+
321+
$services->set('shopware.filesystem.s3.client', RetryableHttpClient::class)
322+
->args([
323+
service('s3.http_client'),
324+
null, // default retry strategy
325+
3, // max retries
326+
]);
327+
};
328+
```
329+
330+
This creates a plain HTTP client via `HttpClient::create()` with custom options and wraps it in a `RetryableHttpClient` with the default retry strategy.
331+
224332
### Google Cloud Platform
225333

226334
In order to use the Google Cloud Platform adapter you need to install the `league/flysystem-google-cloud-storage` package.

0 commit comments

Comments
 (0)