if a requests response is 409 retry upto 10 times

This commit is contained in:
Niraj Acharya
2023-07-18 09:26:36 +05:45
parent ca929abd3a
commit abb111c3a1
3 changed files with 44 additions and 14 deletions
+18 -6
View File
@@ -41,7 +41,7 @@ use GuzzleHttp\Pool;
*/ */
class HttpRequestHelper { class HttpRequestHelper {
public const HTTP_TOO_EARLY = 425; public const HTTP_TOO_EARLY = 425;
public const HTTP_CONFLICT = 409;
private static ?string $oCSelectorCookie = null; private static ?string $oCSelectorCookie = null;
/** /**
@@ -159,7 +159,6 @@ class HttpRequestHelper {
} }
/** /**
*
* @param string|null $url * @param string|null $url
* @param string|null $xRequestId * @param string|null $xRequestId
* @param string|null $method * @param string|null $method
@@ -173,8 +172,10 @@ class HttpRequestHelper {
* than download it all up-front. * than download it all up-front.
* @param int|null $timeout * @param int|null $timeout
* @param Client|null $client * @param Client|null $client
* @param bool|null $isGivenStep
* *
* @return ResponseInterface * @return ResponseInterface
*
* @throws GuzzleException * @throws GuzzleException
*/ */
public static function sendRequest( public static function sendRequest(
@@ -189,7 +190,8 @@ class HttpRequestHelper {
?CookieJar $cookies = null, ?CookieJar $cookies = null,
bool $stream = false, bool $stream = false,
?int $timeout = 0, ?int $timeout = 0,
?Client $client = null ?Client $client = null,
?bool $isGivenStep = false
):ResponseInterface { ):ResponseInterface {
if ((\getenv('DEBUG_ACCEPTANCE_RESPONSES') !== false) || (\getenv('DEBUG_ACCEPTANCE_API_CALLS') !== false)) { if ((\getenv('DEBUG_ACCEPTANCE_RESPONSES') !== false) || (\getenv('DEBUG_ACCEPTANCE_API_CALLS') !== false)) {
$debugResponses = true; $debugResponses = true;
@@ -216,7 +218,7 @@ class HttpRequestHelper {
$client $client
); );
if ($response->getStatusCode() >= 400 && $response->getStatusCode() !== self::HTTP_TOO_EARLY) { if ($response->getStatusCode() >= 400 && $response->getStatusCode() !== self::HTTP_TOO_EARLY && $response->getStatusCode() !== self::HTTP_CONFLICT) {
$sendExceptionHappened = true; $sendExceptionHappened = true;
} }
@@ -224,11 +226,21 @@ class HttpRequestHelper {
self::debugResponse($response); self::debugResponse($response);
} }
$sendCount = $sendCount + 1; $sendCount = $sendCount + 1;
$loopAgain = !$sendExceptionHappened && ($response->getStatusCode() === self::HTTP_TOO_EARLY) && ($sendCount <= $sendRetryLimit); // Here we check if the response has status code 425 or is a 409 gotten from a Given step
// HTTP_TOO_EARLY (425) can happen if async processing of a previous request is still happening.
// For example, if a test uploads a file and then immediately tries to download it.
// HTTP_CONFLICT (409) can happen if the user has just been created in the previous step.
// The OCS API might not "realize" yet that the user exists. A folder creation (MKCOL) or maybe even
// a file upload might return 409.
// In all these cases we can try the API request again after a short time.
$loopAgain = !$sendExceptionHappened && ($response->getStatusCode() === self::HTTP_TOO_EARLY ||
($response->getStatusCode() === self::HTTP_CONFLICT && $isGivenStep)) &&
$sendCount <= $sendRetryLimit;
if ($loopAgain) { if ($loopAgain) {
// we need to repeat the send request, because we got HTTP_TOO_EARLY // we need to repeat the send request, because we got HTTP_TOO_EARLY or HTTP_CONFLICT
// wait 1 second before sending again, to give the server some time // wait 1 second before sending again, to give the server some time
// to finish whatever post-processing it might be doing. // to finish whatever post-processing it might be doing.
self::debugResponse($response);
\sleep(1); \sleep(1);
} }
} while ($loopAgain); } while ($loopAgain);
+5 -2
View File
@@ -601,6 +601,7 @@ class WebDavHelper {
* @param Client|null $client * @param Client|null $client
* @param array|null $urlParameter to concatenate with path * @param array|null $urlParameter to concatenate with path
* @param string|null $doDavRequestAsUser run the DAV as this user, if null it is the same as $user * @param string|null $doDavRequestAsUser run the DAV as this user, if null it is the same as $user
* @param bool $isGivenStep is set to true if makeDavRequest is called from a "given" step
* *
* @return ResponseInterface * @return ResponseInterface
* @throws GuzzleException * @throws GuzzleException
@@ -623,7 +624,8 @@ class WebDavHelper {
?int $timeout = 0, ?int $timeout = 0,
?Client $client = null, ?Client $client = null,
?array $urlParameter = [], ?array $urlParameter = [],
?string $doDavRequestAsUser = null ?string $doDavRequestAsUser = null,
?bool $isGivenStep = false
):ResponseInterface { ):ResponseInterface {
$baseUrl = self::sanitizeUrl($baseUrl, true); $baseUrl = self::sanitizeUrl($baseUrl, true);
@@ -702,7 +704,8 @@ class WebDavHelper {
null, null,
$stream, $stream,
$timeout, $timeout,
$client $client,
$isGivenStep
); );
} }
+21 -6
View File
@@ -389,9 +389,12 @@ trait WebDav {
* @param string|null $password * @param string|null $password
* @param array|null $urlParameter * @param array|null $urlParameter
* @param string|null $doDavRequestAsUser * @param string|null $doDavRequestAsUser
* @param bool|null $isGivenStep
* *
* @return ResponseInterface * @return ResponseInterface
* @throws GuzzleException|JsonException *
* @throws GuzzleException
* @throws JsonException
*/ */
public function makeDavRequest( public function makeDavRequest(
?string $user, ?string $user,
@@ -404,7 +407,8 @@ trait WebDav {
bool $stream = false, bool $stream = false,
?string $password = null, ?string $password = null,
?array $urlParameter = [], ?array $urlParameter = [],
?string $doDavRequestAsUser = null ?string $doDavRequestAsUser = null,
?bool $isGivenStep = false
):ResponseInterface { ):ResponseInterface {
$user = $this->getActualUsername($user); $user = $this->getActualUsername($user);
if ($this->customDavPath !== null) { if ($this->customDavPath !== null) {
@@ -438,7 +442,8 @@ trait WebDav {
$this->httpRequestTimeout, $this->httpRequestTimeout,
null, null,
$urlParameter, $urlParameter,
$doDavRequestAsUser $doDavRequestAsUser,
$isGivenStep
); );
} }
@@ -3520,18 +3525,28 @@ trait WebDav {
* *
* @param string $user * @param string $user
* @param string $destination * @param string $destination
* @param bool|null $isGivenStep
* *
* @return void * @return void
* @throws JsonException | GuzzleException * @throws JsonException | GuzzleException
* @throws GuzzleException | JsonException
*/ */
public function userCreatesFolder(string $user, string $destination):void { public function userCreatesFolder(string $user, string $destination, ?bool $isGivenStep = false):void {
$user = $this->getActualUsername($user); $user = $this->getActualUsername($user);
$destination = '/' . \ltrim($destination, '/'); $destination = '/' . \ltrim($destination, '/');
$this->response = $this->makeDavRequest( $this->response = $this->makeDavRequest(
$user, $user,
"MKCOL", "MKCOL",
$destination, $destination,
[] [],
null,
"files",
null,
false,
null,
[],
null,
$isGivenStep
); );
$this->setResponseXml( $this->setResponseXml(
HttpRequestHelper::parseResponseAsXml($this->response) HttpRequestHelper::parseResponseAsXml($this->response)
@@ -3551,7 +3566,7 @@ trait WebDav {
*/ */
public function userHasCreatedFolder(string $user, string $destination):void { public function userHasCreatedFolder(string $user, string $destination):void {
$user = $this->getActualUsername($user); $user = $this->getActualUsername($user);
$this->userCreatesFolder($user, $destination); $this->userCreatesFolder($user, $destination, true);
$this->theHTTPStatusCodeShouldBe( $this->theHTTPStatusCodeShouldBe(
["201", "204"], ["201", "204"],
"HTTP status code was not 201 or 204 while trying to create folder '$destination' for user '$user'" "HTTP status code was not 201 or 204 while trying to create folder '$destination' for user '$user'"