试图通过python套接字升级到http2
我正在尝试使用python套接字升级到http/2.0。我已经尝试过这样使用升级头:试图通过python套接字升级到http2,python,sockets,ssl,Python,Sockets,Ssl,我正在尝试使用python套接字升级到http/2.0。我已经尝试过这样使用升级头:Connection:upgrade然后upgrade:h2c。这使服务器以http/1.1 200 OK响应进行响应。我现在正试图通过ssl模块使用ALPN。 这是通过ALPN尝试的代码: def connect_socket(self): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) context =
Connection:upgrade
然后upgrade:h2c
。这使服务器以http/1.1 200 OK响应进行响应。我现在正试图通过ssl
模块使用ALPN。这是通过ALPN尝试的代码:
def connect_socket(self):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
context = ssl.create_default_context()
context.set_alpn_protocols(['h2c'])
while True:
try:
sock.connect(("twitter.com", 443))
sock = context.wrap_socket(sock)
return sock
except:
pass
这只是挂在上下文中。包装套接字(sock)
。如果我去掉上下文,只使用ssl.wrap_socket()一切正常,我就可以很好地使用HTTP/1.1。服务器确实支持它,因为使用PyCurl的详细模式,我可以看到它使用HTTP/2。我试过使用
h2c
http/2.0
和h2
打印我得到的异常结果是:
[WinError 10056] A connect request was made on an already connected socket
仍不升级的最新代码:
def connect_socket(self):
while True:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
context = ssl.create_default_context()
context.set_alpn_protocols(['h2c'])
context.check_hostname = False
try:
sock.connect(("twitter.com", 443))
sock = context.wrap_socket(sock)
return sock
except Exception as e:
sock.close()
print(e)
这将返回一个无错误的套接字,然后发送此请求:
def test_send_data(self, sock):
unencoded_string = 'GET /noah HTTP/1.1\r\nHost: twitter.com\r\nConnection: keep-alive\r\n\r\n'
sock.send(unencoded_string.encode())
这很好,响应的重要部分是:
HTTP/1.1 200 OK\r\ncache-control: no-cache, no-store, must-revalidate,
我的问题是:为什么它只是挂起,我如何修复它?我认为您的一些异常处理给了您错误的提示。如果遇到异常,您可能会再次尝试连接,Windows会在某个时候抱怨尝试连接到未关闭的套接字 HTTP/2的ALPN协议应设置为
h2
,然后运行代码时出现错误:
ValueError: check_hostname requires server_hostname
添加该参数后,我能够从服务器获得响应,Python说连接是H2:
导入套接字
导入ssl
def connect_h2_插槽(主机):
sock=socket.socket(socket.AF\u INET,socket.sock\u流)
context=ssl.create\u default\u context()
context.set_alpn_协议([“h2”])
sock.connect((主机,443))
sock=context.wrap\u套接字(sock,server\u hostname=host)
回程短袜
s=连接h2插座(“twitter.com”)
打印(“选定协议:”,s.选定协议()
打印(s.recv())
运行此命令将为我产生以下结果:
'h2'
是否改变了与'h2c'
相反的任何东西?不,原来我得到了一个例外。查看编辑后的问题了解详细信息。while循环有什么用?我相信你首先遇到了一个不同的异常,它会传递异常,然后当你再次连接时,你会发现你已经在套接字上了,因为你处于循环中。哎哟,不小心在最近的一条评论之前删除了我的评论,这条评论对后人来说是“passserver\u hostname=“twitter.com”“
到包装\u套接字
并使用h2作为协议。应该没问题。摆脱while循环,不要传递异常。“原来你是对的。使用h2,不检查主机名挂起,但传递服务器的主机名将起作用。在那之后,我的下一个错误实际上是在recv函数中,我正在寻找\r\n\r\n从读取循环中断并返回字节字符串。我刚刚意识到这将不起作用,如果您愿意,在打印套接字recv数据后,发布答案,我将接受+up-vote。您是否知道如何通过HPACK解压缩响应?我似乎越来越多了errors@Noah我不知道HPACK是什么,最好还是单独问一个问题!
Selected protocol: h2
b'\x00\x00\x06\x04\x00\x00\x00\x00\x00\x00\x04\x00\x01\x00\x00'