Commit Graph

30812 Commits

Author SHA1 Message Date
Jérémy Derussé
1ec0630262
Prevent user serializing the key 2020-10-03 14:03:42 +02:00
Fabien Potencier
534466d1cf feature #38177 [Security] Magic login link authentication (weaverryan)
This PR was squashed before being merged into the 5.2-dev branch.

Discussion
----------

[Security] Magic login link authentication

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| Deprecations? | no
| Tickets       | none
| License       | MIT
| Doc PR        | TODO

Hi!

This adds a Slack-style "magic link" login authenticator to the new login system: (A) enter your email into a form, (B) receive an email with a link in it (C) click that link and you are authenticated!

For most users, implementing this would require:

A) Create a [controller](https://github.com/weaverryan/symfony-magic-login-link-example/blob/master/src/Controller/MagicLinkLoginController.php) with the "enter your email" form and a route for the "check" functionality (similar to `form_login`)
B) Activate in `security.yaml`:

```yml
security:
    enable_authenticator_manager: true
    # ...
    firewalls:
        # ...
        main:
            # ...
            login_link:
                check_route: 'magic_link_verify'
                # this is an important and powerful option
                # An array of properties on your User that are used to sign the link.
                # If any of these change, all existing links will become invalid
                # tl;dr If you want the modification of ANY field to invalidate ALL existing magic links immediately,
                # then you can add it to this list. You could even add a "lastLoginLinkSentAt" to invalid
                # all existing login links when a new one is sent.
                signature_properties: [id, password, email]

                # optional - by default, links can be reused but have a 10 minute lifetime
                #max_uses: 3
                #used_link_cache: cache.app
```

Done! This will generate a URL that looks something like this:

> https://127.0.0.1:9033/login/verify?user=weaverryan@gmail.com&expires=1601342578&hash=YzE1ZDJlYjM3YTMyMjgwZDdkYzg2ZjFlMjZhN2E5ZWRmMzk3NjAxNjRjYThiMjMzNmIxYzAzYzQ4NmQ2Zjk4NA%3D%3D

We would implement a Maker command this config + login/controller. The implementation is done via a "signed URL" and an optional cache pool to "expire" links. The hash of the signed URL can contain any user fields you want, which give you a powerful mechanism to invalidate magic tokens on user data changes. See `signature_properties` above.

#### Security notes:

There is a LOT of variability about how secure these need to be:

* A) Many/most implementation only allow links to be used ONE time. That is *possible* with this implementation, but is not the *default*. You CAN add a `max_uses` config which stores the expired links in a cache so they cannot be re-used. However, to make this work, you need to do more work by adding some "page" between the link the users clicks and *actually* using the login link. Why? Because unless you do this, email clients may follow the link to "preview" it and will "consume" the link.

* B) Many implementations will invalidate all other login links for a user when a new one is created. We do *not* do that, but that IS possible (and we could even generate the code for it) by adding a `lastLoginLinkSentAt` field to `User` and including this in `signature_properties`.

* C) We *do* invalidate all links if the user's email address is changed (assuming the `email` is included in `signature_properties`, which it should be). You can also invalidate on password change or whatever you want.

* D) Some implementations add a "state" so that you can only use the link on the same device that created it. That is, in many cases, quite annoying. We do not currently support that, but we could in the future (and the user could add it themselves).

Thanks!

#### TODOS:

* [x] A) more tests: functional (?) traits
* [ ] B) documentation
* [ ] C) MakerBundle PR
* [ ] D) Make sure we have what we need to allow that "in between" page
* [ ] E) Create a new cache pool instead of relying on cache.app?

Commits
-------

a8afe109d8 [Security] Magic login link authentication
2020-10-03 08:23:42 +02:00
Ryan Weaver
a8afe109d8 [Security] Magic login link authentication 2020-10-03 08:23:35 +02:00
Fabien Potencier
f589ff41ca feature #38224 [HttpFoundation] Add Request::toArray() for JSON content (Nyholm)
This PR was squashed before being merged into the 5.2-dev branch.

Discussion
----------

[HttpFoundation] Add Request::toArray() for JSON content

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | ni
| New feature?  | yes
| Deprecations? | no
| Tickets       |
| License       | MIT
| Doc PR        |

