Python的“请求”图书馆是目前所有的愤怒,因为漂亮的界面,它提供了HTTP请求的 - 但它的下面似乎有间接的许多层 - 会话,HTTP适配器和urllib3终于机制。
凡在本组抽象的是,如果我已经持有一个开放的插座,想用“请求”派下来的套接字的HTTP响应,并收到回复给介入正确的地方?
如果没有某种形式的干预(或定制?)的,堆栈会尽力为我创建一个新的TCP / IP套接字,但在我的特定应用我的代码不叫,直到连接已经代表我的建立,所以我会需要说服请求谈论现有插座上,如果我想能够使用要求的特点。
该请求库:
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')
直奔urllib3
库; 它拥有一个连接池urllib3.connectionpool
模块 。
你可以更换池或由黑客进行调整poolmanager
模块可能。