JSONRPCサーバーを検証するテストを作成しています。リクエストモジュールを使用して、無効なContent-LengthヘッダーやContent-Typeヘッダーの設定などをテストしたいと思いました。ただし、サーバーには有効なクライアント証明書が必要であり、できません。turorialに記載されているように、requestsモジュールを取得してクライアント証明書を適切に利用します。
ソケットを開いて手動でデータを送信するだけで、問題なく機能します。
>>> 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!"}
しかし、requestsモジュールを使用して同じことを行うと、失敗します。
>>> 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>
だから、なぜこれが失敗したのかわからないだけでなく、何が悪かったのかを理解する方法さえわかりません。Apacheサーバーの設定を変更してロギングを有効にする許可を取得しようとすると、それが明らかになる可能性があります。しかし、なぜこれが失敗しているのかを理解する方法はクライアントにありますか?