summaryrefslogtreecommitdiff
path: root/packages/web-util/src/utils/http-impl.sw.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/web-util/src/utils/http-impl.sw.ts')
-rw-r--r--packages/web-util/src/utils/http-impl.sw.ts85
1 files changed, 46 insertions, 39 deletions
diff --git a/packages/web-util/src/utils/http-impl.sw.ts b/packages/web-util/src/utils/http-impl.sw.ts
index 3120309f4..9c820bb4b 100644
--- a/packages/web-util/src/utils/http-impl.sw.ts
+++ b/packages/web-util/src/utils/http-impl.sw.ts
@@ -18,15 +18,16 @@
* Imports.
*/
import {
+ Duration,
RequestThrottler,
- TalerErrorCode,
TalerError,
- Duration,
+ TalerErrorCode
} from "@gnu-taler/taler-util";
import {
DEFAULT_REQUEST_TIMEOUT_MS,
Headers,
+ HttpLibArgs,
HttpRequestLibrary,
HttpRequestOptions,
HttpResponse,
@@ -38,9 +39,15 @@ import {
* An implementation of the [[HttpRequestLibrary]] using the
* browser's XMLHttpRequest.
*/
-export class ServiceWorkerHttpLib implements HttpRequestLibrary {
+export class BrowserFetchHttpLib implements HttpRequestLibrary {
private throttle = new RequestThrottler();
private throttlingEnabled = true;
+ private requireTls = false;
+
+ public constructor(args?: HttpLibArgs) {
+ this.throttlingEnabled = args?.enableThrottling ?? true;
+ this.requireTls = args?.requireTls ?? false;
+ }
async fetch(
requestUrl: string,
@@ -51,9 +58,11 @@ export class ServiceWorkerHttpLib implements HttpRequestLibrary {
const requestHeader = options?.headers;
const requestTimeout =
options?.timeout ?? Duration.fromMilliseconds(DEFAULT_REQUEST_TIMEOUT_MS);
+ const requestCancel = options?.cancellationToken;
+ const requestRedirect = options?.redirect;
+ const parsedUrl = new URL(requestUrl);
if (this.throttlingEnabled && this.throttle.applyThrottle(requestUrl)) {
- const parsedUrl = new URL(requestUrl);
throw TalerError.fromDetail(
TalerErrorCode.WALLET_HTTP_REQUEST_THROTTLED,
{
@@ -64,22 +73,42 @@ export class ServiceWorkerHttpLib implements HttpRequestLibrary {
`request to origin ${parsedUrl.origin} was throttled`,
);
}
+ if (this.requireTls && parsedUrl.protocol !== "https:") {
+ throw TalerError.fromDetail(
+ TalerErrorCode.WALLET_NETWORK_ERROR,
+ {
+ requestMethod: requestMethod,
+ requestUrl: requestUrl,
+ },
+ `request to ${parsedUrl.origin} is not possible with protocol ${parsedUrl.protocol}`,
+ );
+ }
- let myBody: ArrayBuffer | undefined =
- requestMethod === "POST" ? encodeBody(requestBody) : undefined;
-
- const requestHeadersMap = {
- ...getDefaultHeaders(requestMethod),
- ...requestHeader,
- };
+ const myBody: ArrayBuffer | undefined =
+ requestMethod === "POST" || requestMethod === "PUT" || requestMethod === "PATCH"
+ ? encodeBody(requestBody)
+ : undefined;
+
+ const requestHeadersMap = getDefaultHeaders(requestMethod);
+ if (requestHeader) {
+ Object.entries(requestHeader).forEach(([key, value]) => {
+ if (value === undefined) return;
+ requestHeadersMap[key] = value
+ })
+ }
const controller = new AbortController();
- let timeoutId: any | undefined;
+ let timeoutId: ReturnType<typeof setTimeout> | undefined;
if (requestTimeout.d_ms !== "forever") {
timeoutId = setTimeout(() => {
- controller.abort(TalerErrorCode.WALLET_HTTP_REQUEST_GENERIC_TIMEOUT);
+ controller.abort(TalerErrorCode.GENERIC_TIMEOUT);
}, requestTimeout.d_ms);
}
+ if (requestCancel) {
+ requestCancel.onCancelled(() => {
+ controller.abort(TalerErrorCode.GENERIC_CLIENT_INTERNAL_ERROR)
+ });
+ }
try {
const response = await fetch(requestUrl, {
@@ -87,6 +116,7 @@ export class ServiceWorkerHttpLib implements HttpRequestLibrary {
body: myBody,
method: requestMethod,
signal: controller.signal,
+ redirect: requestRedirect
});
if (timeoutId) {
@@ -109,42 +139,19 @@ export class ServiceWorkerHttpLib implements HttpRequestLibrary {
} catch (e) {
if (controller.signal) {
throw TalerError.fromDetail(
- TalerErrorCode.WALLET_HTTP_REQUEST_GENERIC_TIMEOUT,
+ controller.signal.reason,
{
requestUrl,
requestMethod,
timeoutMs: requestTimeout.d_ms === "forever" ? 0 : requestTimeout.d_ms
},
- `request to ${requestUrl} timed out`,
+ `HTTP request failed.`,
);
}
throw e;
}
}
- get(url: string, opt?: HttpRequestOptions): Promise<HttpResponse> {
- return this.fetch(url, {
- method: "GET",
- ...opt,
- });
- }
-
- postJson(
- url: string,
- body: any,
- opt?: HttpRequestOptions,
- ): Promise<HttpResponse> {
- return this.fetch(url, {
- method: "POST",
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify(body),
- ...opt,
- });
- }
-
- stop(): void {
- // Nothing to do
- }
}
function makeTextHandler(
@@ -190,7 +197,7 @@ function makeJsonHandler(
requestMethod,
httpStatusCode: response.status,
},
- message,
+ message,
);
}
}