WIP: work on http load test (now partly working) and http protocol

This commit is contained in:
Joakim Frostegård 2020-07-20 14:30:36 +02:00
parent 5b0d364ccf
commit d1e9d24773
10 changed files with 326 additions and 226 deletions

View file

@ -22,6 +22,7 @@ harness = false
anyhow = "1"
bendy = { version = "0.3", features = ["std", "serde"] }
hashbrown = { version = "0.7", features = ["serde"] }
hex = { version = "0.4", default-features = false }
itoa = "0.4"
log = "0.4"
memchr = "2"

View file

@ -1,3 +1,5 @@
use std::io::Write;
use anyhow::Context;
use hashbrown::HashMap;
use smartstring::{SmartString, LazyCompact};
@ -20,12 +22,80 @@ pub struct AnnounceRequest {
}
impl AnnounceRequest {
pub fn as_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.extend_from_slice(b"GET /announce?info_hash=");
bytes.extend_from_slice(&urlencode_20_bytes(self.info_hash.0));
bytes.extend_from_slice(b"&peer_id=");
bytes.extend_from_slice(&urlencode_20_bytes(self.peer_id.0));
bytes.extend_from_slice(b"&port=");
itoa::write(&mut bytes, self.port);
bytes.extend_from_slice(b"&left=");
itoa::write(&mut bytes, self.bytes_left);
bytes.extend_from_slice(b"&event=started"); // FIXME
bytes.extend_from_slice(b"&compact=");
itoa::write(&mut bytes, self.compact as u8);
if let Some(numwant) = self.numwant {
bytes.extend_from_slice(b"&numwant=");
itoa::write(&mut bytes, numwant);
}
if let Some(ref key) = self.key {
bytes.extend_from_slice(b"&key=");
bytes.extend_from_slice(key.as_str().as_bytes());
}
bytes.extend_from_slice(b" HTTP/1.1\r\n\r\n");
bytes
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ScrapeRequest {
pub info_hashes: Vec<InfoHash>,
}
impl ScrapeRequest {
pub fn as_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.extend_from_slice(b"GET /scrape?");
let mut first = true;
for info_hash in self.info_hashes.iter() {
if !first {
bytes.push(b'&')
}
bytes.extend_from_slice(b"info_hash=");
for b in info_hash.0.iter() {
bytes.push(b'%');
bytes.extend_from_slice(format!("{:02x}", b).as_bytes());
}
first = false;
}
bytes.extend_from_slice(b" HTTP/1.1\r\n\r\n");
bytes
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Request {
Announce(AnnounceRequest),
@ -263,6 +333,13 @@ impl Request {
Ok(processed)
}
pub fn as_bytes(&self) -> Vec<u8> {
match self {
Self::Announce(r) => r.as_bytes(),
Self::Scrape(r) => r.as_bytes(),
}
}
}

View file

@ -187,6 +187,12 @@ impl Response {
Response::Scrape(r) => r.to_bytes(),
}
}
pub fn from_bytes(bytes: &[u8]) -> anyhow::Result<Self> {
Ok(Self::Failure(FailureResponse {
failure_reason: "fake response".to_string()
}))
}
}

View file

@ -6,6 +6,22 @@ use smartstring::{SmartString, LazyCompact};
use super::response::ResponsePeer;
pub fn urlencode_20_bytes(input: [u8; 20]) -> Vec<u8> {
let mut tmp = [0u8; 40];
hex::encode_to_slice(&input, &mut tmp);
let mut output = Vec::with_capacity(60);
for chunk in tmp.chunks_exact(2){
output.push(b'%');
output.extend_from_slice(chunk);
}
output
}
/// Not for serde
pub fn deserialize_20_bytes(value: SmartString<LazyCompact>) -> anyhow::Result<[u8; 20]> {
let mut arr = [0u8; 20];