taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

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:
Mpackages/taler-util/src/http-client/exchange.ts | 2++
Mpackages/taler-util/src/http-common.ts | 5+++++
Mpackages/web-util/src/utils/http-impl.browser.ts | 26++++++++++++++++++++++++--
Mpackages/web-util/src/utils/http-impl.sw.ts | 11++++++++++-
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