PySocks 的默认值不会改变 ftplib 的路由
与其假定 set_default_proxy 会替换 Python 原生 socket 实现,不如追踪 ftplib 实际创建的 socket。
socks.set_default_proxy() 只为之后创建的 PySocks socksocket 对象保存默认值。它不会替换 Python 的原生 socket 类。因此,仅仅因为在连接 FTP 之前调用了它,并不会让 ftplib 改走代理。
要看住构造函数,而不是保存代理 URL 的那个变量。ftplib 会建立一个控制连接,并另外建立传输连接。在被动 FTP 下,登录成功只证明控制连接可用;用于列目录或传输文件的数据 socket 同样需要走预期的路由。
替换 socket.socket 或包裹模块的做法,做的事已经超出了设置 PySocks 默认值。它可能影响共用该模块的其他库。事后再恢复原样,并不能让并发连接与这次改动隔离开。
自建 ftplib 子类可以覆盖连接路径,但复制来的内部实现带着它来源 Python 版本的假设,包括超时哨兵值和协议处理。标准库更新不会更新那份副本。
针对所需的代理和 FTP 模式,选择仍在维护的客户端或受支持的集成方式。用 PycURL 进行被动 FTP 下载的示例展示了另一条客户端路径。如果是应用自有的定制,先确认每个控制 socket 和数据 socket 由哪个构造函数打开,并保留它所替换的上游行为。只有当这些构造函数真正读取代理值时,正确的代理值才起作用。