Squid Web Cache Wiki

Squid Web Cache 文档

🔗 内部子系统交互的愿望清单

这是对squid各部分在多种用例中**应**如何交互的尝试性文档。

:warning: 当前为草稿,请谨慎阅读

🔗 指导原则

🔗 通用所有权说明(仍为草稿)

🔗 用例

🔗 无法解析的请求

在此示例中,Socket是指代表单个操作系统Socket的对象 - 在unix上是fd,在windows上是HANDLE。

HttpClientConnection 指的是单个 HttpClientConnection 对象

  1. 操作系统报告新的套接字可用。
    • 通信层构建Socket对象。
    • 通信层持有Socket的 RefCountReference (通信层在此代表操作系统) - 在通知操作系统等之前,它不能被释放。
    • Socket持有通信层的 CallbackReference 以通知其关闭。
  2. 新的Socket被传递给接收到它的端口的监听工厂。
    • 工厂构建 HttpClientConnection 以在协议层表示Socket。
    • 工厂调用 Socket.setClient(HttpClientConnection)
    • Socket持有 HttpClientConnection (它继承自 SocketClient)的 RefCountReference
    • HttpClientConnection 持有Socket的 CallbackReference
  3. HttpClientConnection 对Socket调用read()。
    • 对于某些系统,读取现在被安排在套接字上。对于其他系统,当下一个事件循环发生时,读取将完成。
    • Socket获得了分发器的 RefCount 引用。
  4. Socket请求从操作系统读取(如果尚未安排)。
  5. 读取完成。
    • Socket将 HttpClientConnection 和读取结果交给分发器。
    • 分发器持有 HttpClientConnectionCallbackReference
  6. 分发器回调 HttpClientConnection
    • HttpClientConnection 无法解析请求。
  7. HttpClientConnection 调用Socket的write()以发送错误页面。
    • 根据套接字逻辑,写入可能立即发出,或者可能等待下一个事件循环。
    • Socket获得了分发器的 RefCountReference
  8. Socket向操作系统发出写入请求(如果未立即发出)。
  9. 写入完成。
    • Socket将 HttpClientConnection 和写入结果交给分发器。
    • 分发器持有 HttpClientConnectionCallbackReference
  10. 分发器以写入状态回调 HttpClientConnection
    • 分发器放弃其对 HttpClientConnectionCallbackReference
  11. HttpClientConnection 调用Socket的clean_close()。
    • Socket检查是否有待处理的读取或写入。
  12. Socket调用shutdown(SD_SEND)到操作系统。
    • Socket调用 HttpClientConnection 的 `socket_detached`,通知它已被释放。
    • Socket放弃其对 HttpClientConnectionCallbackReference
  13. HttpClientConnection 没有持有对其的 RefCountReferences,因此被释放。
  14. Socket调用setClient,使用 LingerCloseSocketClient 来设置自己。
    • Socket持有 LingerCloseSocketClientRefCountReference
  15. LingerCloseSocketClient 调用socket的read()以检测EOF。
    • socket现在向操作系统安排读取。
  16. LingerCloseSocketClient 注册了一个回调,时间为现在 + LINGERDELAY。
    • EventScheduler 持有 LingerCloseSocketClient 和分发器的 CallbackReference
  17. 或者Socket现在可以安排读取到操作系统,在下一个事件循环中。

情况1:先读取到EOF (远端已确认关闭)

  1. 读取完成。
    • Socket标记其读取通道为已关闭。
    • Socket将 LingerCloseSocketClient 和读取结果交给分发器。
    • 分发器持有 LingerSocketClientCallbackReference
  2. 分发器将读取结果交给 LingerSocketClient
    • LingerSocketClient 看到已达到EOF。
  3. LingerSocket 调用Socket的close()。
    • Socket执行sd_shutdown(SD_BOTH)和close(fd)。
  4. Socket回调通信层回调,通知其已完成。
    • 通信层放弃其对socket的 RefCountReference
  5. Socket因没有引用而释放。
    • Socket调用 LingerSocketClient 的 `socket_detached`。
  6. LingerSocketClient 因没有引用而释放。

