diff --git a/proj-2/balancebeam/Cargo.toml b/proj-2/balancebeam/Cargo.toml index dee4b57..2766fbf 100644 --- a/proj-2/balancebeam/Cargo.toml +++ b/proj-2/balancebeam/Cargo.toml @@ -20,6 +20,6 @@ parking_lot = "0.12.1" [dev-dependencies] nix = "0.26.2" -hyper = "0.14.24" +hyper = { version = "0.14", features = ["full"] } reqwest = "0.11.14" async-trait = "0.1.66" diff --git a/proj-2/balancebeam/implement_notes.md b/proj-2/balancebeam/implement_notes.md new file mode 100644 index 0000000..a10e8d4 --- /dev/null +++ b/proj-2/balancebeam/implement_notes.md @@ -0,0 +1,28 @@ +# Project-2 Balancebeam 实现记录 + +## 综述 + +这东西本质上是一个类似于反向代理之类的东西, + +## 每个 Milestone 的说明 + +### Milestone 0 + +依然是传统的看代码环节。 + +首先是 `main.rs` 里面的东西。 +1. `CmdOption` 用的是 `clap` 这个 crate,用非常奇葩的 macro 语法来定义命令行参数并解析。 +2. `ProxyState` 是执行线程的共享参数,不知道有啥特别的意义,可能是为后面的东西预留的 +3. `TCPListener` 是标准库提供的东西,提供了一个简单的 TCP server。它通过 `incoming` 迭代器来返回构造的 TCP stream 抽象,这种字节流抽象最终会被分发给执行线程。 +4. 执行线程: + 1. 首先,它随机选择一个上游服务器并打开与该服务器的连接。如果服务器无了,返回502。 + 2. 然后循环从客户端读取请求,客户端可以在一个连接上发送任何数量的请求,而 `balancebeam` 会将每个请求转发到上游服务器。如果客户端发送了一个错误的请求,会有一些错误处理。 + 3. 一旦请求被读取,`balancebeam` 就会添加一个 `X-Forwarded-For HTTP` 头,以便上游服务器能够知道客户端的IP地址。(这对理解并不特别重要;它只是一个事实上的标准头。) + 4. 接下来,`balancebeam` 将请求转发给上游服务器。如果在传输请求时有错误,它就会通知客户端。 + 5. 接下来,`balancebeam` 试图从上游服务器读取响应。如果响应被破坏或在接收时有其他问题,它将通知客户端。 + 6. 最后,`balancebeam` 将响应转发给客户。 + +然后是封装库 `request.rs` `response.rs`,就像 project 1 里面的 gimili wrapper 一样,又臭又长。分别用来基于 TCP 字节流来处理 HTTP 请求和响应。分别提供了 `read_from_stream` 和 `write_to_stream` 这两个接口供 main 处理两个 TCP 链接( Client HTTP req -> Proxy HTTP req -> Server, Server HTTP resp -> Proxy HTTP resp -> Client)。 + + +## 附加任务? \ No newline at end of file