mirror of
https://github.com/certbot/certbot.git
synced 2026-05-28 04:34:11 -04:00
Merge pull request #4114 from certbot/auto-retry-0.10.x
Automatically retry after getting badNonce error part 2
This commit is contained in:
commit
2ca44a064b
2 changed files with 42 additions and 4 deletions
|
|
@ -658,8 +658,25 @@ class ClientNetwork(object): # pylint: disable=too-many-instance-attributes
|
|||
self._add_nonce(self.head(url))
|
||||
return self._nonces.pop()
|
||||
|
||||
def post(self, url, obj, content_type=JOSE_CONTENT_TYPE, **kwargs):
|
||||
"""POST object wrapped in `.JWS` and check response."""
|
||||
def post(self, *args, **kwargs):
|
||||
"""POST object wrapped in `.JWS` and check response.
|
||||
|
||||
If the server responded with a badNonce error, the request will
|
||||
be retried once.
|
||||
|
||||
"""
|
||||
should_retry = True
|
||||
while True:
|
||||
try:
|
||||
return self._post_once(*args, **kwargs)
|
||||
except messages.Error as error:
|
||||
if should_retry and error.code == 'badNonce':
|
||||
logger.debug('Retrying request after error:\n%s', error)
|
||||
should_retry = False
|
||||
else:
|
||||
raise
|
||||
|
||||
def _post_once(self, url, obj, content_type=JOSE_CONTENT_TYPE, **kwargs):
|
||||
data = self._wrap_in_jws(obj, self._get_nonce(url))
|
||||
kwargs.setdefault('headers', {'Content-Type': content_type})
|
||||
response = self._send_request('POST', url, data=data, **kwargs)
|
||||
|
|
|
|||
|
|
@ -616,7 +616,9 @@ class ClientNetworkWithMockedResponseTest(unittest.TestCase):
|
|||
self.wrapped_obj = mock.MagicMock()
|
||||
self.content_type = mock.sentinel.content_type
|
||||
|
||||
self.all_nonces = [jose.b64encode(b'Nonce'), jose.b64encode(b'Nonce2')]
|
||||
self.all_nonces = [
|
||||
jose.b64encode(b'Nonce'),
|
||||
jose.b64encode(b'Nonce2'), jose.b64encode(b'Nonce3')]
|
||||
self.available_nonces = self.all_nonces[:]
|
||||
|
||||
def send_request(*args, **kwargs):
|
||||
|
|
@ -664,7 +666,7 @@ class ClientNetworkWithMockedResponseTest(unittest.TestCase):
|
|||
self.net._wrap_in_jws.assert_called_once_with(
|
||||
self.obj, jose.b64decode(self.all_nonces.pop()))
|
||||
|
||||
assert not self.available_nonces
|
||||
self.available_nonces = []
|
||||
self.assertRaises(errors.MissingNonce, self.net.post,
|
||||
'uri', self.obj, content_type=self.content_type)
|
||||
self.net._wrap_in_jws.assert_called_with(
|
||||
|
|
@ -680,6 +682,25 @@ class ClientNetworkWithMockedResponseTest(unittest.TestCase):
|
|||
self.assertRaises(errors.BadNonce, self.net.post, 'uri',
|
||||
self.obj, content_type=self.content_type)
|
||||
|
||||
def test_post_failed_retry(self):
|
||||
check_response = mock.MagicMock()
|
||||
check_response.side_effect = messages.Error.with_code('badNonce')
|
||||
|
||||
# pylint: disable=protected-access
|
||||
self.net._check_response = check_response
|
||||
self.assertRaises(messages.Error, self.net.post, 'uri',
|
||||
self.obj, content_type=self.content_type)
|
||||
|
||||
def test_post_successful_retry(self):
|
||||
check_response = mock.MagicMock()
|
||||
check_response.side_effect = [messages.Error.with_code('badNonce'),
|
||||
self.checked_response]
|
||||
|
||||
# pylint: disable=protected-access
|
||||
self.net._check_response = check_response
|
||||
self.assertEqual(self.checked_response, self.net.post(
|
||||
'uri', self.obj, content_type=self.content_type))
|
||||
|
||||
def test_head_get_post_error_passthrough(self):
|
||||
self.send_request.side_effect = requests.exceptions.RequestException
|
||||
for method in self.net.head, self.net.get:
|
||||
|
|
|
|||
Loading…
Reference in a new issue