更新: jython 2.7b1 のバグに関連する問題。バグ レポートを参照してください: http://bugs.jython.org/issue2021。jython-coders は修正に取り組んでいます!
Jython2.5.3 から jython2.7beta1 に変更した後、SSL、http、および「すべての証明書を信頼する」を使用して Web ページのコンテンツを読み取ることができなくなりました。https ページからの応答は常に空の文字列であり、Jython の httplib.py から httplib.BadStatusLine 例外が発生します。
認証が必要なWebページから読み取ることができる必要があり、移植性が必要なため、証明書ストアをセットアップしたくありません。したがって、私の解決策は、http://tech.pedersen-live.com/2010/10/trusting-all-certificates-in-jython/が提供する優れた実装を使用することです
サンプル コードを以下に詳しく説明します。Twitter は証明書の信頼を必要としないため、最良の例ではないかもしれません。ただし、結果はデコレータの有無にかかわらず同じです。
#! /usr/bin/python
import sys
from javax.net.ssl import TrustManager, X509TrustManager
from jarray import array
from javax.net.ssl import SSLContext
class TrustAllX509TrustManager(X509TrustManager):
# Define a custom TrustManager which will blindly
# accept all certificates
def checkClientTrusted(self, chain, auth):
pass
def checkServerTrusted(self, chain, auth):
pass
def getAcceptedIssuers(self):
return None
# Create a static reference to an SSLContext which will use
# our custom TrustManager
trust_managers = array([TrustAllX509TrustManager()], TrustManager)
TRUST_ALL_CONTEXT = SSLContext.getInstance("SSL")
TRUST_ALL_CONTEXT.init(None, trust_managers, None)
# Keep a static reference to the JVM's default SSLContext for restoring
# at a later time
DEFAULT_CONTEXT = SSLContext.getDefault()
def trust_all_certificates(f):
# Decorator function that will make it so the context of the decorated
# method will run with our TrustManager that accepts all certificates
def wrapped(*args, **kwargs):
# Only do this if running under Jython
if 'java' in sys.platform:
from javax.net.ssl import SSLContext
SSLContext.setDefault(TRUST_ALL_CONTEXT)
print "SSLContext set to TRUST_ALL"
try:
res = f(*args, **kwargs)
return res
finally:
SSLContext.setDefault(DEFAULT_CONTEXT)
else:
return f(*args, **kwargs)
return wrapped
#@trust_all_certificates
def read_page(host):
import httplib
print "Host: " + host
conn = httplib.HTTPSConnection(host)
conn.set_debuglevel(1)
conn.request('GET', '/example')
response = conn.getresponse()
print response.read()
read_page("twitter.com")
これにより、次の結果が得られます。
Host: twitter.com
send: 'GET /example HTTP/1.1\r\nHost: twitter.com\r\nAccept-Encoding: identity\r\n\r\n'
reply: ''
Traceback (most recent call last):
File "jytest.py", line 62, in <module>
read_page("twitter.com")
File "jytest.py", line 59, in read_page
response = conn.getresponse()
File "/Users/erikiveroth/Workspace/Procera/sandbox/jython/jython2.7.jar/Lib/httplib.py", line 1030, in getresponse
File "/Users/erikiveroth/Workspace/Procera/sandbox/jython/jython2.7.jar/Lib/httplib.py", line 407, in begin
File "/Users/erikiveroth/Workspace/Procera/sandbox/jython/jython2.7.jar/Lib/httplib.py", line 371, in _read_status
httplib.BadStatusLine: ''
jython2.5.3 に戻すと、Twitter から解析可能な出力が得られます。
これを見たことがある人はいますか?これに関するjythonプロジェクトページでバグチケットを見つけることができず、どの変更がこの動作につながる可能性があるかを理解できません(おそらく#1309以上ですが、それが私の問題に関連しているかどうかはわかりません)。
乾杯