使用jython2.7的https +信任所有证书不起作用。结果:httplib.BadStatusLine

时间:2013-02-28 10:56:04

标签: ssl https jython

  

更新:与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,但我不明白它是否与我的问题有关)。

干杯

0 个答案:

没有答案