match TcpStream::connect(host_port) {
Ok(mut proxy_stream) => {
proxy_stream.write(req_str.as_bytes()).unwrap();
// 1、这个 buffer 应该声明多大?
let mut buffer = [0u8; 411096];
proxy_stream.read(&mut buffer).unwrap();
// 2、为什么这个返回的乱码
let proxy_res_str = String::from_utf8_lossy(&buffer);
print!("响应:{}\r\n\r\n", proxy_res_str);
}
Err(e) => {
println!("Unable to proxy: {}", e);
}
}
背景:
上面的代码,我想用 Rust 实现一个 http 代理,我建立一个 Tcp 连接,转发了客户端的请求到目标服务器,但返回的内容却是乱码,如下图
有两个问题想问:
1、用来缓存请求返回内容的 buffer 应该声明多大,可以声明成动态的吗?
2、为什么返回的网页内容是乱码?
关于 buffer 大小,这个其实可以反复读,直到读完。想保证 buffer 足够大想一次读完所有返回内容是不太可行的。
根据 header ,有不同的方式判断返回结束,当然也可能连接关闭 read 返回 Ok(0) 。比如,有的会用 Content-Length 表明返回 body 有多大,有的不用(比如你现在遇到的这个 chunked)。
看 header ,
Transfer-Encoding: chunked
,Content-Encoding: gzip
。所以这里有两件事要搞,一个是把 chunked 结构重新拼装,然后还要做 gzip 的解压,之后才能得到真正的内容。
一般 http client 都会自动把这些都处理了,所以能直接看到内容。现在你用 tcp stream 直接得到的是 tcp 上传输的内容,就得自己处理了。
作为 proxy ,一般没有任何必要把 body 的真实内容解析出来。直接透传出去就好了。Header 也许有一些内容需要修改。
如果你真的把 body 内容解析出来了再传,那么 header 里就会有更多的东西需要修改。