aquatic_http: continue implementation work

This commit is contained in:
Joakim Frostegård 2020-07-02 13:21:39 +02:00
parent 76079cf66e
commit a487347a0d
6 changed files with 96 additions and 171 deletions

View file

@ -9,25 +9,25 @@ use crate::common::Peer;
// use serde_helpers::*;
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
#[serde(transparent)]
pub struct PeerId(
// #[serde(
// deserialize_with = "deserialize_20_bytes",
// serialize_with = "serialize_20_bytes"
// )]
pub [u8; 20]
pub String
);
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
#[serde(transparent)]
pub struct InfoHash(
// #[serde(
// deserialize_with = "deserialize_20_bytes",
// serialize_with = "serialize_20_bytes"
// )]
pub [u8; 20]
pub String
);
@ -76,8 +76,8 @@ pub struct AnnounceRequest {
pub bytes_left: usize,
#[serde(default)]
pub event: AnnounceEvent,
/// FIXME: number: 0 or 1
pub compact: bool,
/// FIXME: number: 0 or 1 to bool
pub compact: u8,
/// Requested number of peers to return
pub numwant: usize,
}
@ -130,16 +130,32 @@ pub enum Request {
impl Request {
pub fn from_http(http: httparse::Request) -> Option<Self> {
http.path
.and_then(|path| {
let mut iterator = path.splitn(2, '?');
log::debug!("path: {:?}", http.path);
iterator.next();
iterator.next()
})
.and_then(|query_string| {
serde_urlencoded::from_str(query_string).ok()
})
let path = http.path?;
let mut split_parts= path.splitn(2, '?');
let path = split_parts.next()?;
let query_string = split_parts.next()?;
if path == "/announce" {
let result: Result<AnnounceRequest, serde_urlencoded::de::Error> = serde_urlencoded::from_str(query_string);
if let Err(ref err) = result {
log::debug!("error: {}", err);
}
result.ok().map(Request::Announce)
} else {
let result: Result<ScrapeRequest, serde_urlencoded::de::Error> = serde_urlencoded::from_str(query_string);
if let Err(ref err) = result {
log::debug!("error: {}", err);
}
result.ok().map(Request::Scrape)
}
}
}
@ -154,6 +170,6 @@ pub enum Response {
impl Response {
pub fn to_http_string(self) -> String {
unimplemented!()
"(response)".to_string()
}
}

View file

@ -126,122 +126,4 @@ pub fn deserialize_info_hashes<'de, D>(
where D: Deserializer<'de>,
{
Ok(deserializer.deserialize_any(InfoHashVecVisitor).unwrap_or_default())
}
#[cfg(test)]
mod tests {
use serde::Deserialize;
use super::*;
fn info_hash_from_bytes(bytes: &[u8]) -> InfoHash {
let mut arr = [0u8; 20];
assert!(bytes.len() == 20);
arr.copy_from_slice(&bytes[..]);
InfoHash(arr)
}
#[test]
fn test_deserialize_20_bytes(){
let input = r#""aaaabbbbccccddddeeee""#;
let expected = info_hash_from_bytes(b"aaaabbbbccccddddeeee");
let observed: InfoHash = serde_json::from_str(input).unwrap();
assert_eq!(observed, expected);
let input = r#""aaaabbbbccccddddeee""#;
let res_info_hash: Result<InfoHash, _> = serde_json::from_str(input);
assert!(res_info_hash.is_err());
let input = r#""aaaabbbbccccddddeee𝕊""#;
let res_info_hash: Result<InfoHash, _> = serde_json::from_str(input);
assert!(res_info_hash.is_err());
}
#[test]
fn test_serde_20_bytes(){
let info_hash = info_hash_from_bytes(b"aaaabbbbccccddddeeee");
let out = serde_json::to_string(&info_hash).unwrap();
let info_hash_2 = serde_json::from_str(&out).unwrap();
assert_eq!(info_hash, info_hash_2);
}
#[derive(Debug, PartialEq, Eq, Deserialize)]
struct Test {
#[serde(deserialize_with = "deserialize_info_hashes", default)]
info_hashes: Vec<InfoHash>,
}
#[test]
fn test_deserialize_info_hashes_vec(){
let input = r#"{
"info_hashes": ["aaaabbbbccccddddeeee", "aaaabbbbccccddddeeee"]
}"#;
let expected = Test {
info_hashes: vec![
info_hash_from_bytes(b"aaaabbbbccccddddeeee"),
info_hash_from_bytes(b"aaaabbbbccccddddeeee"),
]
};
let observed: Test = serde_json::from_str(input).unwrap();
assert_eq!(observed, expected);
}
#[test]
fn test_deserialize_info_hashes_str(){
let input = r#"{
"info_hashes": "aaaabbbbccccddddeeee"
}"#;
let expected = Test {
info_hashes: vec![
info_hash_from_bytes(b"aaaabbbbccccddddeeee"),
]
};
let observed: Test = serde_json::from_str(input).unwrap();
assert_eq!(observed, expected);
}
#[test]
fn test_deserialize_info_hashes_null(){
let input = r#"{
"info_hashes": null
}"#;
let expected = Test {
info_hashes: vec![]
};
let observed: Test = serde_json::from_str(input).unwrap();
assert_eq!(observed, expected);
}
#[test]
fn test_deserialize_info_hashes_missing(){
let input = r#"{}"#;
let expected = Test {
info_hashes: vec![]
};
let observed: Test = serde_json::from_str(input).unwrap();
assert_eq!(observed, expected);
}
}