diff options
author | Florian Dold <florian.dold@gmail.com> | 2020-09-02 12:23:11 +0530 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2020-09-02 12:23:11 +0530 |
commit | 659e9cdbe6defd54d0f4713bb230e4a156262a2c (patch) | |
tree | 1a29245514f9dd5e84617c6ac699ef7a2bf264a5 | |
parent | 0ffea74ad52113aa9036453ff3ea8d4dff61b3d8 (diff) |
respect cache header
-rw-r--r-- | packages/taler-wallet-core/src/operations/exchanges.ts | 19 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/types/dbTypes.ts | 5 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/util/http.ts | 18 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/util/time.ts | 4 |
4 files changed, 42 insertions, 4 deletions
diff --git a/packages/taler-wallet-core/src/operations/exchanges.ts b/packages/taler-wallet-core/src/operations/exchanges.ts index 76ce874de..618b1cf4a 100644 --- a/packages/taler-wallet-core/src/operations/exchanges.ts +++ b/packages/taler-wallet-core/src/operations/exchanges.ts @@ -43,16 +43,19 @@ import { WALLET_CACHE_BREAKER_CLIENT_VERSION, WALLET_EXCHANGE_PROTOCOL_VERSION, } from "./versions"; -import { getTimestampNow, Duration } from "../util/time"; +import { getTimestampNow, Duration, isTimestampExpired } from "../util/time"; import { compare } from "../util/libtoolVersion"; import { createRecoupGroup, processRecoupGroup } from "./recoup"; import { TalerErrorCode } from "../TalerErrorCode"; import { readSuccessResponseJsonOrThrow, readSuccessResponseTextOrThrow, + getExpiryTimestamp, } from "../util/http"; import { Logger } from "../util/logging"; import { URL } from "../util/url"; +import { reconcileReserveHistory } from "../util/reserveHistoryUtil"; +import { checkDbInvariant } from "../util/invariants"; const logger = new Logger("exchanges.ts"); @@ -195,6 +198,7 @@ async function updateExchangeWithKeys( masterPublicKey: exchangeKeysJson.master_public_key, protocolVersion: protocolVersion, signingKeys: exchangeKeysJson.signkeys, + nextUpdateTime: getExpiryTimestamp(resp), }; r.updateStatus = ExchangeUpdateStatus.FetchWire; r.lastError = undefined; @@ -459,7 +463,7 @@ async function updateExchangeFromUrlImpl( const now = getTimestampNow(); baseUrl = canonicalizeBaseUrl(baseUrl); - const r = await ws.db.get(Stores.exchanges, baseUrl); + let r = await ws.db.get(Stores.exchanges, baseUrl); if (!r) { const newExchangeRecord: ExchangeRecord = { builtIn: false, @@ -476,7 +480,6 @@ async function updateExchangeFromUrlImpl( termsOfServiceAcceptedTimestamp: undefined, termsOfServiceLastEtag: undefined, termsOfServiceText: undefined, - updateDiff: undefined, }; await ws.db.put(Stores.exchanges, newExchangeRecord); } else { @@ -498,6 +501,16 @@ async function updateExchangeFromUrlImpl( }); } + r = await ws.db.get(Stores.exchanges, baseUrl); + checkDbInvariant(!!r); + + + const t = r.details?.nextUpdateTime; + if (!forceNow && t && !isTimestampExpired(t)) { + logger.trace("using cached exchange info"); + return r; + } + await updateExchangeWithKeys(ws, baseUrl); await updateExchangeWithWireInfo(ws, baseUrl); await updateExchangeWithTermsOfService(ws, baseUrl); diff --git a/packages/taler-wallet-core/src/types/dbTypes.ts b/packages/taler-wallet-core/src/types/dbTypes.ts index 1c3613ced..b74a9ce3e 100644 --- a/packages/taler-wallet-core/src/types/dbTypes.ts +++ b/packages/taler-wallet-core/src/types/dbTypes.ts @@ -539,6 +539,11 @@ export interface ExchangeDetails { * Timestamp for last update. */ lastUpdateTime: Timestamp; + + /** + * When should we next update the information about the exchange? + */ + nextUpdateTime: Timestamp; } export enum ExchangeUpdateStatus { diff --git a/packages/taler-wallet-core/src/util/http.ts b/packages/taler-wallet-core/src/util/http.ts index 58b04d455..0977b429e 100644 --- a/packages/taler-wallet-core/src/util/http.ts +++ b/packages/taler-wallet-core/src/util/http.ts @@ -26,7 +26,7 @@ import { Codec } from "./codec"; import { OperationFailedError, makeErrorDetails } from "../operations/errors"; import { TalerErrorCode } from "../TalerErrorCode"; import { Logger } from "./logging"; -import { Duration } from "./time"; +import { Duration, Timestamp, getTimestampNow } from "./time"; const logger = new Logger("http.ts"); @@ -253,3 +253,19 @@ export async function readSuccessResponseTextOrThrow<T>( } throwUnexpectedRequestError(httpResponse, r.talerErrorResponse); } + +/** + * Get the timestamp at which the response's content is considered expired. + */ +export function getExpiryTimestamp(httpResponse: HttpResponse): Timestamp { + const expiryDateMs = new Date( + httpResponse.headers.get("expiry") ?? "", + ).getTime(); + if (Number.isNaN(expiryDateMs)) { + return getTimestampNow(); + } else { + return { + t_ms: expiryDateMs, + } + } +} diff --git a/packages/taler-wallet-core/src/util/time.ts b/packages/taler-wallet-core/src/util/time.ts index ccd75e14b..ff4c1885b 100644 --- a/packages/taler-wallet-core/src/util/time.ts +++ b/packages/taler-wallet-core/src/util/time.ts @@ -46,6 +46,10 @@ export function getTimestampNow(): Timestamp { }; } +export function isTimestampExpired(t: Timestamp) { + return timestampCmp(t, getTimestampNow()) <= 0; +} + export function getDurationRemaining( deadline: Timestamp, now = getTimestampNow(), |