gpt4 book ai didi

python - 将 Python “requests” 与现有套接字连接一起使用

转载 作者:太空狗 更新时间:2023-10-29 16:57:40 24 4
gpt4 key购买 nike

Python“requests”库目前风靡一时,因为它为发出 HTTP 请求提供了漂亮的界面——但在它之下似乎有许多间接层—— session 、HTTP 适配器,最后是urllib3.

如果我已经持有一个打开的套接字,并且想使用“请求”向该套接字发送 HTTP 响应并接收回复,那么在这个抽象堆栈中哪里是正确的干预位置?

如果没有某种干预(或定制?),堆栈将尝试为我创建一个新的 TCP/IP 套接字,但在我的特定应用程序中,我的代码不会被调用,直到已经代表我建立了连接,因此,如果我希望能够使用 Requests 的功能,我将需要说服 Requests 在现有套接字上进行对话。

请求库:

http://pypi.python.org/pypi/requests

https://github.com/kennethreitz/requests

最佳答案

以下代码需要来自git的请求(尤其是requests.packages.urllib3.poolmanager.PoolManager._new_pool())

我使用 ncat -v -l 127.0.0.1 8000 测试了它

问题在于,连接不是由 urllib3 打开的,而是由标准库中的 httplib 打开的。

import socket
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3 import PoolManager, HTTPConnectionPool

try:
from http.client import HTTPConnection
except ImportError:
from httplib import HTTPConnection


class MyAdapter(HTTPAdapter):
def init_poolmanager(self, connections, maxsize):
self.poolmanager = MyPoolManager(num_pools=connections,
maxsize=maxsize)


class MyPoolManager(PoolManager):
def _new_pool(self, scheme, host, port):
# Important!
if scheme == 'http' and host == my_host and port == my_port:
return MyHTTPConnectionPool(host, port, **self.connection_pool_kw)
return super(PoolManager, self)._new_pool(self, scheme, host, port)


class MyHTTPConnectionPool(HTTPConnectionPool):
def _new_conn(self):
self.num_connections += 1
return MyHTTPConnection(host=self.host,
port=self.port,
strict=self.strict)


class MyHTTPConnection(HTTPConnection):
def connect(self):
"""Connect to the host and port specified in __init__."""
# Original
# self.sock = socket.create_connection((self.host, self.port),
# self.timeout, self.source_address)
# Important!
self.sock = my_socket
if self._tunnel_host:
self._tunnel()


if __name__ == '__main__':
import time

my_host = '127.0.0.1'
my_port = 8000

my_socket = socket.create_connection((my_host, my_port))
time.sleep(4)
s = requests.Session()
s.mount('http://', MyAdapter())
s.get('http://127.0.0.1:8000/foo')

编辑:

或者直接对连接池进行monkeypatching:

class MyHTTPConnection(HTTPConnection):
def connect(self):
self.sock = my_socket
if self._tunnel_host:
self._tunnel()

requests.packages.urllib3.connectionpool.HTTPConnection = MyHTTPConnection

if __name__ == '__main__':
my_host = '127.0.0.1'
my_port = 8000

my_socket = socket.create_connection((my_host, my_port))
requests.get('http://127.0.0.1:8000/foo')

关于python - 将 Python “requests” 与现有套接字连接一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14665064/

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