Search code examples
pythonclient-certificatespython-requests

How do I diagnose client certificate errors with the requests module?


I'm writing tests which validate our JSONRPC server, and I wanted to use the requests module to test things like setting invalid Content-Length and Content-Type headers, etc. However, our server requires valid client certificates, and I can't get the requests module to properly make use of my client certs as documented in their turorial.

If I simply open a socket and manually send data, it works just fine:

>>> import socket, ssl
>>> s = """\
... POST /jsonrpc HTTP/1.1
... Host: example.com
... Content-Length: 77
... 
... {"params": [{"example": "parameter"}], "id": 1, "method": "example.function"}\
... """.replace("\n", "\r\n")
>>> sock = socket.create_connection(("example.com", 443))
>>> sock = ssl.wrap_socket(sock, keyfile = "key.pem", certfile = "cert.pem")
>>> sock.sendall(s)
144
>>> print(sock.recv(4096) + sock.recv(4096))
HTTP/1.1 200 OK
Date: Mon, 23 Jul 2012 19:50:17 GMT
Server: CherryPy/3.2.0
Content-Length: 53
Content-Type: application/json
Set-Cookie: session_id=4ee3f4c435aee126c8042d4fba99962a48ca0a37; expires=Mon, 23 Jul 2012 20:20:17 GMT; Path=/; secure
Connection: close

{"jsonrpc": "2.0", "id": 1, "result": "Hello World!"}

But when I use the requests module to do the same thing, it fails:

>>> import requests
>>> data = '{"params": [{"example": "parameter"}], "id": 1, "method": "example.function"}'
>>> r = requests.post("https://example.com/jsonrpc", data = data, headers = {"Content-Length": "77"}, timeout = 2, verify = False, cert = ("cert.pem", "key.pem"))
>>> print r.content
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /jsonrpc
on this server.</p>
<hr>
<address>Apache/2.2.15 (Red Hat) Server at example.com Port 443</address>
</body></html>

So not only do I not know why this failed, I don't even know how to figure out what went wrong. I can try to get permission to change our Apache server settings to turn logging way up and that might shed some light on it. But is there any way on the client to figure out why this is failing?


Solution

  • This problem went away when I upgraded to the latest version of the requests module. I'd still like to know how to diagnose these kinds of certificate errors in general, so if anyone knows then please post an answer!