Dummy data instead of HTTP
This commit is contained in:
parent
66d8aeb4a5
commit
dec39cf2e3
10 changed files with 1543 additions and 1413 deletions
101
src/record.rs
101
src/record.rs
|
|
@ -4,12 +4,10 @@ use std::{
|
|||
sync::mpsc::{Receiver, Sender, channel},
|
||||
};
|
||||
|
||||
use crate::util::{ResponseStreamer, print_bin};
|
||||
|
||||
const CLIENT_TO_SERVER: u8 = b'C';
|
||||
const SERVER_TO_CLIENT: u8 = b'S';
|
||||
|
||||
pub type Records = BTreeMap<u64, (Vec<u8>, Vec<(Direction, Vec<u8>)>)>;
|
||||
pub type Records = BTreeMap<u64, (Vec<u8>, Vec<(u64, Direction, u64)>)>;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
pub enum Direction {
|
||||
|
|
@ -34,7 +32,7 @@ fn write_record(
|
|||
direction: Direction,
|
||||
conn_id: u64,
|
||||
server_name: &str,
|
||||
data: &[u8],
|
||||
len: u64,
|
||||
) {
|
||||
let server_name = server_name.as_bytes();
|
||||
file.write_all(&[match direction {
|
||||
|
|
@ -45,8 +43,7 @@ fn write_record(
|
|||
file.write_all(&conn_id.to_be_bytes()).unwrap();
|
||||
file.write_all(&[server_name.len() as u8]).unwrap();
|
||||
file.write_all(server_name).unwrap();
|
||||
file.write_all(&(data.len() as u64).to_be_bytes()).unwrap();
|
||||
file.write_all(&data).unwrap();
|
||||
file.write_all(&len.to_be_bytes()).unwrap();
|
||||
file.flush().unwrap();
|
||||
}
|
||||
|
||||
|
|
@ -78,17 +75,25 @@ impl Recorder {
|
|||
let Some(server_name) = server_name else {
|
||||
continue;
|
||||
};
|
||||
write_record(&mut self.file, direction, conn_id, &server_name, &data);
|
||||
write_record(
|
||||
&mut self.file,
|
||||
direction,
|
||||
conn_id,
|
||||
&server_name,
|
||||
data.len() as u64,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "record")]
|
||||
#[derive(Clone)]
|
||||
struct Handler {
|
||||
sender: Sender<(u64, Option<String>, Direction, Vec<u8>)>,
|
||||
server_name: Option<String>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "record")]
|
||||
impl sslrelay::HandlerCallbacks for Handler {
|
||||
// DownStream non blocking callback
|
||||
fn ds_nb_callback(&self, in_data: Vec<u8>, conn_id: u64) {
|
||||
|
|
@ -129,6 +134,7 @@ impl sslrelay::HandlerCallbacks for Handler {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "record")]
|
||||
pub fn make_record(path: &str) {
|
||||
let (mut recorder, sender) = Recorder::new(path);
|
||||
let mut relay = sslrelay::SSLRelay::new(
|
||||
|
|
@ -161,7 +167,7 @@ pub fn make_record(path: &str) {
|
|||
|
||||
pub fn read_record_file(path: &str) -> Records {
|
||||
let mut file = std::fs::OpenOptions::new().read(true).open(path).unwrap();
|
||||
let mut records = BTreeMap::<u64, (Vec<u8>, Vec<(Direction, Vec<u8>)>)>::new();
|
||||
let mut records = BTreeMap::<u64, (Vec<u8>, Vec<(u64, Direction, u64)>)>::new();
|
||||
loop {
|
||||
let mut direction = [0; 1];
|
||||
if file.read(&mut direction).unwrap() != 1 {
|
||||
|
|
@ -202,84 +208,39 @@ pub fn read_record_file(path: &str) -> Records {
|
|||
println!("Error: len too large {len}. stop.");
|
||||
break;
|
||||
}
|
||||
let mut buf = vec![0; len as usize];
|
||||
if file.read(&mut buf).unwrap() != len as usize {
|
||||
println!("Error: incomplete data. stop.");
|
||||
break;
|
||||
}
|
||||
|
||||
// Replace URL with unique id, to allow for better tracking by making each request unique.
|
||||
// (proxy may modify some headers, but not the URL)
|
||||
let mut insert_id = |req_id| {
|
||||
if direction == Direction::ClientToServer {
|
||||
let mut spaces = buf
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(i, c)| if *c == b' ' { Some(i) } else { None });
|
||||
let s1 = spaces.next().unwrap();
|
||||
let s2 = spaces.next().unwrap();
|
||||
let new_url = format!("/{conn_id}-{req_id}/");
|
||||
if s2 - s1 - 1 < new_url.len() {
|
||||
// Not optimal but good enough
|
||||
let mut new_buf = Vec::new();
|
||||
new_buf.extend_from_slice(&buf[0..s1 + 1]);
|
||||
new_buf.extend_from_slice(new_url.as_bytes());
|
||||
new_buf.extend_from_slice(&buf[s2..]);
|
||||
buf = new_buf;
|
||||
} else {
|
||||
buf[s1 + 1..s2][0..new_url.len()].copy_from_slice(new_url.as_bytes());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
match records.entry(conn_id) {
|
||||
btree_map::Entry::Occupied(mut entry) => {
|
||||
(insert_id)(entry.get().1.len());
|
||||
entry.get_mut().1.push((direction, buf));
|
||||
let req_id = entry.get().1.len() as u64;
|
||||
entry.get_mut().1.push((req_id, direction, len));
|
||||
}
|
||||
btree_map::Entry::Vacant(entry) => {
|
||||
(insert_id)(0);
|
||||
entry.insert((server_name, vec![(direction, buf)]));
|
||||
let req_id = 0;
|
||||
entry.insert((server_name, vec![(req_id, direction, len)]));
|
||||
}
|
||||
}
|
||||
}
|
||||
records
|
||||
}
|
||||
|
||||
pub fn print_records(records: &Records, print_packets: bool, number: Option<u64>) {
|
||||
for (id, (server_name, records)) in records {
|
||||
pub fn print_records(records: &Records, number: Option<u64>) {
|
||||
for (conn_id, (server_name, records)) in records {
|
||||
if let Some(number) = number
|
||||
&& number != *id
|
||||
&& number != *conn_id
|
||||
{
|
||||
continue;
|
||||
}
|
||||
let server_name = str::from_utf8(server_name.as_slice()).unwrap();
|
||||
println!("{id} {server_name}");
|
||||
for (direction, data) in records {
|
||||
println!("{conn_id} {server_name}");
|
||||
for (req_id, direction, len) in records {
|
||||
match direction {
|
||||
Direction::ClientToServer => {
|
||||
println!(" >> {}", data.len());
|
||||
println!(" ({req_id}) >> {len}");
|
||||
}
|
||||
Direction::ServerToClient => {
|
||||
println!(" << {}", data.len());
|
||||
println!(" ({req_id}) << {len}");
|
||||
}
|
||||
}
|
||||
if print_packets {
|
||||
/*let data_tr = if data.len() >= 256 && *direction == Direction::ServerToClient {
|
||||
&data[0..256]
|
||||
} else {
|
||||
data.as_slice()
|
||||
};
|
||||
if let Ok(data_tr) = str::from_utf8(data_tr) {
|
||||
println!(" {data_tr:?}")
|
||||
} else {
|
||||
println!(" {data_tr:?}")
|
||||
}
|
||||
if let Some(header_end) = memchr::memmem::find(data, b"\r\n\r\n") {
|
||||
println!(" --> body len: {}", data.len() - header_end - 4);
|
||||
}*/
|
||||
print_bin(&data[0..data.len().min(8192)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -292,7 +253,13 @@ pub fn make_test_record(path: &str) {
|
|||
.open(path)
|
||||
.unwrap();
|
||||
for (conn_id, server_name, direction, data) in TEST_RECORD {
|
||||
write_record(&mut file, *direction, *conn_id, *server_name, *data);
|
||||
write_record(
|
||||
&mut file,
|
||||
*direction,
|
||||
*conn_id,
|
||||
server_name,
|
||||
data.len() as u64,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -311,9 +278,9 @@ pub fn remove_record(
|
|||
.unwrap();
|
||||
for (conn_id, (server_name, packets)) in records.into_iter() {
|
||||
let server_name = String::from_utf8(server_name).unwrap();
|
||||
for (packet_id, (direction, data)) in packets.into_iter().enumerate() {
|
||||
for (packet_id, (_req_id, direction, len)) in packets.into_iter().enumerate() {
|
||||
if conn_id != record_to_remove || packet_id != packet_to_remove {
|
||||
write_record(&mut output_file, direction, conn_id, &server_name, &data);
|
||||
write_record(&mut output_file, direction, conn_id, &server_name, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue