1
0
Fork 0

Merge branch '2.2' into main

pull/10769/head
Jordi Boggiano 2022-05-11 13:08:11 +02:00
commit 6af9fb63f5
No known key found for this signature in database
GPG Key ID: 7BBD42C429EC80BC
3 changed files with 12 additions and 4 deletions

View File

@ -79,11 +79,12 @@ class AuthHelper
* @param int $statusCode HTTP status code that triggered this call * @param int $statusCode HTTP status code that triggered this call
* @param string|null $reason a message/description explaining why this was called * @param string|null $reason a message/description explaining why this was called
* @param string[] $headers * @param string[] $headers
* @param int $retryCount the amount of retries already done on this URL
* @return array containing retry (bool) and storeAuth (string|bool) keys, if retry is true the request should be * @return array containing retry (bool) and storeAuth (string|bool) keys, if retry is true the request should be
* retried, if storeAuth is true then on a successful retry the authentication should be persisted to auth.json * retried, if storeAuth is true then on a successful retry the authentication should be persisted to auth.json
* @phpstan-return array{retry: bool, storeAuth: 'prompt'|bool} * @phpstan-return array{retry: bool, storeAuth: 'prompt'|bool}
*/ */
public function promptAuthIfNeeded(string $url, string $origin, int $statusCode, ?string $reason = null, array $headers = array()): array public function promptAuthIfNeeded(string $url, string $origin, int $statusCode, ?string $reason = null, array $headers = array(), int $retryCount = 0): array
{ {
$storeAuth = false; $storeAuth = false;
@ -200,8 +201,15 @@ class AuthHelper
throw new TransportException($message, $statusCode); throw new TransportException($message, $statusCode);
} }
// fail if we already have auth // fail if we already have auth
if ($this->io->hasAuthentication($origin)) { if ($this->io->hasAuthentication($origin)) {
// if two or more requests are started together for the same host, and the first
// received authentication already, we let the others retry before failing them
if ($retryCount === 0) {
return array('retry' => true, 'storeAuth' => false);
}
throw new TransportException("Invalid credentials for '" . $url . "', aborting.", $statusCode); throw new TransportException("Invalid credentials for '" . $url . "', aborting.", $statusCode);
} }

View File

@ -531,7 +531,7 @@ class CurlDownloader
private function isAuthenticatedRetryNeeded(array $job, Response $response): array private function isAuthenticatedRetryNeeded(array $job, Response $response): array
{ {
if (in_array($response->getStatusCode(), array(401, 403)) && $job['attributes']['retryAuthFailure']) { if (in_array($response->getStatusCode(), array(401, 403)) && $job['attributes']['retryAuthFailure']) {
$result = $this->authHelper->promptAuthIfNeeded($job['url'], $job['origin'], $response->getStatusCode(), $response->getStatusMessage(), $response->getHeaders()); $result = $this->authHelper->promptAuthIfNeeded($job['url'], $job['origin'], $response->getStatusCode(), $response->getStatusMessage(), $response->getHeaders(), $job['attributes']['retries']);
if ($result['retry']) { if ($result['retry']) {
return $result; return $result;
@ -563,7 +563,7 @@ class CurlDownloader
if ($needsAuthRetry) { if ($needsAuthRetry) {
if ($job['attributes']['retryAuthFailure']) { if ($job['attributes']['retryAuthFailure']) {
$result = $this->authHelper->promptAuthIfNeeded($job['url'], $job['origin'], 401); $result = $this->authHelper->promptAuthIfNeeded($job['url'], $job['origin'], 401, null, array(), $job['attributes']['retries']);
if ($result['retry']) { if ($result['retry']) {
return $result; return $result;
} }

View File

@ -594,7 +594,7 @@ class RemoteFilesystem
*/ */
protected function promptAuthAndRetry($httpStatus, ?string $reason = null, array $headers = array()) protected function promptAuthAndRetry($httpStatus, ?string $reason = null, array $headers = array())
{ {
$result = $this->authHelper->promptAuthIfNeeded($this->fileUrl, $this->originUrl, $httpStatus, $reason, $headers); $result = $this->authHelper->promptAuthIfNeeded($this->fileUrl, $this->originUrl, $httpStatus, $reason, $headers, 1 /** always pass 1 as RemoteFilesystem is single threaded there is no race condition possible */);
$this->storeAuth = $result['storeAuth']; $this->storeAuth = $result['storeAuth'];
$this->retry = $result['retry']; $this->retry = $result['retry'];