From 46ffbeaa6eb6aa977079dbca0e6e0fe14e72e21d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=BC=D1=98=D0=B0=D0=BD=20=D0=93=D0=B5=D0=BE?= =?UTF-8?q?=D1=80=D0=B3=D0=B8=D0=B5=D0=B2=D1=81=D0=BA=D0=B8?= Date: Wed, 4 Jul 2018 23:10:12 +0200 Subject: [PATCH] implement streaming of a folder as a tar --- src/main.rs | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 2e3a000..d4b444e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,7 @@ use futures::Stream; use std::env; use std::path::PathBuf; +use std::thread; // TODO cli args fn main() -> Result<(), Error> { @@ -72,8 +73,41 @@ fn handle_tar(req: &HttpRequest) -> Result { if !(path.is_dir()) { return Err(error::ErrorBadRequest("not a directory")); } + let (writer, stream) = MpscWriter::new(); - Ok(HttpResponse::Ok().body(format!("fixme: {:?}\n", path))) + thread::spawn(move || { + let mut a = tar::Builder::new(writer); + a.mode(tar::HeaderMode::Deterministic); + a.append_dir_all(path.clone(), path); + a.finish(); + }); + + let resp = HttpResponse::Ok() + .content_type("application/x-tar") + .streaming(stream.map_err(|_e| error::ErrorBadRequest("bad request"))); + Ok(resp) } +// TODO: see about a bounded channel, that work with tokio +struct MpscWriter { + tx: futures::sync::mpsc::UnboundedSender +} + +impl MpscWriter { + fn new() -> (Self, futures::sync::mpsc::UnboundedReceiver) { + let (tx, rx) = futures::sync::mpsc::unbounded(); + (MpscWriter{tx:tx}, rx) + } +} + +impl std::io::Write for MpscWriter { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + self.tx.unbounded_send(bytes::Bytes::from(buf)); + Ok(buf.len()) + } + + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } +}