diff options
| -rw-r--r-- | acmens.py | 48 | 
1 files changed, 26 insertions, 22 deletions
| @@ -22,7 +22,7 @@ import copy  import textwrap  from urllib.request import urlopen -from urllib.error import HTTPError +from urllib.error import URLError  __version__ = "0.2.0.dev" @@ -58,7 +58,7 @@ def _cmd(cmd_list, stdin=None, cmd_input=None, err_msg="Command Line Error"):      return out -def _do_request(url, data=None, err_msg="Error", depth=0): +def _do_request(url, data=None, err_msg="Error"):      try:          resp = urllib.request.urlopen(              urllib.request.Request( @@ -75,29 +75,17 @@ def _do_request(url, data=None, err_msg="Error", depth=0):              resp.getcode(),              resp.headers,          ) -    except IOError as e: +    except URLError as e:          resp_data = e.read().decode("utf8") if hasattr(e, "read") else str(e)          code, headers = getattr(e, "code", None), {}      try:          resp_data = json.loads(resp_data)  # try to parse json results      except ValueError: -        pass  # ignore json parsing errors -    if ( -        depth < 100 -        and code == 400 -        and resp_data["type"] == "urn:ietf:params:acme:error:badNonce" -    ): -        raise IndexError(resp_data)  # allow 100 retrys for bad nonces -    if code not in [200, 201, 204]: -        raise ValueError( -            "{0}:\nUrl: {1}\nData: {2}\nResponse Code: {3}\nResponse: {4}".format( -                err_msg, url, data, code, resp_data -            ) -        ) +        pass  # resp_data is not a JSON string; that's fine      return resp_data, code, headers -def _send_signed_request(url, payload, nonce_url, auth, account_key, err_msg, depth=0): +def _send_signed_request(url, payload, nonce_url, auth, account_key, err_msg):      """Make signed request to ACME endpoint"""      payload64 = "" if payload is None else _b64(json.dumps(payload).encode("utf8"))      new_nonce = _do_request(nonce_url)[2]["Replay-Nonce"] @@ -114,12 +102,28 @@ def _send_signed_request(url, payload, nonce_url, auth, account_key, err_msg, de      data = json.dumps(          {"protected": protected64, "payload": payload64, "signature": _b64(out)}      ) -    try: -        return _do_request(url, data=data.encode("utf8"), err_msg=err_msg, depth=depth) -    except IndexError:  # retry bad nonces (they raise IndexError) -        return _send_signed_request( -            url, payload, auth, account_key, err_msg, depth=(depth + 1) + +    tried = 0 +    while True: +        resp_data, resp_code, headers = _do_request( +            url, data=data.encode("utf8"), err_msg=err_msg          ) +        if resp_code in [200, 201, 204]: +            return resp_data, resp_code, headers +        elif ( +            resp_code == 400 +            and resp_data.get("type", "") == "urn:ietf:params:acme:error:badNonce" +            and tried < 100 +        ): +            tried += 1 +            continue +        else: +            sys.stderr.write( +                "{0}:\nUrl: {1}\nData: {2}\nResponse Code: {3}\nResponse: {4}".format( +                    err_msg, url, data, resp_code, resp_data +                ) +            ) +            sys.exit(1)  def _poll_until_not(url, pending_statuses, nonce_url, auth, account_key, err_msg): | 
