From a111d61d85454f5d58a0f843ced3413b5678f244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Valls=20Fern=C3=A1ndez?= Date: Thu, 30 Mar 2017 02:25:34 +0200 Subject: [PATCH] Move nonce retry from jws to http (#367) * Move nonce retry from jws to http The error raised by an "invalid nonce" response never appeared inside jws.go, but instead it was handled at http.go, so it makes sense to move the retry logic to that file. The previous code from jws.go had no effect and did not solve issues related to invalid nonces. * Rename retry response variable name for clarity --- acme/http.go | 33 ++++++++++++++++++++++++++++++++- acme/jws.go | 16 +--------------- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/acme/http.go b/acme/http.go index dc958046..a858b5a7 100644 --- a/acme/http.go +++ b/acme/http.go @@ -97,10 +97,41 @@ func postJSON(j *jws, uri string, reqBody, respBody interface{}) (http.Header, e if err != nil { return nil, fmt.Errorf("Failed to post JWS message. -> %v", err) } + defer resp.Body.Close() if resp.StatusCode >= http.StatusBadRequest { - return resp.Header, handleHTTPError(resp) + + err := handleHTTPError(resp) + + switch err.(type) { + + case NonceError: + + // Retry once if the nonce was invalidated + + retryResp, err := j.post(uri, jsonBytes) + if err != nil { + return nil, fmt.Errorf("Failed to post JWS message. -> %v", err) + } + + defer retryResp.Body.Close() + + if retryResp.StatusCode >= http.StatusBadRequest { + return retryResp.Header, handleHTTPError(retryResp) + } + + if respBody == nil { + return retryResp.Header, nil + } + + return retryResp.Header, json.NewDecoder(retryResp.Body).Decode(respBody) + + default: + return resp.Header, err + + } + } if respBody == nil { diff --git a/acme/jws.go b/acme/jws.go index 3b77cd49..a3943434 100644 --- a/acme/jws.go +++ b/acme/jws.go @@ -44,26 +44,12 @@ func (j *jws) post(url string, content []byte) (*http.Response, error) { if err != nil { return nil, fmt.Errorf("Failed to HTTP POST to %s -> %s", url, err.Error()) } - - // Even in case of an error, the response should still contain a nonce. + nonce, nonceErr := getNonceFromResponse(resp) if nonceErr == nil { j.nonces.Push(nonce) } - if err != nil { - switch err.(type) { - case NonceError: - // In case of a nonce error - retry once - resp, err = httpPost(url, "application/jose+json", bytes.NewBuffer([]byte(signedContent.FullSerialize()))) - if err != nil { - return nil, fmt.Errorf("Failed to HTTP POST to %s -> %s", url, err.Error()) - } - default: - return nil, fmt.Errorf("Failed to HTTP POST to %s -> %s", url, err.Error()) - } - } - return resp, nil }