respect cache header
This commit is contained in:
parent
0ffea74ad5
commit
659e9cdbe6
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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(),
|
||||
|
Loading…
Reference in New Issue
Block a user