Repository: certbot/certbot

Issue:
`acme` module's `client._revoke` sends incorrect `ContentType` header.
[ACME draft-10, section 6.2](https://tools.ietf.org/html/draft-ietf-acme-acme-10#section-6.2) explicitly requires POSTs be sent with a `Content-Type` of `application/jose+json`: 

> Because client requests in ACME carry JWS objects in the Flattened
> JSON Serialization, they must have the "Content-Type" header field
> set to "application/jose+json".  If a request does not meet this
> requirement, then the server MUST return a response with status code
> 415 (Unsupported Media Type).

The good news is that Certbot & the `acme` module already do this in 99.99% of cases :tada: :+1: :balloon: 

The bad news is that `client._revoke` overrides the default (correct) `ContentType` with `none`: https://github.com/certbot/certbot/blob/77fdb4d7d6194989dcc775f2e0ad81b6147c2359/acme/acme/client.py#L231

This will make revocation requests fail in a world where this restriction is enforced (See https://github.com/letsencrypt/boulder/pull/3532) 

There doesn't seem to be a reason to want to override `ContentType` in this case so I believe the fix is to change `_revoke` to use the default.

Thanks!

Discussion:
cpu: Thank you @sydneyli :1st_place_medal: :racing_car: 

Patch:
diff --git a/acme/acme/client.py b/acme/acme/client.py
index d52c82a5c..9e2478afe 100644
--- a/acme/acme/client.py
+++ b/acme/acme/client.py
@@ -227,8 +227,7 @@ class ClientBase(object):  # pylint: disable=too-many-instance-attributes
         response = self._post(url,
                               messages.Revocation(
                                 certificate=cert,
-                                reason=rsn),
-                                content_type=None)
+                                reason=rsn))
         if response.status_code != http_client.OK:
             raise errors.ClientError(
                 'Successful revocation must return HTTP OK status')


Test patch:
diff --git a/acme/acme/client_test.py b/acme/acme/client_test.py
index a0c27e74f..00b9e19dd 100644
--- a/acme/acme/client_test.py
+++ b/acme/acme/client_test.py
@@ -635,8 +635,7 @@ class ClientTest(ClientTestBase):
     def test_revoke(self):
         self.client.revoke(self.certr.body, self.rsn)
         self.net.post.assert_called_once_with(
-            self.directory[messages.Revocation], mock.ANY, content_type=None,
-            acme_version=1)
+            self.directory[messages.Revocation], mock.ANY, acme_version=1)
 
     def test_revocation_payload(self):
         obj = messages.Revocation(certificate=self.certr.body, reason=self.rsn)
@@ -776,8 +775,7 @@ class ClientV2Test(ClientTestBase):
     def test_revoke(self):
         self.client.revoke(messages_test.CERT, self.rsn)
         self.net.post.assert_called_once_with(
-            self.directory["revokeCert"], mock.ANY, content_type=None,
-            acme_version=2)
+            self.directory["revokeCert"], mock.ANY, acme_version=2)
 
 
 class MockJSONDeSerializable(jose.JSONDeSerializable):