summaryrefslogtreecommitdiff
path: root/src/action_meta.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/action_meta.rs')
-rw-r--r--src/action_meta.rs32
1 files changed, 18 insertions, 14 deletions
diff --git a/src/action_meta.rs b/src/action_meta.rs
index 4e31e1b..9763ede 100644
--- a/src/action_meta.rs
+++ b/src/action_meta.rs
@@ -1,5 +1,8 @@
use std::io::Read;
use std::time::Instant;
+use std::convert::TryFrom;
+use bendy::decoding::FromBencode;
+use chifs_common::Hash;
use crate::httpclient::{Client,Error};
use crate::config::Config;
@@ -10,7 +13,7 @@ const MAXMETALEN : u64 = 1024*1024;
const MAXPACKSLEN : u64 = 64*1024*1024; // 64 MiB is 2 million pack files. Ought to be enough, right?
-fn fetch_meta(conn: &Client) -> Result<(Option<String>,Option<String>,Vec<u8>), Error> {
+fn fetch_meta(conn: &Client) -> Result<(Option<String>,Option<String>,Hash), Error> {
let t_start = Instant::now();
conn.get("/.chifs-share/meta")?;
@@ -37,7 +40,7 @@ fn fetch_meta(conn: &Client) -> Result<(Option<String>,Option<String>,Vec<u8>),
match k {
b"title" => title = Some(String::from_utf8(v.try_into_bytes()?.to_vec()).map_err(|_| Error::Custom("Invalid UTF-8 in title field".to_string()))?),
b"contact" => contact = Some(String::from_utf8(v.try_into_bytes()?.to_vec()).map_err(|_| Error::Custom("Invalid UTF-8 in contact field".to_string()))?),
- b"blake3.packs" => packs = Some(v.try_into_bytes()?.to_vec()),
+ b"blake3.packs" => packs = Some(Hash::decode_bencode_object(v)?),
_ => ()
}
}
@@ -47,7 +50,7 @@ fn fetch_meta(conn: &Client) -> Result<(Option<String>,Option<String>,Vec<u8>),
}
-fn fetch_packs(conn: &Client, blake3: &[u8], buf: &mut Vec<u8>) -> Result<(), Error> {
+fn fetch_packs(conn: &Client, blake3: &Hash, buf: &mut Vec<u8>) -> Result<(), Error> {
let t_start = Instant::now();
conn.get("/.chifs-share/blake3.packs")?;
let res = conn.recv(MAXPACKSLEN)?;
@@ -60,21 +63,21 @@ fn fetch_packs(conn: &Client, blake3: &[u8], buf: &mut Vec<u8>) -> Result<(), Er
if buf.len() % 32 != 0 {
return Err(Error::Custom("blake3.packs size is not a multiple of 32".to_string()));
}
- if blake3::hash(&buf[..]).as_bytes() != blake3 {
+ if &Hash::hash_buf(&buf[..]) != blake3 {
return Err(Error::Custom("blake3.packs does not match the blake3 hash indicated in the metadata".to_string()));
}
Ok(())
}
-fn update(conf: &Config, db: &Pool, shareid: i32, addr: &str, blake3: Option<&[u8]>) -> Result<(), Error> {
+fn update(conf: &Config, db: &Pool, shareid: i32, addr: &str, blake3: Option<Hash>) -> Result<(), Error> {
let conn = Client::socks_connect(&conf.tor_address, addr)?;
let (title, contact, new_blake3) = fetch_meta(&conn)?;
let mut packs : Vec<u8> = Vec::new();
- if blake3 != Some(&new_blake3[..]) {
- if db.get().query_one("SELECT 1 FROM pack_indices WHERE blake3 = $1::bytea::hash256 LIMIT 1", &[&new_blake3]).is_err() {
- fetch_packs(&conn, &new_blake3[..], &mut packs)?;
+ if blake3 != Some(new_blake3) {
+ if db.get().query_one("SELECT 1 FROM pack_indices WHERE blake3 = $1 LIMIT 1", &[&new_blake3]).is_err() {
+ fetch_packs(&conn, &new_blake3, &mut packs)?;
}
}
@@ -83,9 +86,10 @@ fn update(conf: &Config, db: &Pool, shareid: i32, addr: &str, blake3: Option<&[u
let t_ins = Instant::now();
if !packs.is_empty() {
- let q_ind = txn.prepare("INSERT INTO pack_indices (blake3, pack) VALUES ($1::bytea::hash256, $2::bytea::hash256) ON CONFLICT (blake3, pack) DO NOTHING").unwrap();
- let q_packs = txn.prepare("INSERT INTO packs (pack) VALUES ($1::bytea::hash256) ON CONFLICT (pack) DO NOTHING").unwrap();
+ let q_ind = txn.prepare("INSERT INTO pack_indices (blake3, pack) VALUES ($1, $2) ON CONFLICT (blake3, pack) DO NOTHING").unwrap();
+ let q_packs = txn.prepare("INSERT INTO packs (pack) VALUES ($1) ON CONFLICT (pack) DO NOTHING").unwrap();
for p in packs.chunks_exact(32) {
+ let p = Hash::try_from(p).unwrap();
txn.execute(&q_ind, &[&new_blake3, &p]).unwrap();
txn.execute(&q_packs, &[&p]).unwrap();
}
@@ -93,16 +97,16 @@ fn update(conf: &Config, db: &Pool, shareid: i32, addr: &str, blake3: Option<&[u
let t_upd = Instant::now();
txn.execute(
- "UPDATE shares SET title = $1, contact = $2, blake3_packs = $3::bytea::hash256 WHERE id = $4 AND (title,contact,blake3_packs) IS DISTINCT FROM ($1,$2,$3::bytea::hash256)",
+ "UPDATE shares SET title = $1, contact = $2, blake3_packs = $3 WHERE id = $4 AND (title,contact,blake3_packs) IS DISTINCT FROM ($1,$2,$3)",
&[&title, &contact, &new_blake3, &shareid]
).unwrap();
let t_del = Instant::now();
- if blake3 != Some(&new_blake3[..]) {
+ if blake3 != Some(new_blake3) {
// Delete unreferenced pack_indices, packs and files. The latter is done automatically as
// part of an ON DELETE foreign key reference.
txn.execute("
- WITH del(blake3) AS (SELECT $1::bytea::hash256 WHERE NOT EXISTS(SELECT 1 FROM shares WHERE blake3_packs = $1::bytea::hash256))
+ WITH del(blake3) AS (SELECT $1::hash256 WHERE NOT EXISTS(SELECT 1 FROM shares WHERE blake3_packs = $1))
, x AS (
DELETE FROM packs
WHERE pack IN(SELECT pack FROM pack_indices WHERE blake3 IN(SELECT blake3 FROM del))
@@ -125,7 +129,7 @@ fn update(conf: &Config, db: &Pool, shareid: i32, addr: &str, blake3: Option<&[u
}
-pub fn run(conf: &Config, db: Pool, shareid: i32, addr: &str, blake3: Option<&[u8]>) {
+pub fn run(conf: &Config, db: Pool, shareid: i32, addr: &str, blake3: Option<Hash>) {
debug!("Fetching Meta for share {} ({})", shareid, addr);
share_log::Action::Meta.run(db.clone(), shareid, |_| update(conf, &db, shareid, addr, blake3));
}