web 框架用的是 actix-web, sftp 访问用的是 ssh2, 以下测试代码, 调接口后 sftp 的文件加载到内存完成后才能开始下载。
想实现 sftp 的文件不用加载到内存和下载到本地服务器,调用 web 接口可以马上下载的效果
#[get("/")]
async fn file_download() -> HttpResponse{
let tcp = TcpStream::connect("1.2.3.4:22").unwrap();
let mut sess = Session::new().unwrap();
sess.set_tcp_stream(tcp);
sess.handshake().unwrap();
sess.userauth_password("root", "abcde").unwrap();
let file_path = "/root/gg.zip";
let (mut remote_file, _stat) = sess.scp_recv(Path::new(file_path)).unwrap();
let (tx, rx) = local_channel::mpsc::channel::<Result<Bytes, Error>>();
actix_web::rt::spawn(async move {
let mut buffer = [0; 100];
loop {
if !remote_file.eof() {
if let Ok(_n) = remote_file.read(&mut buffer[..]) {
let data = Vec::from(buffer);
tx.send(Ok(Bytes::from(data))).unwrap();
} else {
break
}
} else {
break
}
}
});
HttpResponse::Ok()
.set_header(actix_web::http::header::CONTENT_DISPOSITION, format!("attachment; filename={}", file_path.split("/").last().unwrap()))
.streaming(rx)
}
如果换做用 go, 用 io.copy 就能实现
c.Writer.WriteHeader( http.StatusOK)
c.Header("Content-Disposition", "attachment; filename=gg.txt")
_, _ = io.Copy(c.Writer, sftpFile)
rust 这方面资料实在太少(连搜索英文都搜不到什么),rust 也有 io::copy 但不知道怎么绑定到 httpresponse, 希望有经验人士能解答下,即使换 web 框架都可以(不用 actix-web)
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.