clippy and rustfmt anoyances

This commit is contained in:
Дамјан Георгиевски 2019-09-21 16:32:15 +02:00
parent c68cf3a3e8
commit da69d3de6f
3 changed files with 103 additions and 54 deletions

View file

@ -3,28 +3,34 @@ mod web;
fn main() -> std::io::Result<()> { fn main() -> std::io::Result<()> {
let app = clap::App::new(clap::crate_name!()) let app = clap::App::new(clap::crate_name!())
.author(clap::crate_authors!("\n")) .author(clap::crate_authors!("\n"))
.version(clap::crate_version!()) .version(clap::crate_version!())
.about(clap::crate_description!()) .about(clap::crate_description!())
.arg(clap::Arg::with_name("chdir") .arg(
.short("w") clap::Arg::with_name("chdir")
.long("chdir") .short("w")
.value_name("DIRECTORY") .long("chdir")
.help("directory to serve") .value_name("DIRECTORY")
.default_value(".") .help("directory to serve")
.takes_value(true)) .default_value(".")
.arg(clap::Arg::with_name("addr") .takes_value(true),
.short("b") )
.long("bind") .arg(
.value_name("ADDRESS") clap::Arg::with_name("addr")
.help("bind address") .short("b")
.default_value("0.0.0.0") .long("bind")
.takes_value(true)) .value_name("ADDRESS")
.arg(clap::Arg::with_name("port") .help("bind address")
.value_name("PORT") .default_value("0.0.0.0")
.help("Specify alternate port") .takes_value(true),
.default_value("8000") )
.index(1)); .arg(
clap::Arg::with_name("port")
.value_name("PORT")
.help("Specify alternate port")
.default_value("8000")
.index(1),
);
let matches = app.get_matches(); let matches = app.get_matches();
let chdir = matches.value_of("chdir").unwrap(); // these shouldn't panic ever, since all have default_value let chdir = matches.value_of("chdir").unwrap(); // these shouldn't panic ever, since all have default_value
@ -32,7 +38,10 @@ fn main() -> std::io::Result<()> {
let port = matches.value_of("port").unwrap(); let port = matches.value_of("port").unwrap();
let bind_addr = format!("{}:{}", addr, port); let bind_addr = format!("{}:{}", addr, port);
std::env::set_var("RUST_LOG", std::env::var("RUST_LOG").unwrap_or("info".to_string())); std::env::set_var(
"RUST_LOG",
std::env::var("RUST_LOG").unwrap_or_else(|_| "info".to_string()),
);
env_logger::init(); env_logger::init();
let root = std::path::PathBuf::from(chdir).canonicalize()?; let root = std::path::PathBuf::from(chdir).canonicalize()?;

View file

@ -1,12 +1,11 @@
use bytes;
use futures; use futures;
use futures::Sink; use futures::Sink;
use bytes;
use tar; use tar;
use std::thread;
use std::path::PathBuf;
use std::io; use std::io;
use std::path::PathBuf;
use std::thread;
/* /*
* TODO: * TODO:
@ -17,7 +16,6 @@ type Stream = futures::sync::mpsc::Receiver<bytes::Bytes>;
type Sender = futures::sync::mpsc::Sender<bytes::Bytes>; type Sender = futures::sync::mpsc::Sender<bytes::Bytes>;
type BlockingSender = futures::sink::Wait<Sender>; type BlockingSender = futures::sink::Wait<Sender>;
pub fn stream_tar_in_thread(path: PathBuf) -> Stream { pub fn stream_tar_in_thread(path: PathBuf) -> Stream {
let (writer, stream) = StreamWriter::new(64); let (writer, stream) = StreamWriter::new(64);
@ -27,32 +25,34 @@ pub fn stream_tar_in_thread(path: PathBuf) -> Stream {
a.mode(tar::HeaderMode::Deterministic); a.mode(tar::HeaderMode::Deterministic);
a.append_dir_all(last_path_component, &path) a.append_dir_all(last_path_component, &path)
.unwrap_or_else(|e| println!("{}", e)); .unwrap_or_else(|e| println!("{}", e));
a.finish() a.finish().unwrap_or_else(|e| println!("{}", e));
.unwrap_or_else(|e| println!("{}", e));
}); });
stream stream
} }
struct StreamWriter { struct StreamWriter {
tx: BlockingSender tx: BlockingSender,
} }
impl StreamWriter { impl StreamWriter {
fn new(size: usize) -> (Self, Stream) { fn new(size: usize) -> (Self, Stream) {
let (tx, rx) = futures::sync::mpsc::channel(size); let (tx, rx) = futures::sync::mpsc::channel(size);
let tx = tx.wait(); let tx = tx.wait();
(StreamWriter{tx:tx}, rx) (StreamWriter { tx }, rx)
} }
} }
impl io::Write for StreamWriter { impl io::Write for StreamWriter {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.tx.send(bytes::Bytes::from(buf)) self.tx
.send(bytes::Bytes::from(buf))
.map(|_| buf.len()) .map(|_| buf.len())
.map_err(|e| io::Error::new(io::ErrorKind::Other, e)) .map_err(|e| io::Error::new(io::ErrorKind::Other, e))
} }
fn flush(&mut self) -> io::Result<()> { fn flush(&mut self) -> io::Result<()> {
self.tx.flush().map_err(|e| io::Error::new(io::ErrorKind::Other, e)) self.tx
.flush()
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))
} }
} }

View file

@ -1,6 +1,6 @@
use actix_web::{App, middleware, error, HttpServer, HttpRequest, HttpResponse, Responder, web};
use actix_web::dev::ServiceResponse;
use actix_files as fs; use actix_files as fs;
use actix_web::dev::ServiceResponse;
use actix_web::{error, middleware, web, App, HttpRequest, HttpResponse, HttpServer, Responder};
use futures::Stream; use futures::Stream;
use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC}; use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
use v_htmlescape::escape as escape_html_entity; use v_htmlescape::escape as escape_html_entity;
@ -10,7 +10,6 @@ use crate::threaded_archiver;
use std::fmt::Write; use std::fmt::Write;
use std::path::PathBuf; use std::path::PathBuf;
pub fn run(bind_addr: &str, root: &PathBuf) -> std::io::Result<()> { pub fn run(bind_addr: &str, root: &PathBuf) -> std::io::Result<()> {
let root = root.clone(); let root = root.clone();
HttpServer::new(move || { HttpServer::new(move || {
@ -32,49 +31,88 @@ pub fn run(bind_addr: &str, root: &PathBuf) -> std::io::Result<()> {
.run() .run()
} }
fn handle_directory(
fn handle_directory<'a, 'b>( dir: &fs::Directory,
dir: &'a fs::Directory, req: &HttpRequest,
req: &'b HttpRequest,
) -> Result<ServiceResponse, std::io::Error> { ) -> Result<ServiceResponse, std::io::Error> {
let rd = std::fs::read_dir(&dir.path)?; let rd = std::fs::read_dir(&dir.path)?;
fn optimistic_is_dir(entry: &std::fs::DirEntry) -> bool { fn optimistic_is_dir(entry: &std::fs::DirEntry) -> bool {
// consider it non directory if metadata reading fails, better than an unwrap() panic // consider it non directory if metadata reading fails, better than an unwrap() panic
entry.metadata().map(|m| m.file_type().is_dir()).unwrap_or(false) entry
.metadata()
.map(|m| m.file_type().is_dir())
.unwrap_or(false)
} }
let mut paths : Vec<_> = rd.filter_map(|entry| if dir.is_visible(&entry) { entry.ok() } else {None}).collect(); let mut paths: Vec<_> = rd
.filter_map(|entry| {
if dir.is_visible(&entry) {
entry.ok()
} else {
None
}
})
.collect();
paths.sort_by_key(|entry| (!optimistic_is_dir(entry), entry.file_name())); paths.sort_by_key(|entry| (!optimistic_is_dir(entry), entry.file_name()));
let tar_url = req.path().trim_end_matches('/'); // this is already encoded let tar_url = req.path().trim_end_matches('/'); // this is already encoded
let mut body = String::new(); let mut body = String::new();
writeln!(body, "<h1>Index of {}</h1>", req.path()).unwrap(); // FIXME: decode from url, escape for html writeln!(body, "<h1>Index of {}</h1>", req.path()).unwrap(); // FIXME: decode from url, escape for html
writeln!(body, r#"<small>[<a href="{}.tar">.tar</a> of whole directory]</small>"#, tar_url).unwrap(); writeln!(
body,
r#"<small>[<a href="{}.tar">.tar</a> of whole directory]</small>"#,
tar_url
)
.unwrap();
writeln!(body, "<table>").unwrap(); writeln!(body, "<table>").unwrap();
writeln!(body, "<tr><td>📁 <a href='../'>../</a></td><td>Size</td></tr>").unwrap(); writeln!(
body,
"<tr><td>📁 <a href='../'>../</a></td><td>Size</td></tr>"
)
.unwrap();
for entry in paths { for entry in paths {
let meta = entry.metadata()?; let meta = entry.metadata()?;
let file_url = utf8_percent_encode(&entry.file_name().to_string_lossy(), NON_ALPHANUMERIC).to_string(); let file_url =
utf8_percent_encode(&entry.file_name().to_string_lossy(), NON_ALPHANUMERIC).to_string();
let file_name = escape_html_entity(&entry.file_name().to_string_lossy()).to_string(); let file_name = escape_html_entity(&entry.file_name().to_string_lossy()).to_string();
let size = meta.len(); let size = meta.len();
write!(body, "<tr>").unwrap(); write!(body, "<tr>").unwrap();
if meta.file_type().is_dir() { if meta.file_type().is_dir() {
writeln!(body, r#"<td>📂 <a href="{}/">{}/</a></td>"#, file_url, file_name).unwrap(); writeln!(
write!(body, r#" <td><small>[<a href="{}.tar">.tar</a>]</small></td>"#, file_url).unwrap(); body,
r#"<td>📂 <a href="{}/">{}/</a></td>"#,
file_url, file_name
)
.unwrap();
write!(
body,
r#" <td><small>[<a href="{}.tar">.tar</a>]</small></td>"#,
file_url
)
.unwrap();
} else { } else {
writeln!(body, r#"<td>🗎 <a href="{}">{}</a></td>"#, file_url, file_name).unwrap(); writeln!(
body,
r#"<td>🗎 <a href="{}">{}</a></td>"#,
file_url, file_name
)
.unwrap();
write!(body, " <td>{}</td>", size).unwrap(); write!(body, " <td>{}</td>", size).unwrap();
} }
writeln!(body, "</tr>").unwrap(); writeln!(body, "</tr>").unwrap();
} }
writeln!(body, "</table>").unwrap(); writeln!(body, "</table>").unwrap();
writeln!(body, r#"<footer><a href="{}">{} {}</a></footer>"#, writeln!(
env!("CARGO_PKG_HOMEPAGE"), env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION")).unwrap(); body,
r#"<footer><a href="{}">{} {}</a></footer>"#,
env!("CARGO_PKG_HOMEPAGE"),
env!("CARGO_PKG_NAME"),
env!("CARGO_PKG_VERSION")
)
.unwrap();
let mut html = String::new(); let mut html = String::new();
writeln!(html, "<!DOCTYPE html>").unwrap(); writeln!(html, "<!DOCTYPE html>").unwrap();
@ -85,7 +123,9 @@ fn handle_directory<'a, 'b>(
writeln!(html, "<body>\n{}</body>", body).unwrap(); writeln!(html, "<body>\n{}</body>", body).unwrap();
writeln!(html, "</html>").unwrap(); writeln!(html, "</html>").unwrap();
let resp = HttpResponse::Ok().content_type("text/html; charset=utf-8").body(html); let resp = HttpResponse::Ok()
.content_type("text/html; charset=utf-8")
.body(html);
Ok(ServiceResponse::new(req.clone(), resp)) Ok(ServiceResponse::new(req.clone(), resp))
} }