JSON-RPC server.

This commit is contained in:
chriseth 2022-09-03 23:54:22 +02:00
parent df7877ea37
commit 531722cc3e
3 changed files with 108 additions and 13 deletions

View file

@ -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"

View file

@ -2,23 +2,26 @@ use std::env;
mod flow;
mod io;
mod server;
mod types;
use types::Address;
fn main() {
let args: Vec<String> = 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<String> = 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,
// );
}

91
src/server.rs Normal file
View file

@ -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<dyn Error>> {
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<JsonRpcRequest, Box<dyn Error>> {
// 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<Vec<u8>, Box<dyn Error>> {
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)
}