Python httplib SSL23_GET_SERVER_你好:未知p

2024-10-02 22:36:15 发布

您现在位置:Python中文网/ 问答频道 /正文

注意:这段代码在Ubuntu上运行得很好,但在mac上不行,我不想在本地更改mac/python设置,而是尝试对代码进行更改,这样它就可以在任何地方运行。。

import ssl 
import httplib 
httplib.HTTPConnection(server, port, timeout)

但它会抛出错误:

[Errno 1] _ssl.c:503: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol

现在代码不再使用urllib.request而使用httplib

我想更改代码,以便将SSLv3作为默认协议,如下所示:

ssl.SSLContext(ssl.PROTOCOL_SSLv3)

我环顾四周,发现了一些链接,但没有任何工作!

this link is for ubuntu

link for python urllib and cURL

python bug fix, but again for urllib


Tags: 代码importsslforserverportubuntumac
1条回答
网友
1楼 · 发布于 2024-10-02 22:36:15

注意:自python 2.7.9以来,HTTPSConnection构造函数允许将sslcontext作为参数传递,在本例中应使用该参数。

此答案早于此更改,因此仅适用于过时的python版本。


^{}只需调用打开的套接字上的^{}来初始化一个https连接,不幸的是,您不能在python2.7中指定任何参数(python3允许passing the ^{})。

如果要指定协议版本,则需要对这两个版本中的一个进行monkey修补:

方法1:补丁httplib.HTTPSConnection.connect

import httplib
import socket
import ssl

def connect_patched(self):
    "Connect to a host on a given (SSL) port."

    sock = socket.create_connection((self.host, self.port),
                                    self.timeout, self.source_address)
    if self._tunnel_host:
        self.sock = sock
        self._tunnel()
    self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file,
                                ssl_version=ssl.PROTOCOL_SSLv3)

httplib.HTTPSConnection.connect = connect_patched

这将更改使用HTTPSConnection建立的所有连接的协议版本。

方法2:补丁ssl.wrap_socket

import ssl

wrap_socket_orig = ssl.wrap_socket

def wrap_socket_patched(sock, keyfile=None, certfile=None,
                        server_side=False, cert_reqs=ssl.CERT_NONE,
                        ssl_version=ssl.PROTOCOL_SSLv3, ca_certs=None,
                        do_handshake_on_connect=True,
                        suppress_ragged_eofs=True, ciphers=None):
    return wrap_socket_orig(sock, keyfile, certfile, server_side,
                            cert_reqs, ssl_version, ca_certs,
                            do_handshake_on_connect,
                            suppress_ragged_eofs, ciphers)

ssl.wrap_socket = wrap_socket_patched

这将更改使用wrap_socket的所有代码的默认协议版本,因此也会影响其他库。

编辑:

方法3:因为httplib实际上只访问来自sslwrap_socket,所以也可以用提供wrap_socket的类替换httplib.ssl。使用functools.partial可以使编写以下内容变得非常优雅:

import httplib
import ssl
from functools import partial

class fake_ssl:
    wrap_socket = partial(ssl.wrap_socket, ssl_version=ssl.PROTOCOL_SSLv3)

httplib.ssl = fake_ssl

相关问题 更多 >