From 540ef967457a7871637cfdb5012ed1fa3261757b Mon Sep 17 00:00:00 2001 From: xiaojunnuo Date: Sun, 1 Feb 2026 15:25:28 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Dlitessl=20new-nonce?= =?UTF-8?q?=E6=8A=A5428=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/acme-client/src/client.js | 4 +- packages/core/acme-client/src/http.js | 49 ++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/packages/core/acme-client/src/client.js b/packages/core/acme-client/src/client.js index 4313d99a2..4a9cd25e2 100644 --- a/packages/core/acme-client/src/client.js +++ b/packages/core/acme-client/src/client.js @@ -103,7 +103,9 @@ class AcmeClient { max: this.opts.backoffMax, }; - this.http = new HttpClient(this.opts.directoryUrl, this.opts.accountKey, this.opts.externalAccountBinding, this.opts.urlMapping, opts.logger); + const cacheNonce = true + // const cacheNonce = this.sslProvider === 'litessl'; + this.http = new HttpClient(this.opts.directoryUrl, this.opts.accountKey, this.opts.externalAccountBinding, this.opts.urlMapping, opts.logger, cacheNonce); this.api = new AcmeApi(this.http, this.opts.accountUrl); this.logger = opts.logger; } diff --git a/packages/core/acme-client/src/http.js b/packages/core/acme-client/src/http.js index f641634ca..b63fc7ece 100644 --- a/packages/core/acme-client/src/http.js +++ b/packages/core/acme-client/src/http.js @@ -19,7 +19,7 @@ import { getJwk } from './crypto/index.js'; */ class HttpClient { - constructor(directoryUrl, accountKey, externalAccountBinding = {}, urlMapping = {},logger) { + constructor(directoryUrl, accountKey, externalAccountBinding = {}, urlMapping = {}, logger, cacheNonce= false) { this.directoryUrl = directoryUrl; this.accountKey = accountKey; this.externalAccountBinding = externalAccountBinding; @@ -31,7 +31,34 @@ class HttpClient { this.directoryMaxAge = 86400; this.directoryTimestamp = 0; this.urlMapping = urlMapping; - this.log = logger? logger.info.bind(logger) : log; + this.log = logger ? logger.info.bind(logger) : log; + this.nonces = []; + this.cacheNonce = cacheNonce; + } + + pushNonce(nonce) { + if (!this.cacheNonce || !nonce) { + return; + } + this.nonces.push({ + nonce, + expires: Date.now() + 30*1000, + }); + } + popNonce() { + while (true) { + if (this.nonces.length === 0) { + return null; + } + const item = this.nonces.shift(); + if (!item) { + return null; + } + if (item.expires < Date.now()) { + continue; + } + return item.nonce; + } } /** @@ -70,6 +97,13 @@ class HttpClient { const resp = await axios.request(opts); this.log(`RESP ${resp.status} ${method} ${url}`); + + const nonce = resp.headers['replay-nonce']; + if (nonce) { + //如果有nonce + this.pushNonce(nonce); + } + return resp; } @@ -127,6 +161,13 @@ class HttpClient { */ async getNonce() { + + //尝试从队列中pop一个nonce + const nonce = this.popNonce(); + if (nonce) { + return nonce; + } + const url = await this.getResourceUrl('newNonce'); const resp = await this.request(url, 'head'); @@ -134,7 +175,11 @@ class HttpClient { throw new Error('Failed to get nonce from ACME provider'); } + if (this.cacheNonce) { + return this.popNonce(); + } return resp.headers['replay-nonce']; + } /**