gpt4 book ai didi

python - 如何处理原始 Python 套接字中的 ssl 连接?

转载 作者:太空宇宙 更新时间:2023-11-03 13:54:04 25 4
gpt4 key购买 nike

我正在编写一个程序来下载给定的网页。由于某些限制,我只需要对所有连接使用原始 python 套接字。因此,我与给定域(对象响应 header 中的主机字段)建立套接字连接,然后发送 GET 请求。现在,当 url 是 https url 时,我想我需要先进行 SSL 握手(否则我会从服务器收到非 200 OK 响应以及其他提及 P3P 策略的错误响应)。我检查了 curl 的响应,以检查它如何能够在我没有成功下载的情况下成功下载,结果是 curl 首先进行 SSL 握手(这就是所有的区别)。 curl 始终能够成功下载给定对象,唯一的区别始终是它执行的 SSL 握手。

所以我想知道如何在原始 python 套接字中进行 SSL 握手?基本上我想要一个简单的解决方案,它允许我在使用原始套接字之外做最少的事情。

最佳答案

这里是一个带有 SLL 的 TCP 客户端的例子。

不确定这是否是下载网页的最佳方式,但它应该可以回答您的问题“原始 python 套接字中的 SSL 握手”。

您可能需要调整 struct.pack/unpack,但您已了解总体思路:

import socket
import ssl
import struct
import binascii
import sys

class NotConnectedException(Exception):
def __init__(self, message=None, node=None):
self.message = message
self.node = node

class DisconnectedException(Exception):
def __init__(self, message=None, node=None):
self.message = message
self.node = node

class Connector:
def __init__(self):
pass

def is_connected(self):
return (self.sock and self.ssl_sock)

def open(self, hostname, port, cacert):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.ssl_sock = ssl.wrap_socket(self.sock, ca_certs=cacert, cert_reqs=ssl.CERT_REQUIRED)

if hostname == socket.gethostname():
ipaddress = socket.gethostbyname_ex(hostname)[2][0]
self.ssl_sock.connect((ipaddress, port))
else:
self.ssl_sock.connect((hostname, port))

self.sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)

def close(self):
if self.sock: self.sock.close()
self.sock = None
self.ssl_sock = None

def send(self, buffer):
if not self.ssl_sock: raise NotConnectedException("Not connected (SSL Socket is null)")
self.ssl_sock.sendall(struct.pack('L', len(buffer)))
self.ssl_sock.sendall(buffer)

def receive(self):
if not self.ssl_sock: raise NotConnectedException("Not connected (SSL Socket is null)")
data_size_buffer = self.ssl_sock.recv(4)

if len(data_size_buffer) <= 0:
raise DisconnectedException()

data_size = struct.unpack('L', data_size_buffer)[0]
received_size = 0
data_buffer = ""

while received_size < data_size:
chunk = self.ssl_sock.recv(1024)
data_buffer += chunk
received_size += len(chunk)

return data_buffer

然后你像这样使用这个类:

    connector = Connector.Connector()
connector.open(server_ip, server_port, path_to_the_CA_cert.pem)
connector.send(your_data)
response = connector.receive()
connector.close()

关于python - 如何处理原始 Python 套接字中的 ssl 连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27679890/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com