2

How to implement actix-web response to send file data stream, I want to send it to http response body by decompressing zip file

use zip;
use std::fs::File;
use std::io::prelude::*;
use encoding_rs::Encoder;
use std::str;
use actix_web::{web, App, HttpRequest, HttpServer, Responder, HttpResponse};
use urlencoding::{decode};
use std::sync::Mutex;
use futures::stream::{Stream};

struct MyData {
    zip: zip::ZipArchive<File>,
}

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
    let paz_file = File::open("D:/test.zip").unwrap();
    let mut paz = zip::ZipArchive::new(paz_file).unwrap(); 
    let data = web::Data::new(Mutex::new(MyData { zip: paz }));
    HttpServer::new(move || {
        App::new()
        .app_data(data.clone())
        .route("/static/**", web::get().to(handle_res))
    })
    .bind("127.0.0.1:21607")?
    .run()
    .await?;
    Ok(())
}

async fn handle_res(data: web::Data<Mutex<MyData>>, req: HttpRequest) -> impl Responder {
    let mut data = data.lock().unwrap();
    let paths = req.path().to_string();
    let mut file_path = paths.replace("/static/", "");
    file_path = decode(&file_path).unwrap();
    {
        let mut zip_file = data.zip.by_name(&file_path);
        match zip_file {
            Ok(mut f) => {
                return HttpResponse::Ok()
                //.header("content-type", "text/plain;charset=utf-8")
                .streaming(f.bytes());
            },
            Err(e) => {
                println!("{}", e.to_string());
                return HttpResponse::NotFound().body("File Not Found");
            }
        }
    }
}
Error: 
the trait bound `std::io::Bytes<zip::read::ZipFile<'_>>: futures_core::stream::Stream` is not satisfied
      .streaming(f.bytes());
    | ^^^^^^^^^^ the trait `futures_core::stream::Stream` is not implemented for `std::io::Bytes<zip::read::ZipFile<'_>>`
Peter Hall
  • 53,120
  • 14
  • 139
  • 204
ProJin
  • 101
  • 3
  • 9
  • 1
    It would be helpful to state what exactly isn't working with the code you posted – madlaina Jul 14 '20 at 09:56
  • Sorry, I have corrected and completed the demo code – ProJin Jul 15 '20 at 09:21
  • Are you expecting to be able to decompress the file in a streaming fashion, or decompress it first and then stream that? – Peter Hall Jul 15 '20 at 11:43
  • @Peter Hall .I want to decompress the stream and transmit it to the client – ProJin Jul 15 '20 at 11:52
  • You want to decompress the stream _**and then**_ transmit it, or transmit decompressed bytes _**as they become available**_? – Peter Hall Jul 15 '20 at 11:54
  • @PeterHall: Realize transport stream while decompressing – ProJin Jul 15 '20 at 12:03
  • The `zip` crate does not appear to support that. There may be other crates that do (e.g. I found [this crate](https://docs.rs/tokio-tar/0.2.0/tokio_tar/) which can stream-decompress tar files.) – Peter Hall Jul 15 '20 at 12:13
  • @PeterHall: I think the tar format can also help me, but I don’t know how to implement it in the stream to the http client – ProJin Jul 15 '20 at 12:20

0 Answers0