commit badbf4f5fd86383e0a2a441ec0d2661d315ea12c
parent f13a71f3548a35396e13e8259d6636aec5e2f0c5
Author: Sebastian <sebasjm@gmail.com>
Date: Tue, 15 Apr 2025 13:23:09 -0300
fix #9730: support for payload compression
Diffstat:
4 files changed, 41 insertions(+), 3 deletions(-)
diff --git a/packages/taler-util/src/http-client/exchange.ts b/packages/taler-util/src/http-client/exchange.ts
@@ -747,6 +747,7 @@ export class TalerExchangeHttpClient {
const resp = await this.httpLib.fetch(url.href, {
method: "POST",
body,
+ compress: "deflate",
});
switch (resp.status) {
@@ -1014,6 +1015,7 @@ export class TalerExchangeHttpClient {
),
},
body,
+ compress: "deflate"
});
switch (resp.status) {
diff --git a/packages/taler-util/src/http-common.ts b/packages/taler-util/src/http-common.ts
@@ -71,6 +71,11 @@ export interface HttpRequestOptions {
* Same semantics as WHATWG fetch.
*/
redirect?: "follow" | "error" | "manual";
+
+ /**
+ * How to compress the payload
+ */
+ compress?: "gzip" | "deflate";
}
/**
diff --git a/packages/web-util/src/utils/http-impl.browser.ts b/packages/web-util/src/utils/http-impl.browser.ts
@@ -54,7 +54,7 @@ export class BrowserHttpLibDepreacted implements HttpRequestLibrary {
this.requireTls = args?.requireTls ?? false;
}
- fetch(
+ async fetch(
requestUrl: string,
options?: HttpRequestOptions,
): Promise<HttpResponse> {
@@ -87,13 +87,18 @@ export class BrowserHttpLibDepreacted implements HttpRequestLibrary {
);
}
- let myBody: ArrayBuffer | undefined =
+ const encodedBody: ArrayBuffer | undefined =
requestMethod === "POST" ||
requestMethod === "PUT" ||
requestMethod === "PATCH"
? encodeBody(requestBody)
: undefined;
+ const myBody =
+ !options?.compress || !encodedBody
+ ? encodedBody
+ : (await compress(options.compress, encodedBody));
+
const requestHeadersMap = getDefaultHeaders(requestMethod);
if (requestHeader) {
Object.entries(requestHeader).forEach(([key, value]) => {
@@ -102,6 +107,10 @@ export class BrowserHttpLibDepreacted implements HttpRequestLibrary {
});
}
+ if (options?.compress) {
+ requestHeadersMap["Content-Encoding"] = options.compress
+ }
+
return new Promise<HttpResponse>((resolve, reject) => {
const myRequest = new XMLHttpRequest();
@@ -252,3 +261,15 @@ export class BrowserHttpLibDepreacted implements HttpRequestLibrary {
// Nothing to do
}
}
+
+export async function compress(
+ alg: "gzip" | "deflate" | undefined,
+ buf: ArrayBuffer,
+): Promise<ArrayBuffer> {
+ if (!alg) return buf;
+ const cs = new CompressionStream(alg);
+ const writer = cs.writable.getWriter();
+ writer.write(buf);
+ writer.close();
+ return new Response(cs.readable).arrayBuffer();
+}
+\ No newline at end of file
diff --git a/packages/web-util/src/utils/http-impl.sw.ts b/packages/web-util/src/utils/http-impl.sw.ts
@@ -33,6 +33,7 @@ import {
encodeBody,
getDefaultHeaders,
} from "@gnu-taler/taler-util/http";
+import { compress } from "./http-impl.browser.js";
/**
* An implementation of the [[HttpRequestLibrary]] using the
@@ -80,13 +81,18 @@ export class BrowserFetchHttpLib implements HttpRequestLibrary {
);
}
- const myBody: ArrayBuffer | undefined =
+ const encodedBody: ArrayBuffer | undefined =
requestMethod === "POST" ||
requestMethod === "PUT" ||
requestMethod === "PATCH"
? encodeBody(requestBody)
: undefined;
+ const myBody =
+ !options?.compress || !encodedBody
+ ? encodedBody
+ : await compress(options.compress, encodedBody);
+
const requestHeadersMap = getDefaultHeaders(requestMethod);
if (requestHeader) {
Object.entries(requestHeader).forEach(([key, value]) => {
@@ -95,6 +101,9 @@ export class BrowserFetchHttpLib implements HttpRequestLibrary {
});
}
+ if (options?.compress) {
+ requestHeadersMap["Content-Encoding"] = options.compress;
+ }
/**
* default header assume everything is json
* in case of formData the content-type will be