added serializer for database. removed unused code.
This commit is contained in:
parent
f356201323
commit
703dfbb57d
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1447,6 +1447,7 @@ dependencies = [
|
|||
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"toml 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
|
|
@ -18,3 +18,4 @@ clap = "2.32.0"
|
|||
log = "0.4.5"
|
||||
fern = "0.5.6"
|
||||
num_cpus = "1.8.0"
|
||||
serde_json = "1.0.32"
|
||||
|
|
|
@ -10,12 +10,12 @@ extern crate toml;
|
|||
#[macro_use] extern crate log;
|
||||
extern crate fern;
|
||||
extern crate num_cpus;
|
||||
extern crate serde_json;
|
||||
|
||||
mod server;
|
||||
mod tracker;
|
||||
mod stackvec;
|
||||
mod webserver;
|
||||
mod service;
|
||||
mod config;
|
||||
|
||||
use std::process::exit;
|
||||
|
|
118
src/tracker.rs
118
src/tracker.rs
|
@ -1,4 +1,6 @@
|
|||
use std;
|
||||
use binascii;
|
||||
use serde::{self, Serialize, Deserialize};
|
||||
|
||||
use server::Events;
|
||||
|
||||
|
@ -30,69 +32,16 @@ struct TorrentPeer {
|
|||
pub type PeerId = [u8; 20];
|
||||
pub type InfoHash = [u8; 20];
|
||||
|
||||
pub trait HexConv {
|
||||
fn to_hex(&self) -> String;
|
||||
fn from_hex(hex: &str) -> Option<InfoHash>;
|
||||
}
|
||||
|
||||
impl HexConv for InfoHash {
|
||||
fn to_hex(&self) -> String {
|
||||
const HEX: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
|
||||
let data = self;
|
||||
let mut res = String::with_capacity(data.len() * 2);
|
||||
for b in data {
|
||||
res.push(HEX[((b >> 4) & 0x0fu8) as usize]);
|
||||
res.push(HEX[(b & 0x0fu8) as usize]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
fn from_hex(hex: &str) -> Option<InfoHash> {
|
||||
let mut res : InfoHash = [0u8; 20];
|
||||
if hex.len() != 2 * res.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut tmp = 0;
|
||||
let mut idx = 0;
|
||||
|
||||
for ch in hex.chars() {
|
||||
if idx % 2 == 1 {
|
||||
tmp <<= 4;
|
||||
}
|
||||
|
||||
let mut num = ch as u32;
|
||||
if ch >= '0' && ch <= '9' {
|
||||
num -= '0' as u32;
|
||||
} else if ch >= 'a' && ch <= 'f' {
|
||||
num -= 'a' as u32;
|
||||
num += 10;
|
||||
} else if ch >= 'A' && ch <= 'F' {
|
||||
num -= 'A' as u32;
|
||||
num += 10;
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
|
||||
tmp |= num & 0x0f;
|
||||
|
||||
if idx % 2 == 1 {
|
||||
res[(idx - 1) / 2] = tmp as u8;
|
||||
tmp = 0;
|
||||
}
|
||||
|
||||
idx += 1;
|
||||
}
|
||||
|
||||
return Some(res);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct TorrentEntry {
|
||||
is_flagged: bool,
|
||||
|
||||
#[serde(skip)]
|
||||
peers: std::collections::BTreeMap<PeerId, TorrentPeer>,
|
||||
|
||||
completed: u32,
|
||||
|
||||
#[serde(skip)]
|
||||
seeders: u32,
|
||||
}
|
||||
|
||||
|
@ -163,6 +112,45 @@ struct TorrentDatabase {
|
|||
torrent_peers: std::sync::RwLock<std::collections::BTreeMap<InfoHash, TorrentEntry>>,
|
||||
}
|
||||
|
||||
impl Default for TorrentDatabase {
|
||||
fn default() -> Self {
|
||||
TorrentDatabase{
|
||||
torrent_peers: std::sync::RwLock::new(std::collections::BTreeMap::new()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for TorrentDatabase {
|
||||
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
use serde::ser::SerializeMap;
|
||||
use binascii::bin2hex;
|
||||
|
||||
let db = match self.torrent_peers.read() {
|
||||
Ok(v) => v,
|
||||
Err(err) => {
|
||||
error!("Failed to lock database for reading. {}", err);
|
||||
panic!("fatal error. check logs.");
|
||||
}
|
||||
};
|
||||
let mut info_hash_buffer = [0u8; 40];
|
||||
|
||||
let mut map = serializer.serialize_map(None)?;
|
||||
|
||||
for entry in db.iter() {
|
||||
let info_hash = match bin2hex(entry.0, &mut info_hash_buffer) {
|
||||
Ok(v) => std::str::from_utf8(v).unwrap(),
|
||||
Err(err) => {
|
||||
error!("Failed to serialize database key.");
|
||||
panic!("fatal error. check logs.")
|
||||
}
|
||||
};
|
||||
map.serialize_entry(info_hash, entry.1)?;
|
||||
}
|
||||
|
||||
map.end()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TorrentTracker {
|
||||
mode: TrackerMode,
|
||||
database: TorrentDatabase,
|
||||
|
@ -299,18 +287,4 @@ mod tests {
|
|||
fn tracker_sync() {
|
||||
is_sync::<TorrentTracker>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ih2hex() {
|
||||
let ih: InfoHash = [1u8, 2, 3, 4, 5, 6, 7, 8, 9, 0xa,
|
||||
0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0xff];
|
||||
assert!(ih.to_hex() == "0102030405060708090a0b0c0d0e0f10111213ff");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hex2ih() {
|
||||
let ih = InfoHash::from_hex("0102030405060708090a0b0c0d0e0f10111213ff").unwrap();
|
||||
assert_eq!(ih, [1u8, 2, 3, 4, 5, 6, 7, 8, 9, 0xa,
|
||||
0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0xff]);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue