3

更新: 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以上ですが、それが私の問題に関連しているかどうかはわかりません)。

乾杯

4

0 に答える 0