3

更新:与 jython 2.7b1 中的错误相关的问题。请参阅错误报告:http ://bugs.jython.org/issue2021 。jython-coders 正在努力修复!

从 Jython2.5.3 更改为 jython2.7beta1 后,我不再能够使用 SSL、http 和“信任所有证书”读取网页内容。https 页面的响应始终为空字符串,从而导致 Jython 中 httplib.py 的 httplib.BadStatusLine 异常。

我需要能够从需要身份验证的网页中读取,并且不想设置任何证书存储,因为我必须具有可移植性。因此我的解决方案是使用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