@azure/msal-node
Version:
Microsoft Authentication Library for Node
72 lines (60 loc) • 2.11 kB
text/typescript
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
import http from "http";
import { IHttpRetryPolicy } from "./IHttpRetryPolicy.js";
export class LinearRetryPolicy implements IHttpRetryPolicy {
maxRetries: number;
retryDelay: number;
httpStatusCodesToRetryOn: Array<number>;
constructor(
maxRetries: number,
retryDelay: number,
httpStatusCodesToRetryOn: Array<number>
) {
this.maxRetries = maxRetries;
this.retryDelay = retryDelay;
this.httpStatusCodesToRetryOn = httpStatusCodesToRetryOn;
}
private retryAfterMillisecondsToSleep(
retryHeader: http.IncomingHttpHeaders["retry-after"]
): number {
if (!retryHeader) {
return 0;
}
// retry-after header is in seconds
let millisToSleep = Math.round(parseFloat(retryHeader) * 1000);
/*
* retry-after header is in HTTP Date format
* <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT
*/
if (isNaN(millisToSleep)) {
millisToSleep = Math.max(
0,
// .valueOf() is needed to subtract dates in TypeScript
new Date(retryHeader).valueOf() - new Date().valueOf()
);
}
return millisToSleep;
}
async pauseForRetry(
httpStatusCode: number,
currentRetry: number,
retryAfterHeader: http.IncomingHttpHeaders["retry-after"]
): Promise<boolean> {
if (
this.httpStatusCodesToRetryOn.includes(httpStatusCode) &&
currentRetry < this.maxRetries
) {
const retryAfterDelay: number =
this.retryAfterMillisecondsToSleep(retryAfterHeader);
await new Promise((resolve) => {
// retryAfterHeader value of 0 evaluates to false, and this.retryDelay will be used
return setTimeout(resolve, retryAfterDelay || this.retryDelay);
});
return true;
}
return false;
}
}