情况2:Linger超时发生。

  1. EventSchedulerLingerSocketClient 放入分发队列。
    • 分发器持有 LingerSocketClientCallbackReference
    • EventScheduler 放弃其对 LingerSocketClientCallbackReference
  2. 分发器向 LingerSocketClient 触发事件。
    • 分发器放弃对 LingerSocketClientCallbackReference
  3. LingerSocketClient 调用socket.force_close()。
    • Socket执行sd_shutdown(SD_BOTH)和close(fd)。
  4. Socket回调通信层回调,通知其已完成。
    • 通信层放弃其对socket的 RefCountReference
  5. Socket因没有引用而释放。
    • Socket调用 LingerSocketClient 的 `socket_detached`。
  6. LingerSocketClient 因没有引用而释放。

🔗 内部请求

  1. 监听套接字工厂为已打开的套接字创建一个 SocketClient 对象。
    • Socket通过 RefCount 拥有 SocketClient
    • Socket由通信层拥有。如果是基于FD的,它在一个表中。如果是基于HANDLE的,它被放入一个已打开套接字集合中。
    • SocketClient 对Socket有一个弱引用:新的Client拥有socket。没有人拥有Client。Socket对Client有回调,用于通知事件:ReadPossible (数据已到达),Close (因请求或外部事件)。其他事件在排队时得到回调 - 要求socket读取并将回调传递给它。这可以是“this”,如果我们的API结构良好,也可以是其他东西。

      :x: 需要更多细节/仔细处理。

  2. Client使用其原生协议将URL解析为一个规范化的请求:HTTPClient 将使用HTTP规则解析URL,FTP客户端将执行FTP代理操作以获取目标服务器等。这会创建一个新对象来处理该单个请求 - ClientRequestSocketClientClientRequest 中注册自身,此时 ClientRequest 可能会从核心启动其请求:Socket有对 SocketClient 的回调,SocketClient 拥有Socket,并拥有其创建的 ClientRequest
  3. SocketClient 调用 ClientRequest.atReadFront() 来指示 ClientRequest 现在位于套接字的队列前端,并且如果它想读取正文数据,就可以开始读取。Socket有对 SocketClient 的回调,SocketClient 拥有Socket,并拥有其创建的 ClientRequestClientRequest 有一个对 SocketClient 的回调句柄。
  4. ClientRequest 调用 SocketClient.finishedReadingRequest() 来指示它将不再从 SocketClient 读取任何数据,并且下一个请求可以被解析。
  5. SocketClient 调用 ClientRequest.atWriteFront() 来指示 ClientRequest 现在位于套接字的队列前端。ClientRequestSocketClient 有回调,用于处理事件:WillNotReadAnyMoreSocketMustBeClosedSocketMustBeReset。Socket有对 SocketClient 的回调,SocketClient 拥有Socket,并拥有其创建的 ClientRequestClientRequest 有对 SocketClient 的回调,用于处理事件:WillNotReadAnyMoreSocketMustBeClosedSocketMustBeReset,并且
  6. ClientRequest 请求squid核心的URL映射器对该规范化请求的响应。Socket有对 SocketClient 的回调,SocketClient 拥有Socket,并拥有其创建的 ClientRequestClientRequest 有对 SocketClient 的回调,用于处理事件:WillNotReadAnyMoreSocketMustBeClosedSocketMustBeReset
  7. URL映射器根据协议或URL路径确定请求是针对内部资源的。
  8. 请求被转发到内部资源以满足。一个对象被提供给Client,该对象代表数据“源” - 它上面有方法允许请求响应头,拉取数据流,以及取消客户端的请求。
  9. 内部资源对象被客户端调用以启动传输,然后它交付内部头信息和内部生成的数据。
  10. 内部资源在最后一次请求读取数据时向客户端发出文件结束信号。
  11. 客户端。

🔗 不可缓存请求

🔗 隧道请求

🔗 可缓存请求

导航:网站搜索网站页面类别🔼 向上