Method, StatusCode, Uri,
};
use serde::Serialize;
+use sha2::{Digest, Sha256};
use std::borrow::Cow;
use std::cmp::Ordering;
use std::collections::HashMap;
} else if query_params.contains_key("view") {
self.handle_edit_file(path, DataKind::View, head_only, user, &mut res)
.await?;
+ } else if query_params.contains_key("hash") {
+ self.handle_hash_file(path, head_only, &mut res).await?;
} else {
self.handle_send_file(path, headers, head_only, &mut res)
.await?;
Ok(())
}
+ async fn handle_hash_file(
+ &self,
+ path: &Path,
+ head_only: bool,
+ res: &mut Response,
+ ) -> Result<()> {
+ let output = sha256_file(path).await?;
+ res.headers_mut()
+ .typed_insert(ContentType::from(mime_guess::mime::TEXT_HTML_UTF_8));
+ res.headers_mut()
+ .typed_insert(ContentLength(output.as_bytes().len() as u64));
+ if head_only {
+ return Ok(());
+ }
+ *res.body_mut() = body_full(output);
+ Ok(())
+ }
+
async fn handle_propfind_dir(
&self,
path: &Path,
let (start, _) = parse_range(value, size).ok_or_else(err)?;
Ok(Some(start))
}
+
+async fn sha256_file(path: &Path) -> Result<String> {
+ let mut file = fs::File::open(path).await?;
+ let mut hasher = Sha256::new();
+ let mut buffer = [0u8; 8192];
+
+ loop {
+ let bytes_read = file.read(&mut buffer).await?;
+ if bytes_read == 0 {
+ break;
+ }
+ hasher.update(&buffer[..bytes_read]);
+ }
+
+ let result = hasher.finalize();
+ Ok(format!("{:x}", result))
+}
Ok(())
}
+#[rstest]
+fn hash_file(server: TestServer) -> Result<(), Error> {
+ let resp = reqwest::blocking::get(format!("{}index.html?hash", server.url()))?;
+ assert_eq!(
+ resp.headers().get("content-type").unwrap(),
+ "text/html; charset=utf-8"
+ );
+ assert_eq!(resp.status(), 200);
+ assert_eq!(
+ resp.text()?,
+ "c8dd395e3202674b9512f7b7f956e0d96a8ba8f572e785b0d5413ab83766dbc4"
+ );
+ Ok(())
+}
+
#[rstest]
fn get_file_404(server: TestServer) -> Result<(), Error> {
let resp = reqwest::blocking::get(format!("{}404", server.url()))?;