The past few months I've been working more and more with javascript and APIs. I've written controllers that parse json from the request body. I've found myself copying code between projects so I looked at the possibility to add this code to the `Request` class itself.

### Usage

```http
POST /add-user
Content-Type: application/json

{"name": "Tobias", "email": "tobias.nyholm@gmail.com"}
```

```php
use Symfony\Component\HttpFoundation\Exception\JsonException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;

class MyController
    // ...
    public function addUser(Request $request): JsonResponse
    {
        try {
            $data = $request->toArray();
        } catch (JsonException $e) {
            return new JsonResponse(['message'=>'Request does not contain valid json'], 415);
        }

        $command = new AddUser($data['email'] ?? '', $data['name'] ?? '');

        try {
            $this->commandBus->dispatch($command);
        } catch (ValidationFailedException $e) {
            return new JsonResponse(['message' => 'Unexpected JSON body'], 400);
        }

        return new JsonResponse(['message' => 'User successfully added']);
    }
}
```
----------

I've searched but I have not found that this has been proposed before.. With is strange.. ¯\\_(ツ)_/¯

Commits
-------

83c1a2666d [HttpFoundation] Add Request::toArray() for JSON content
2020-10-03 08:14:02 +02:00
Nyholm
83c1a2666d [HttpFoundation] Add Request::toArray() for JSON content 2020-10-03 08:13:56 +02:00
Fabien Potencier
f8b154357d Fix CS 2020-10-03 08:07:27 +02:00
Fabien Potencier
d69b525000 bug #38385 [PropertyInfo] Fix failure over array<string,mixed> PhpDoc type (romaricdrigon)
This PR was merged into the 5.2-dev branch.

Discussion
----------

[PropertyInfo] Fix failure over array<string,mixed> PhpDoc type

| Q             | A
| ------------- | ---
| Branch?       | master (issue introduced in master)
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | /
| License       | MIT
| Doc PR        | /

**Background**

Since a few days ago ([this commit](80e5a7fbd8)), PropertyInfo 5.2 component supports array PhpDoc types, such as `array<string,string>`.
While testing SF 5.2 over my project, it was failing over:
```php
class SomeDoctrineEntityProxy implements \Doctrine\ORM\Proxy\Proxy
{
    /**
     * @var array<string, mixed> default values of properties to be lazy loaded, with keys being the property names
     *
     * @see \Doctrine\Common\Proxy\Proxy::__getLazyProperties
     */
    public static $lazyPropertiesDefaults = array();
}
```

Upon investigation, it appears `array<string,mixed>` is causing the issue: `mixed` type is not handled.

**Expected behavior**

PropertyInfo component should not guess anything for `mixed` type (return `NULL`), but it should not throw any exception.

**Comment about my fix**

I added a test case (`arrayOfMixed`) you can use to reproduce the issue.
Since array PhpDoc types were not tested at all, I also added a test case over `array<string,string>`.

Commits
-------

590177ff8e [PropertyInfo] Fix failure over array<string,mixed> PhpDoc type
2020-10-03 08:03:47 +02:00
Yonel Ceruto
3d83f94a89 Fixed undefined property in Firewall\ExceptionListener 2020-10-02 17:21:50 -04:00
Romaric Drigon
590177ff8e [PropertyInfo] Fix failure over array<string,mixed> PhpDoc type 2020-10-02 16:56:39 +02:00
Nicolas Grekas
5e48c1e1c6 Merge branch '5.1'
* 5.1:
  [HttpClient] Always "buffer" empty responses
2020-10-02 16:25:10 +02:00
Nicolas Grekas
c453c3dbd5 Merge branch '4.4' into 5.1
* 4.4:
  [HttpClient] Always "buffer" empty responses
2020-10-02 16:24:03 +02:00
Nicolas Grekas
700462f118 [HttpClient] fix last fix 2020-10-02 16:15:25 +02:00
Nicolas Grekas
993525a366 [HttpClient] Fix dealing with empty responses in AsyncResponse 2020-10-02 16:11:19 +02:00
Nicolas Grekas
1f7b8fdf7b bug #38378 [HttpClient] Fix exception triggered with AsyncResponse (jderusse)
This PR was merged into the 5.2-dev branch.

