curio 的 http 库 asks 代码解析
asks 是 Python 的异步框架 curio 中的 一个 http 库。
init.py
init 函数,初始化 curio 或者 trio 库
auth.py
auth 相关函数
base_funcs.py
asks.request 函数,创建一个session,然后做请求,之后再丢弃掉这个session
cookie_utils.py
CookieTracker类
对外的方法主要有两个 get_additional_cookies 用于获取域名对应的cookie,_store_cookies 用于添加cookie
errors.py 抛出的异常的类
req_structs.py
SocketQ
这是一个 socket 的连接池。
使用一个deque作为存储,实际上相当于又模拟了一个字典{netloc => socket}(思考:为什么不使用OrderedDict呢?) 是deque的子类。index返回指定hostloc对应的index。pull弹出指定index的socket。__contains__遍历看是否包含对应的socket
CaseIncesitiveDict 对大小写不敏感的词典
request.py
Request 类
make_request 方法。hconnection定义和使用的地方相距太远了。cookie的生成应该使用join。之后调用_request_io 发送请求
_request_io 调用 首先掉用_send, 然后调用_catch_response
_catch_response 调用recv_event
_recv_event 不断调用 _async_lib.recv(self.sock, 10000) 从而不断产生数据,知道读完为之
session 类
request 调用 grab_connection 获取一个socket,然后把这个socket交给Request对象 grab_connection 调用 checkout_connection 获得一个socket或者,调用make_connection产生一个新的socket,注意其中有一个奇怪的 await sleep(0),可能意思是把循环交回给event loop
make_connection 调用_connect 方法,并把host和port作为属性写到socket上
session 中有两个SocketQ的类,conn_pool, checked_out_sockets 分别用来保存已连接未使用的socket和正在使用中的socket
Asks 的连接池
如果使用代理的话
curio 的网络通信
首先,需要引入curio.socket 而不是使用内置的socket TCP通信,使用sock.bind/listen/accept等建立服务器,使用recv和sendall发送接收消息 UDP通信,使用recvfrom和sendto函数通信
作为客户端使用curio.open_connection 打开到服务器的链接,其中ssl=True打开的是HTTPS连接诶
对于其他要使用ssl的情况,应该使用curio.ssl而不是标准库的ssl
curio.network.
ssl.wrap_socket 不支持server_hostname sslcontext.wrap_socket 支持
不要把 proxies 传递给request 对象