summaryrefslogtreecommitdiffstats
path: root/acme_dns_tiny.py
diff options
context:
space:
mode:
Diffstat (limited to 'acme_dns_tiny.py')
-rw-r--r--acme_dns_tiny.py17
1 files changed, 13 insertions, 4 deletions
diff --git a/acme_dns_tiny.py b/acme_dns_tiny.py
index 051e6ba..4903c63 100644
--- a/acme_dns_tiny.py
+++ b/acme_dns_tiny.py
@@ -177,17 +177,22 @@ class ACME:
self.jwk_thumbprint = b64sha256(json.dumps(header['jwk'],
sort_keys=True, separators=(',', ':')))
+ def request_new_nonce(self):
+ log.info('Request new nonce')
+ self.jws_header['nonce'] = requests.get(self.directory["newNonce"]
+ ).headers['Replay-Nonce']
+
def init_sreqs(self, directory_url=None):
self.generate_jws_header(self.account_key_path)
log.info('Fetch information from the ACME directory.')
self.directory = dirmap = requests.get(directory_url,
headers=self.dirheaders).json()
- log.info('Request first nonce')
- self.jws_header['nonce'] = requests.get(dirmap["newNonce"]
- ).headers['Replay-Nonce']
+ self.request_new_nonce()
- def sreq(self, url=None, payload=None, headers=None):
+ def sreq(self, url=None, payload=None, headers=None, max_retry=10):
"""Sends signed requests to ACME server."""
+ if max_retry < 0:
+ raise ValueError('max_retry exceeded')
# POST-as-GET (payload=None != {}), payload64 is an empty string
payload64 = '' if payload is None else b64json(payload)
protected64 = b64json({**self.jws_header, 'url': url})
@@ -207,6 +212,10 @@ class ACME:
with contextlib.suppress(ValueError):
jmap = req.json()
if req.status_code not in (200, 201):
+ if jmap['type'] == 'urn:ietf:params:acme:error:badNonce':
+ log.info('nonce expired or invalid, retry (left %d)', max_retry)
+ self.request_new_nonce()
+ return self.sreq(url, payload, headers, max_retry-1)
raise ValueError(f'Request failed: {req.status_code} {jmap}, '
'hint: {sreq.headers.get("Link", "empty")}.')
return collections.namedtuple('sreq', ['code', 'headers', 'map',