Rust TcpStream 连接返回乱码

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 连接,转发了客户端的请求到目标服务器,但返回的内容却是乱码,如下图

image.png

有两个问题想问:
1、用来缓存请求返回内容的 buffer 应该声明多大,可以声明成动态的吗?
2、为什么返回的网页内容是乱码?

阅读 2.9k
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 里就会有更多的东西需要修改。

开了 gzip 压缩,需要解压

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题