Discussion
----------

[HttpClient] Fix exception triggered with AsyncResponse

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | https://github.com/symfony/symfony/pull/38289#issuecomment-702573975
| License       | MIT
| Doc PR        | /

When a request is replayed with the AsyncResponse and the 2nd request failed, users get an exception even when they pass `$throw=false`.

In fact, there are 2 exceptions:

1. Cannot get the content of the response twice: buffering is disabled.

73ca97c97a/src/Symfony/Component/HttpClient/Response/CommonResponseTrait.php (L51-L68)

Because CommonResponseTrait::$content is null and `self::stream` yield only the LastChunk. The content is stays null

2. HTTP/2 429  returned for "https://httpbin.org/status/429"

73ca97c97a/src/Symfony/Component/HttpClient/Response/AsyncResponse.php (L209-L225)

Because on the second request passthru is null, it didn't disable the the exception thrown on destruct for the wrapped response.
This

Commits
-------

3aedb51dd8 [HttpClient] Fix exception triggered with AsyncResponse
2020-10-02 15:57:56 +02:00
Jérémy Derussé
3aedb51dd8 [HttpClient] Fix exception triggered with AsyncResponse 2020-10-02 15:57:08 +02:00
Nicolas Grekas
03d60fce47 [HttpClient] Always "buffer" empty responses 2020-10-02 15:41:48 +02:00
Fabien Potencier
a3e8c112c2 feature #38323 [Mime] Allow multiple parts with the same name in FormDataPart (HypeMC)
This PR was merged into the 5.2-dev branch.

Discussion
----------

[Mime] Allow multiple parts with the same name in FormDataPart

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| Deprecations? | no
| Tickets       | Fix #38258
| License       | MIT
| Doc PR        | -

Added the possibility to choose whether multiple parts with the same name should be suffixed or not:

```php
$f1 = new FormDataPart([
    'foo' => [
        'one',
        'two',
    ],
]);

var_dump($f1->toString());
```

```
Content-Type: multipart/form-data; boundary=6rqazwiG

--6rqazwiG
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Content-Disposition: form-data; name="foo[0]"

one
--6rqazwiG
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Content-Disposition: form-data; name="foo[1]"

two
--6rqazwiG--
```

```php
$f1 = new FormDataPart([
    ['foo' => 'one'],
    ['foo' => 'two'],
]);

var_dump($f1->toString());
```

```
Content-Type: multipart/form-data; boundary=xxW9dGzq

--xxW9dGzq
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Content-Disposition: form-data; name="foo"

one
--xxW9dGzq
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Content-Disposition: form-data; name="foo"

two
--xxW9dGzq--
```

Only applies to numeric keys:

```php
$f1 = new FormDataPart([
    'foo' => [
        'a' => 'one',
        'b' => 'two',
    ],
], true);

var_dump($f1->toString());
```

```
Content-Type: multipart/form-data; boundary=W6qkqgrD

--W6qkqgrD
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Content-Disposition: form-data; name="foo[a]"

one
--W6qkqgrD
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Content-Disposition: form-data; name="foo[b]"

two
--W6qkqgrD--
```

Commits
-------

1f7f2c6ddc Allow multiple parts with the same name in FormDataPart
2020-10-02 15:33:43 +02:00
Nicolas Grekas
9d6333a7ff Merge branch '5.1'
* 5.1:
  [5.1] Ignore more deprecations for Mockery mocks
  [PhpUnitBridge] Fix Deprecation file when it comes from the TestsListener
  disallow FrameworkBundle 4.4+
  propagate validation groups to subforms
  [Form] [Validator] Add failing testcase to demonstrate group sequence issue
2020-10-02 15:09:26 +02:00
Thomas Calvet
58e6cb1ddc [5.1] Ignore more deprecations for Mockery mocks 2020-10-02 15:05:43 +02:00
Nicolas Grekas
8ea3e7a6bb Merge branch '4.4' into 5.1
* 4.4:
  disallow FrameworkBundle 4.4+
  propagate validation groups to subforms
  [Form] [Validator] Add failing testcase to demonstrate group sequence issue
