summaryrefslogtreecommitdiff
path: root/packages/taler-util/src/http-impl.qtart.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-util/src/http-impl.qtart.ts')
-rw-r--r--packages/taler-util/src/http-impl.qtart.ts127
1 files changed, 127 insertions, 0 deletions
diff --git a/packages/taler-util/src/http-impl.qtart.ts b/packages/taler-util/src/http-impl.qtart.ts
new file mode 100644
index 000000000..954b41802
--- /dev/null
+++ b/packages/taler-util/src/http-impl.qtart.ts
@@ -0,0 +1,127 @@
+/*
+ This file is part of GNU Taler
+ (C) 2019 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+*/
+
+/**
+ * Imports.
+ */
+import { Logger } from "@gnu-taler/taler-util";
+import { TalerError } from "./errors.js";
+import { encodeBody, HttpLibArgs } from "./http-common.js";
+import {
+ Headers,
+ HttpRequestLibrary,
+ HttpRequestOptions,
+ HttpResponse,
+} from "./http.js";
+import { RequestThrottler, TalerErrorCode, URL } from "./index.js";
+import { qjsOs } from "./qtart.js";
+
+const logger = new Logger("http-impl.qtart.ts");
+
+const textDecoder = new TextDecoder();
+
+/**
+ * Implementation of the HTTP request library interface for node.
+ */
+export class HttpLibImpl implements HttpRequestLibrary {
+ private throttle = new RequestThrottler();
+ private throttlingEnabled = true;
+
+ constructor(args?: HttpLibArgs) {
+ this.throttlingEnabled = args?.enableThrottling ?? false;
+ }
+
+ /**
+ * Set whether requests should be throttled.
+ */
+ setThrottling(enabled: boolean): void {
+ this.throttlingEnabled = enabled;
+ }
+
+ async fetch(url: string, opt?: HttpRequestOptions): Promise<HttpResponse> {
+ const method = opt?.method ?? "GET";
+
+ logger.trace(`Requesting ${method} ${url}`);
+
+ const parsedUrl = new URL(url);
+ if (this.throttlingEnabled && this.throttle.applyThrottle(url)) {
+ throw TalerError.fromDetail(
+ TalerErrorCode.WALLET_HTTP_REQUEST_THROTTLED,
+ {
+ requestMethod: method,
+ requestUrl: url,
+ throttleStats: this.throttle.getThrottleStats(url),
+ },
+ `request to origin ${parsedUrl.origin} was throttled`,
+ );
+ }
+
+ let data: ArrayBuffer | undefined = undefined;
+ let headers: string[] = [];
+ if (opt?.headers) {
+ for (let headerName of Object.keys(opt.headers)) {
+ headers.push(`${headerName}: ${opt.headers[headerName]}`);
+ }
+ }
+ if (method.toUpperCase() === "POST") {
+ data = encodeBody(opt?.body);
+ }
+ const res = await qjsOs.fetchHttp(url, {
+ method,
+ data,
+ headers,
+ });
+ return {
+ requestMethod: method,
+ // FIXME: We don't return headers!
+ headers: new Headers(),
+ async bytes() {
+ return res.data;
+ },
+ json() {
+ const text = textDecoder.decode(res.data);
+ return JSON.parse(text);
+ },
+ async text() {
+ const text = textDecoder.decode(res.data);
+ return text;
+ },
+ requestUrl: url,
+ status: res.status,
+ };
+ }
+
+ async get(url: string, opt?: HttpRequestOptions): Promise<HttpResponse> {
+ return this.fetch(url, {
+ method: "GET",
+ ...opt,
+ });
+ }
+
+ async postJson(
+ url: string,
+ body: any,
+ opt?: HttpRequestOptions,
+ ): Promise<HttpResponse> {
+ return this.fetch(url, {
+ method: "POST",
+ body,
+ ...opt,
+ });
+ }
+}