diff options
-rw-r--r-- | packages/taler-util/src/http-impl.node.ts | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/packages/taler-util/src/http-impl.node.ts b/packages/taler-util/src/http-impl.node.ts index 5e613e6cd..ea2309504 100644 --- a/packages/taler-util/src/http-impl.node.ts +++ b/packages/taler-util/src/http-impl.node.ts @@ -184,6 +184,18 @@ export class HttpLibImpl implements HttpRequestLibrary { ); } + let timeoutHandle: NodeJS.Timer | undefined = undefined; + let cancelCancelledHandler: (() => void) | undefined = undefined; + + const doCleanup = () => { + if (timeoutHandle != null) { + clearTimeout(timeoutHandle); + } + if (cancelCancelledHandler) { + cancelCancelledHandler(); + } + }; + return new Promise((resolve, reject) => { const handler = (res: IncomingMessage) => { res.on("data", (d) => { @@ -219,6 +231,7 @@ export class HttpLibImpl implements HttpRequestLibrary { return text; }, }; + doCleanup(); resolve(resp); }); res.on("error", (e) => { @@ -232,6 +245,7 @@ export class HttpLibImpl implements HttpRequestLibrary { }, `Error in HTTP response handler: ${code}`, ); + doCleanup(); reject(err); }); }; @@ -245,6 +259,43 @@ export class HttpLibImpl implements HttpRequestLibrary { throw new Error(`unsupported protocol ${options.protocol}`); } + if (timeoutMs != null) { + timeoutHandle = setTimeout(() => { + logger.info(`request to ${url} timed out`); + const err = TalerError.fromDetail( + TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR, + { + requestUrl: url, + requestMethod: method, + httpStatusCode: 0, + }, + `Request timed out after ${timeoutMs} ms`, + ); + timeoutHandle = undefined; + req.destroy(); + doCleanup(); + reject(err); + req.destroy(); + }, timeoutMs); + } + + if (opt?.cancellationToken) { + cancelCancelledHandler = opt.cancellationToken.onCancelled(() => { + const err = TalerError.fromDetail( + TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR, + { + requestUrl: url, + requestMethod: method, + httpStatusCode: 0, + }, + `Request cancelled`, + ); + req.destroy(); + doCleanup(); + reject(err); + }); + } + req.on("error", (e: Error) => { const code = "code" in e ? e.code : "unknown"; const err = TalerError.fromDetail( @@ -256,6 +307,7 @@ export class HttpLibImpl implements HttpRequestLibrary { }, `Error in HTTP request: ${code}`, ); + doCleanup(); reject(err); }); |