Python 什么';在请求框架中使用unix域套接字的正确方法是什么?

Python 什么';在请求框架中使用unix域套接字的正确方法是什么?,python,python-requests,Python,Python Requests,通常,使用框架执行post请求是通过以下方式完成的: payload = {'key1': 'value1', 'key2': 'value2'} r = requests.post("http://httpbin.org/post", data=payload) 但是:如何连接到unix套接字而不是进行TCP连接 请注意,如何在URL中对域路径进行编码 libcurl允许应用程序提供自己的套接字来执行请求 LDAP发明了自己的方案ldapi其中套接字名称在主机字段中编码 httpie在主机

通常,使用框架执行post请求是通过以下方式完成的:

payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.post("http://httpbin.org/post", data=payload)
但是:如何连接到unix套接字而不是进行TCP连接

请注意,如何在URL中对域路径进行编码

  • libcurl允许应用程序提供自己的套接字来执行请求
  • LDAP发明了自己的方案
    ldapi
    其中套接字名称在主机字段中编码
  • httpie
    在主机字段中使用
    http+unix
    方案和%-编码路径
以下是一些示例,但是否有RFC或既定的最佳实践?

您可以使用创建TCP到UNIX套接字代理,例如:

socat TCP-LISTEN:80,reuseaddr,fork UNIX-CLIENT:/tmp/foo.sock
然后将http请求发送到该代理。在UNIX套接字上侦听的服务器仍然必须理解HTTP,因为
socat
不进行任何消息转换。

请求没有现成的实现来处理UNIX套接字

但您可以创建一个自定义接口,用于连接到unix套接字、发送请求和读取应答

您需要实现的所有方法都是
.send()
.close()
,这很简单明了


在会话对象中注册适配器后,您可以将请求机制与UNIX传输一起使用。

无需重新发明轮子:

URL方案为http+unix,套接字路径按百分比编码到主机字段中:

import requests_unixsocket

session = requests_unixsocket.Session()

# Access /path/to/page from /tmp/profilesvc.sock
r = session.get('http+unix://%2Ftmp%2Fprofilesvc.sock/path/to/page')
assert r.status_code == 200

如果您想在Python3中找到一种简洁明了的方法,下面是一个工作示例,它将与unix域套接字上的Ubuntu snapd进行对话

导入请求
导入套接字
导入pprint
从urllib3.connection导入HTTPConnection
从urllib3.connectionpool导入HTTPConnectionPool
从requests.adapters导入HTTPAdapter
类SnapdConnection(HTTPConnection):
定义初始化(自):
super().\uuuu init\uuuuu(“本地主机”)
def连接(自):
self.sock=socket.socket(socket.AF\u UNIX,socket.sock\u流)
self.sock.connect(“/run/snap.socket”)
类SnapdConnectionPool(HTTPConnectionPool):
定义初始化(自):
super().\uuuu init\uuuuu(“本地主机”)
def新连接器(自身):
返回SnapdConnection()
类SnapdAdapter(HTTPAdapter):
def get_连接(自身、url、代理=无):
返回SnapdConnectionPool()
会话=请求。会话()
会话.mount(“http://snapd/,SnapdAdapter())
response=session.get(“http://snapd/v2/system-info")
pprint.pprint(response.json())

套接字是一种文件描述符。您可以读取/写入描述符。我想我没有得到你想要的。是的,非unix套接字也是描述符。但这不是一个低级实现,而是一个HTTP client.requests是一个HTTP库。如果编写适配器,则可以控制如何创建连接。这就是说,cURL似乎并不支持这一点,所以不要期望请求特意添加支持这一点的方法you@Kevin许多服务都有,例如MySQL。这是使用HTTP的服务的一小步。此外,还有一些服务器框架支持unix域套接字,例如cherrypy、flask、gunicorn。主要优势在于多用户环境中的UNIX安全模型,其中服务器进程没有特权。@Kevin考虑其他类型的服务器,例如安装有Tornado的内部本地服务器,提供可代理的外部接口,以及用于内部控制逻辑/命令的UNIX套接字接口,以防DIY,我认为子类化和添加自己的连接池更容易。只需要在后者中更改获取新连接。或者要与Docker的套接字交互(
/var/run/Docker.sock
),请使用类似http+unix://%2Fvar%2Frun%2Fdocker.sock/info的URL。顺便说一句,还有一个用于与unix域套接字交互的插件: