# Buggy code
def send_signed_request(self, url, payload):
    """
    Sends a JWS signed HTTP POST request to the ACME server and returns
    the response as dictionary
    https://tools.ietf.org/html/draft-ietf-acme-acme-02#section-5.2
    """
    protected = copy.deepcopy(self.jws_header)
    protected["nonce"] = self.directory.get_nonce()

    try:
        payload64 = nopad_b64(self.module.jsonify(payload).encode("utf8"))
        protected64 = nopad_b64(self.module.jsonify(protected).encode("utf8"))
    except Exception as e:
        self.module.fail_json(
            msg="Failed to encode payload / headers as JSON: {0}".format(e)
        )

    openssl_sign_cmd = [self._openssl_bin, "dgst", "-sha256", "-sign", self.key]
    sign_payload = "{0}.{1}".format(protected64, payload64).encode("utf8")
    _, out, _ = self.module.run_command(
        openssl_sign_cmd, data=sign_payload, check_rc=True, binary_data=True
    )

    data = self.module.jsonify(
        {
            "header": self.jws_header,
            "protected": protected64,
            "payload": payload64,
            "signature": nopad_b64(out),
        }
    )

    resp, info = fetch_url(self.module, url, data=data, method="POST")
    result = None
    try:
        content = resp.read()
    except AttributeError:
        if info["body"]:
            content = info["body"]

    if content:
        if info["content-type"].startswith("application/json"):
            try:
                result = self.module.from_json(content.decode("utf8"))
            except ValueError:
                self.module.fail_json(
                    msg="Failed to parse the ACME response: {0} {1}".format(
                        url, content
                    )
                )
        else:
            result = content

    return result, info


# Traceback (KeyError)
The full traceback is:
Traceback (most recent call last):
File "/tmp/ansible_f44oyk38/ansible_module_letsencrypt.py", line 812, in <module>
main()
File "/tmp/ansible_f44oyk38/ansible_module_letsencrypt.py", line 802, in main
client = ACMEClient(module)
File "/tmp/ansible_f44oyk38/ansible_module_letsencrypt.py", line 521, in __init__
self.account = ACMEAccount(module)
File "/tmp/ansible_f44oyk38/ansible_module_letsencrypt.py", line 316, in __init__
self.directory = ACMEDirectory(module)
File "/tmp/ansible_f44oyk38/ansible_module_letsencrypt.py", line 289, in __init__
self.directory = simple_get(self.module, self.directory_root)
File "/tmp/ansible_f44oyk38/ansible_module_letsencrypt.py", line 191, in simple_get
if info['content-type'].startswith('application/json'):
KeyError: 'content-type'

fatal: [default]: FAILED! => {
"changed": false,
"failed": true,
"module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_f44oyk38/ansible_module_letsencrypt.py\", line 812, in <module>\n    main()\n  File \"/tmp/ansible_f44oyk38/ansible_module_letsencrypt.py\", line 802, in main\n    client = ACMEClient(module)\n  File \"/tmp/ansible_f44oyk38/ansible_module_letsencrypt.py\", line 521, in __init__\n    self.account = ACMEAccount(module)\n  File \"/tmp/ansible_f44oyk38/ansible_module_letsencrypt.py\", line 316, in __init__\n    self.directory = ACMEDirectory(module)\n  File \"/tmp/ansible_f44oyk38/ansible_module_letsencrypt.py\", line 289, in __init__\n    self.directory = simple_get(self.module, self.directory_root)\n  File \"/tmp/ansible_f44oyk38/ansible_module_letsencrypt.py\", line 191, in simple_get\n    if info['content-type'].startswith('application/json'):\nKeyError: 'content-type'\n",
"module_stdout": "",
"msg": "MODULE FAILURE",
"rc": 0
}

# Fixed code
def send_signed_request(self, url, payload):
    """
    Sends a JWS signed HTTP POST request to the ACME server and returns
    the response as dictionary
    https://tools.ietf.org/html/draft-ietf-acme-acme-02#section-5.2
    """
    protected = copy.deepcopy(self.jws_header)
    protected["nonce"] = self.directory.get_nonce()

    try:
        payload64 = nopad_b64(self.module.jsonify(payload).encode("utf8"))
        protected64 = nopad_b64(self.module.jsonify(protected).encode("utf8"))
    except Exception as e:
        self.module.fail_json(
            msg="Failed to encode payload / headers as JSON: {0}".format(e)
        )

    openssl_sign_cmd = [self._openssl_bin, "dgst", "-sha256", "-sign", self.key]
    sign_payload = "{0}.{1}".format(protected64, payload64).encode("utf8")
    _, out, _ = self.module.run_command(
        openssl_sign_cmd, data=sign_payload, check_rc=True, binary_data=True
    )

    data = self.module.jsonify(
        {
            "header": self.jws_header,
            "protected": protected64,
            "payload": payload64,
            "signature": nopad_b64(to_bytes(out)),
        }
    )

    resp, info = fetch_url(self.module, url, data=data, method="POST")
    result = {}
    try:
        content = resp.read()
    except AttributeError:
        content = info.get("body")

    if content:
        if info["content-type"].startswith("application/json"):
            try:
                result = self.module.from_json(content.decode("utf8"))
            except ValueError:
                self.module.fail_json(
                    msg="Failed to parse the ACME response: {0} {1}".format(
                        url, content
                    )
                )
        else:
            result = content

    return result, info