2020-10-02 14:58:01 +02:00
Nicolas Grekas
3d39874a2c Merge branch '3.4' into 4.4
* 3.4:
  disallow FrameworkBundle 4.4+
  propagate validation groups to subforms
  [Form] [Validator] Add failing testcase to demonstrate group sequence issue
2020-10-02 14:43:11 +02:00
Fabien Potencier
bd8c3c1c42 feature #38354 [RateLimiter] add Limit::ensureAccepted() which throws RateLimitExceededException if not accepted (kbond)
This PR was merged into the 5.2-dev branch.

Discussion
----------

[RateLimiter] add Limit::ensureAccepted() which throws RateLimitExceededException if not accepted

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| Deprecations? | no
| Tickets       | Ref https://github.com/symfony/symfony/issues/38241#issuecomment-695212027
| License       | MIT
| Doc PR        | todo

Example:

```php
try {
    $limit = $limiter->consume()->ensureAccepted();
} catch (RateLimitExceededException $e) {
    $limit = $e->getLimit();
}
```

Commits
-------

a7ecd0ed08 [RateLimiter] add Limit::ensureAccepted() and RateLimitExceededException
2020-10-02 13:18:49 +02:00
Nicolas Grekas
48adfb2e4b Merge branch '5.1'
* 5.1:
  [HttpClient] fix unsetting context[ssl][peer_name]
2020-10-02 12:20:36 +02:00
Nicolas Grekas
56679fe735 Merge branch '4.4' into 5.1
* 4.4:
  [HttpClient] fix unsetting context[ssl][peer_name]
2020-10-02 12:20:30 +02:00
Nicolas Grekas
8eb8a7c400 [HttpClient] fix unsetting context[ssl][peer_name] 2020-10-02 12:07:58 +02:00
Christian Flothmann
04f5698e29 propagate validation groups to subforms 2020-10-02 11:43:30 +02:00
Johan de Ruijter
e2c7c3373d [Form] [Validator] Add failing testcase to demonstrate group sequence issue
When using group sequences on a form, sometimes constraints are ignored even though they should fail.
2020-10-02 11:43:30 +02:00
HypeMC
1f7f2c6ddc Allow multiple parts with the same name in FormDataPart 2020-10-02 11:11:56 +02:00
Nicolas Grekas
73ca97c97a Merge branch '5.1'
* 5.1:
  [HttpClient] fix using proxies with NativeHttpClient
  [4.4] Ignore more deprecations for Mockery mocks
  [Routing] fix using !important and defaults/reqs in inline route definitions
  [ErrorHandler][DebugClassLoader] Do not check Mockery mocks classes
  [HttpClient] Fix using https with proxies
  [TwigBundle] Only remove kernel exception listener if twig is used
  [DI] Fix changelog
  Remove CHANGELOG files for 4.x
  Adjust expired range check
  Fix redis connection error message
  [DI] fix dumping non-shared lazy services
2020-10-02 10:56:13 +02:00
Nicolas Grekas
d8255138ae Merge branch '4.4' into 5.1
* 4.4:
  [HttpClient] fix using proxies with NativeHttpClient
  [4.4] Ignore more deprecations for Mockery mocks
  [Routing] fix using !important and defaults/reqs in inline route definitions
  [ErrorHandler][DebugClassLoader] Do not check Mockery mocks classes
  [HttpClient] Fix using https with proxies
  [TwigBundle] Only remove kernel exception listener if twig is used
  Adjust expired range check
  Fix redis connection error message
2020-10-02 10:49:02 +02:00
Nicolas Grekas
0d8721fc01 Merge branch '3.4' into 4.4
* 3.4:
  Adjust expired range check
2020-10-02 10:38:15 +02:00
Nicolas Grekas
3cfd991ae6 bug #38377 [4.4] Ignore more deprecations for Mockery mocks (fancyweb)
This PR was merged into the 4.4 branch.

Discussion
----------

[4.4] Ignore more deprecations for Mockery mocks

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | -
| License       | MIT
| Doc PR        | -

Commits
-------

1a801e8452 [4.4] Ignore more deprecations for Mockery mocks
2020-10-02 10:36:26 +02:00
Nicolas Grekas
aca260fbd0 bug #38375 [HttpClient] fix using proxies with NativeHttpClient (nicolas-grekas)
This PR was merged into the 4.4 branch.

