diff --git a/Cargo.toml b/Cargo.toml index 97bd4fe..ef62f72 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,3 +6,4 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +json = "0.12.4" diff --git a/src/main.rs b/src/main.rs index b994d90..851d669 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,23 +2,26 @@ use std::env; mod flow; mod io; +mod server; mod types; use types::Address; fn main() { - let args: Vec = env::args().collect(); - if args.len() != 4 { - panic!("Expected three arguments"); - } - let (from_str, to_str, edges_file) = (&args[1], &args[2], &args[3]); + server::start(8080); - println!("Computing flow {from_str} -> {to_str} using {edges_file}"); - let edges = io::read_edges_binary(edges_file).expect("Error loading edges."); - println!("Read {} edges", edges.len()); - flow::compute_flow( - &Address::from(from_str.as_str()), - &Address::from(to_str.as_str()), - &edges, - ); + // let args: Vec = env::args().collect(); + // if args.len() != 4 { + // panic!("Expected three arguments"); + // } + // let (from_str, to_str, edges_file) = (&args[1], &args[2], &args[3]); + + // println!("Computing flow {from_str} -> {to_str} using {edges_file}"); + // let edges = io::read_edges_binary(edges_file).expect("Error loading edges."); + // println!("Read {} edges", edges.len()); + // flow::compute_flow( + // &Address::from(from_str.as_str()), + // &Address::from(to_str.as_str()), + // &edges, + // ); } diff --git a/src/server.rs b/src/server.rs new file mode 100644 index 0000000..4ccbe4b --- /dev/null +++ b/src/server.rs @@ -0,0 +1,91 @@ +use json; +use json::JsonValue; +use std::error::Error; +use std::io::{BufRead, BufReader, ErrorKind}; +use std::{ + io::{Read, Write}, + net::{SocketAddr, TcpListener, TcpStream}, +}; + +pub fn start(port: u16) { + let listener = + TcpListener::bind(format!("127.0.0.1:{port}")).expect("Could not create server."); + loop { + match listener.accept() { + Ok((socket, address)) => match handle_connection(socket, address) { + Ok(_) => {} + Err(e) => println!("Error communicating with client: {e}"), + }, + Err(e) => println!("Error accepting connection: {e}"), + } + } +} + +struct JsonRpcRequest { + id: JsonValue, + method: String, + params: JsonValue, +} + +fn handle_connection(mut socket: TcpStream, address: SocketAddr) -> Result<(), Box> { + let request = read_request(socket)?; + match request.method.as_str() { + "load_edges_binary" => {} + "compute_transfer" => {} + "cancel" => {} + "update_edges" => {} + _ => {} + } + Ok(()) +} + +fn read_request(mut socket: TcpStream) -> Result> { + // let mut buf_reader = BufReader::new(&mut socket); + // let http_request: Vec<_> = buf_reader + // .by_ref() + // .lines() + // .map(|result| result.unwrap()) + // .take_while(|line| !line.is_empty()) + // .collect(); + // println!("{http_request:?}"); + // let mut buf = [0; 74]; + // buf_reader.read_exact(&mut buf)?; + // println!("payload: {buf:?}"); + + // let response = "HTTP/1.1 200 OK\r\n\r\n"; + + // socket.write_all(response.as_bytes()).unwrap(); + let payload = read_payload(socket)?; + let mut request = json::parse(&String::from_utf8(payload)?)?; + println!("Request: {request}"); + let id = request["id"].take(); + let params = request["params"].take(); + match request["method"].as_str() { + Some(method) => Ok(JsonRpcRequest { + id, + method: method.to_string(), + params, + }), + _ => Err(From::from("Invalid JSON-RPC request: {request}")), + } +} + +fn read_payload(socket: TcpStream) -> Result, Box> { + let mut reader = BufReader::new(socket); + let mut length = 0; + for result in reader.by_ref().lines() { + let l = result?; + if l.is_empty() { + break; + } + + let header = "content-length: "; + if l.to_lowercase().starts_with(header) { + length = usize::from_str_radix(&l[header.len()..], 10)?; + } + } + let mut payload = vec![0u8; length]; + + reader.read_exact(payload.as_mut_slice())?; + Ok(payload) +}