commit f23ac0aba3e6caacf4541ca1ffb952a1c149c253
parent 000292e482d8c174a165e588a42976eef497c9c7
Author: lash <dev@holbrook.no>
Date: Tue, 21 Jun 2022 10:07:13 +0000
Factor out immutable put
Diffstat:
M | src/main.rs | | | 87 | ++++++++++++++++++++++++++++++++++++------------------------------------------- |
M | src/mutable.rs | | | 52 | ---------------------------------------------------- |
2 files changed, 40 insertions(+), 99 deletions(-)
diff --git a/src/main.rs b/src/main.rs
@@ -9,20 +9,23 @@ use tiny_http::{
use std::net::{Ipv4Addr, SocketAddrV4};
use std::str::FromStr;
use std::path::{PathBuf, Path};
-use std::fs::copy as fs_copy;
use std::fs::File;
-use std::io::Write;
-use sha2::{Sha256, Digest};
+use std::fmt::Error;
use env_logger;
mod auth;
-mod mutable;
+mod record;
use auth::{
AuthSpec,
AuthResult,
};
+use record::{
+ put_immutable,
+ RequestError,
+ RequestErrorType,
+};
use log::{debug, info, error};
@@ -58,6 +61,32 @@ fn exec_auth(auth_spec: AuthSpec) -> Option<AuthResult> {
}
+fn exec_error(e: RequestError, req: Request) {
+ let res_status: StatusCode;
+ match e.typ {
+ RequestErrorType::WriteError => {
+ res_status = StatusCode(500);
+ },
+ RequestErrorType::AuthError => {
+ res_status = StatusCode(403);
+ },
+ RequestErrorType::FormatError => {
+ res_status = StatusCode(400);
+ },
+ _ => {
+ res_status = StatusCode(500);
+ },
+ }
+ match e.v {
+ Some(v) => {
+ req.respond(Response::from_string(v));
+ },
+ None => {
+ req.respond(Response::empty(res_status));
+ }
+ }
+}
+
fn main() {
env_logger::init();
@@ -198,52 +227,16 @@ fn main() {
},
};
- let tempfile = match NamedTempFile::new() {
- Ok(of) => {
- debug!("writing to tempfile {:?} expected size {}", of.path(), expected_size);
-
- let f = req.as_reader();
- let mut buf: [u8; 65535] = [0; 65535];
- let mut h = Sha256::new();
- loop {
- match f.read(&mut buf[..]) {
- Ok(v) => {
- if v == 0 {
- break;
- }
- total_size += v;
- let data = &buf[..v];
- h.update(data);
- of.as_file().write(data);
- },
- Err(e) => {
- error!("cannot read from request body: {}", e);
- break;
- },
- }
- }
-
- if expected_size != total_size {
- res_status = StatusCode(400);
- let mut res = Response::empty(res_status);
- req.respond(res);
- continue;
- }
- let z = h.finalize();
- hash = hex::encode(z);
- info!("have hash {} for content", hash);
- of
+ let f = req.as_reader();
+ match put_immutable(&path, f, expected_size) {
+ Ok(v) => {
+ hash = hex::encode(v);
},
Err(e) => {
- res_status = StatusCode(500);
- let mut res = Response::empty(res_status);
- req.respond(res);
+ exec_error(e, req);
continue;
- }
- };
-
- let final_path = path.join(&hash);
- fs_copy(tempfile.path(), final_path.as_path());
+ },
+ }
res_status = StatusCode(200);
let mut res = Response::from_string(hash);
diff --git a/src/mutable.rs b/src/mutable.rs
@@ -1,53 +1 @@
-use std::str::FromStr;
-use std::convert::Infallible;
-use sha2::{Sha256, Digest};
-
-use crate::auth::AuthResult;
-
-pub struct ResourceKey {
- v: Vec<u8>,
-}
-
-impl FromStr for ResourceKey {
- type Err = Infallible;
-
- fn from_str(s: &str) -> Result<ResourceKey, Infallible> {
- let mut h = Sha256::new();
- h.update(&s[..]);
- let k = ResourceKey{
- v: h.finalize().to_vec(),
- };
- Ok(k)
- }
-}
-
-impl ResourceKey {
- pub fn pointer_for(&self, subject: &AuthResult) -> Vec<u8> {
- let mut h = Sha256::new();
- h.update(&self.v);
- h.update(&subject.identity);
- h.finalize().to_vec()
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::ResourceKey;
- use super::AuthResult;
- use hex;
-
- #[test]
- fn test_pointer() {
- let resource = ResourceKey{
- v: vec!(0x66, 0x6f, 0x6f),
- };
- let subject = AuthResult{
- identity: vec!(0x62, 0x61, 0x72),
- };
- let r = resource.pointer_for(&subject);
-
- let foobar_digest = hex::decode("c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2").unwrap();
- assert_eq!(r, foobar_digest);
- }
-}