Discussion
----------

[HttpClient] fix using proxies with NativeHttpClient

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | -
| License       | MIT
| Doc PR        | -

As spotted by @stof in https://github.com/symfony/symfony/pull/38368#issuecomment-702272737, we cannot use local DNS resolution with HTTP proxies.

Commits
-------

28f301bf03 [HttpClient] fix using proxies with NativeHttpClient
2020-10-02 10:29:59 +02:00
Nicolas Grekas
9c8a3009cf bug #38372 [Routing] fix using !important and defaults/reqs in inline route definitions (nicolas-grekas)
This PR was merged into the 4.4 branch.

Discussion
----------

[Routing] fix using !important and defaults/reqs in inline route definitions

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix #33224
| License       | MIT
| Doc PR        | -

Commits
-------

826db225b7 [Routing] fix using !important and defaults/reqs in inline route definitions
2020-10-02 10:22:10 +02:00
Nicolas Grekas
28f301bf03 [HttpClient] fix using proxies with NativeHttpClient 2020-10-02 10:17:19 +02:00
Thomas Calvet
1a801e8452 [4.4] Ignore more deprecations for Mockery mocks 2020-10-02 09:34:48 +02:00
Fabien Potencier
d0ded920e6 bug #38367 [RateLimiter] Fix cache storage (use namespaced pool + remove \Serializable) (wouterj)
This PR was squashed before being merged into the 5.2-dev branch.

Discussion
----------

[RateLimiter] Fix cache storage (use namespaced pool + remove \Serializable)

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix #38365, fix #38338
| License       | MIT
| Doc PR        | -

Commits
-------

251c202874 Use a dedicated cache.rate_limiter cache pool
5dc562a318 Use __sleep/__wakeup instead of Serializable
2020-10-02 08:02:03 +02:00
Fabien Potencier
67a7be2bd0 Fix CS 2020-10-02 07:59:23 +02:00
Fabien Potencier
954009a4d7 feature #32904 [Messenger] Added ErrorDetailsStamp (TimoBakx)
This PR was merged into the 5.2-dev branch.

Discussion
----------

[Messenger] Added ErrorDetailsStamp

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | yes
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #32311
| License       | MIT
| Doc PR        | No doc changes are needed

#SymfonyHackday

This PR is part of the work started in #32341. That PR has a workaround for showing exceptions added to a previous retry. This PR stores error messages in a separate stamp, so they're more easily accessed.

I also added the exceptionClass as a separate string (independant of FlattenException), so that information is always available, even if the trace is not (due to FlattenException not being available).

Duplicated exceptions (compared to the last one) are not stored separately.

**Questions:**
- Should we limit the total amount of exceptions (remove the oldest when adding a new one)?
  - Yes, but in a new PR
- The current implementation adds this stamp in the Worker instead of the listeners to prevent duplicate code (due to the immutability of the envelope in the event). Is this the proper way to do this?
  - No, create a new listener and a way to add stamps to the envelope inside the event.
- When adding details of a `HandlerFailedException`, should we add a stamp per wrapped `Throwable`? There can be multiple errors wrapped by a single `HandlerFailedException`.
  - Yes, but in a later PR

**Todo:**
- [x] only add new information if it differs from the previous exception
- [x] add deprecations
- [x] fall back to old stamp data if no new stamp is available
- [x] rebase and retarget to master
- [x] update CHANGELOG.md
- [x] check for docs PR

**BC Breaks:**
When this PR is merged, RedeliveryStamps will no longer be populated with exception data. Any implementations that use `RedeliveryStamp::getExceptionMessage()` or `RedeliveryStamp::getFlattenedException()` will receive an empty string or `null` respectively for stamps added after this update. They should rely on `ErrorDetailsStamp` instead.

**New stuff:**
- New stamp `ErrorDetailsStamp`.
- New event subscriber `AddErrorDetailsStampListener`.
- New method `AbstractWorkerMessageEvent::addStamps`.

Commits
-------

cd27b863f9 [Messenger] Added FailedMessageErrorDetailsStamp
2020-10-02 07:56:41 +02:00
Fabien Potencier
14942dbbe8 feature #36152 [Messenger] dispatch event when a message is retried (nikophil)
This PR was squashed before being merged into the 5.2-dev branch.

Discussion
----------

[Messenger] dispatch event when a message is retried

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| Deprecations? | no
| License       | MIT

Hello,

i'm working on a bundle which helps to monitor messenger queues (add some stats for queues/transports + ability to manage failed messages from the browser)
https://github.com/SymfonyCasts/messenger-monitor-bundle/

and we're missing some hooks in the messaging system:
1. a way to know when a message has been retried (fixed by dispatching a new `WorkerMessageRetriedEvent` in `SendFailedMessageForRetryListener::onMessageFailed()`)
2. a way to update the enveloppe in worker message events (fixed by adding `AbstractWorkerMessageEvent::setEnvelope()`)

if needed i can provide some precise use cases.

thanks.

Commits
-------

55bddcb721 [Messenger] dispatch event when a message is retried
2020-10-02 07:48:00 +02:00
Nicolas PHILIPPE
55bddcb721 [Messenger] dispatch event when a message is retried 2020-10-02 07:47:55 +02:00
Olivier Dolbeau
09c9bde479 Can define ChatMessage transport to null 2020-10-02 07:42:01 +02:00
Fabien Potencier
b35bbdbde5 feature #38289 [HttpClient] provide response body to the RetryDecider (jderusse)
This PR was merged into the 5.2-dev branch.

Discussion
----------

[HttpClient] provide response body to the RetryDecider

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| Deprecations? | yes but for not-yet released 5.2 feature
| Tickets       | /
| License       | MIT
| Doc PR        | TODO

Some servers, like AWS, does not always return standard HTTP code. The strategy needs to parse the body to take a decision.
example:
```
400
x-amzn-requestid: XXXXX
content-type: application/x-amz-json-1.1
content-length: 58
date: Thu, 24 Sep 2020 11:17:35 GMT
connection: close

{"__type":"ThrottlingException","message":"Rate exceeded"}
````

This PR update the `RetryDeciderInterface` interface to let the decider notifying the Client when it need the body to take a decision. in that case, the Client, fetch te client, and call again the decider with the full body.

usage
```php
class Decider implements RetryDeciderInterface {
    public function shouldRetry(string $requestMethod, string $requestUrl, array $requestOptions, int $responseCode, array $responseHeaders, ?string $responseContent, \Throwable $throwable = null): ?bool
    {
        if (null !== $throwable) {
            return true;
        }
        if (in_array($responseCode, [423, 425, 429, 500, 502, 503, 504, 507, 510])) {
            return true;
        }
        if (
            $responseCode !== 400
            || $headers['content-type'][0] ?? null !== 'application/x-amz-json-1.1'
            || (int) $headers['content-length'][0] ?? '0' > 1024
        ) {
            return false;
        }
        if (null === $responseContent) {
            return null; // null mean no decision taken and need to be called again with the body
        }

        $data = json_decode($responseContent, true);

        return $data['__type'] ?? '' === 'ThrottlingException';
    }
}
```

Commits
-------

321be5884d [HttpClient] provide response body to the RetryDecider
2020-10-02 07:36:08 +02:00
Kevin Bond
a7ecd0ed08
[RateLimiter] add Limit::ensureAccepted() and RateLimitExceededException 2020-10-01 20:04:22 -04:00
Nicolas Grekas
826db225b7 [Routing] fix using !important and defaults/reqs in inline route definitions 2020-10-01 18:25:17 +02:00
Thomas Calvet
bbd12fe27f [ErrorHandler][DebugClassLoader] Do not check Mockery mocks classes 2020-10-01 18:21:20 +02:00
Bohan Yang
7e0cd4e621 [HttpClient] Fix using https with proxies 2020-10-01 18:05:21 +02:00
Jérémy Derussé
321be5884d
[HttpClient] provide response body to the RetryDecider 2020-10-01 17:55:44 +02:00
Timo Bakx
cd27b863f9 [Messenger] Added FailedMessageErrorDetailsStamp 2020-10-01 16:25:39 +02:00
Wouter de Jong
5dc562a318 Use __sleep/__wakeup instead of Serializable
Fixes #38338
2020-10-01 14:20:33 +02:00