From 379b262ce64406e8e407020416b084d077f5a8a5 Mon Sep 17 00:00:00 2001 From: Jake Hillion Date: Sun, 22 May 2022 22:56:45 +0100 Subject: [PATCH] added example src --- src/fib/main.rs | 15 ++++++ src/fib/spec.json | 27 +++++++++++ src/pipes/main.rs | 42 +++++++++++++++++ src/pipes/spec.json | 25 ++++++++++ src/tls/http.rs | 61 +++++++++++++++++++++++++ src/tls/main.rs | 109 ++++++++++++++++++++++++++++++++++++++++++++ src/tls/spec.json | 76 ++++++++++++++++++++++++++++++ 7 files changed, 355 insertions(+) create mode 100644 src/fib/main.rs create mode 100644 src/fib/spec.json create mode 100644 src/pipes/main.rs create mode 100644 src/pipes/spec.json create mode 100644 src/tls/http.rs create mode 100644 src/tls/main.rs create mode 100644 src/tls/spec.json diff --git a/src/fib/main.rs b/src/fib/main.rs new file mode 100644 index 0000000..da28e67 --- /dev/null +++ b/src/fib/main.rs @@ -0,0 +1,15 @@ +fn main() { + println!("fib(1) = {}", fib(1)); + println!("fib(7) = {}", fib(7)); + println!("fib(19) = {}", fib(19)); +} + +fn fib(i: u64) -> u64 { + let (mut a, mut b) = (0, 1); + + for _ in 0..i { + (a, b) = (b, a + b); + } + + a +} diff --git a/src/fib/spec.json b/src/fib/spec.json new file mode 100644 index 0000000..a94070d --- /dev/null +++ b/src/fib/spec.json @@ -0,0 +1,27 @@ +{ + "entrypoints": { + "fib": { + "environment": [ + "Stdout", + { + "Filesystem": { + "host_path": "/lib/x86_64-linux-gnu/libgcc_s.so.1", + "environment_path": "/lib/libgcc_s.so.1" + } + }, + { + "Filesystem": { + "host_path": "/lib/x86_64-linux-gnu/libc.so.6", + "environment_path": "/lib/libc.so.6" + } + }, + { + "Filesystem": { + "host_path": "/lib64/ld-linux-x86-64.so.2", + "environment_path": "/lib64/ld-linux-x86-64.so.2" + } + } + ] + } + } +} \ No newline at end of file diff --git a/src/pipes/main.rs b/src/pipes/main.rs new file mode 100644 index 0000000..fa24c6a --- /dev/null +++ b/src/pipes/main.rs @@ -0,0 +1,42 @@ +use std::fs::File; +use std::io::Write; + +fn main() { + use std::os::unix::io::FromRawFd; + + let mut args = std::env::args(); + + let _bin = args.next(); + + match args.next() { + Some(s) => match s.as_str() { + "pipe_sender" => { + let fd: i32 = args.next().unwrap().parse().unwrap(); + pipe_sender(unsafe { File::from_raw_fd(fd) }) + } + "pipe_receiver" => { + let pipe_data = args.next().unwrap(); + pipe_receiver(pipe_data.as_str()) + } + _ => unimplemented!(), + }, + None => unimplemented!(), + } +} + +fn pipe_sender(mut tx_pipe: File) { + println!("hello from pipe_sender!"); + + let data = b"some data"; + let bytes_written = tx_pipe.write(&data[..]).unwrap(); + assert!(bytes_written == data.len()); + + let data = b"some more data"; + let bytes_written = tx_pipe.write(&data[..]).unwrap(); + assert!(bytes_written == data.len()); +} + +fn pipe_receiver(rx_data: &str) { + println!("hello from pid: {}", std::process::id()); + println!("received data: {}", rx_data); +} diff --git a/src/pipes/spec.json b/src/pipes/spec.json new file mode 100644 index 0000000..3032669 --- /dev/null +++ b/src/pipes/spec.json @@ -0,0 +1,25 @@ +{ + "entrypoints": { + "pipe_sender": { + "args": [ + "BinaryName", + "Entrypoint", + { + "Pipe": { + "Tx": "messages" + } + } + ] + }, + "pipe_receiver": { + "trigger": { + "Pipe": "messages" + }, + "args": [ + "BinaryName", + "Entrypoint", + "PipeTrigger" + ] + } + } +} \ No newline at end of file diff --git a/src/tls/http.rs b/src/tls/http.rs new file mode 100644 index 0000000..0688f37 --- /dev/null +++ b/src/tls/http.rs @@ -0,0 +1,61 @@ +use std::fs; +use std::io::{Read, Write}; +use std::net::TcpStream; +use std::path::PathBuf; + +pub(super) fn handler(mut stream: TcpStream) -> i32 { + println!("entered http handler"); + + let mut buf = Vec::new(); + loop { + let buf_len = buf.len(); + buf.resize_with(buf_len + 1024, Default::default); + + if stream.read(&mut buf[buf_len..]).unwrap() == 0 { + break; + } + + let mut headers = [httparse::EMPTY_HEADER; 64]; + let mut req = httparse::Request::new(&mut headers); + let result = req.parse(&buf).unwrap(); + + if result.is_partial() { + continue; + } + + let filename = if req.method != Some("GET") { + None + } else { + req.path + }; + + let status_line = if filename.is_some() { + "HTTP/1.1 200 OK" + } else { + "HTTP/1.1 404 NOT FOUND" + }; + + let contents = if let Some(filename) = filename { + fs::read_to_string( + PathBuf::from("/var/www/html/") + .join(filename.strip_prefix('/').unwrap_or(filename)), + ) + .unwrap() + } else { + "content not found\n".to_string() + }; + + let response_header = format!( + "{}\r\nContent-Length: {}\r\n\r\n", + status_line, + contents.len(), + ); + + stream.write_all(response_header.as_bytes()).unwrap(); + stream.write_all(contents.as_bytes()).unwrap(); + + break; + } + + exitcode::OK +} diff --git a/src/tls/main.rs b/src/tls/main.rs new file mode 100644 index 0000000..3b77a55 --- /dev/null +++ b/src/tls/main.rs @@ -0,0 +1,109 @@ +mod http; + +use std::fs::File; +use std::net::{TcpListener, TcpStream}; + +fn main() { + let mut args = std::env::args(); + + let _bin = args.next(); + let entrypoint = args.next(); + + match entrypoint { + Some(s) => match s.as_str() { + "connection_listener" => connection_listener_entrypoint(), + "http_handler" => http_handler_entrypoint(), + + _ => unimplemented!(), + }, + None => unimplemented!(), + } +} + +fn connection_listener_entrypoint() { + // imports + use std::os::unix::io::{FromRawFd, RawFd}; + + // argument parsing + let mut args = std::env::args(); + + let _bin = args.next(); + let _entrypoint = args.next(); + + let http_handler_trigger = args.next(); + let http_handler_trigger: RawFd = http_handler_trigger + .expect("request handler required") + .parse() + .expect("tcp listener should be a file descriptor"); + let http_handler_trigger = unsafe { File::from_raw_fd(http_handler_trigger) }; + + let tcp_listener = args.next(); + let tcp_listener: RawFd = tcp_listener + .expect("tcp listener required") + .parse() + .expect("tcp listener should be a file descriptor"); + let tcp_listener = unsafe { TcpListener::from_raw_fd(tcp_listener) }; + + // actual function body + fn connection_listener(http_handler_trigger: File, tcp_listener: TcpListener) -> i32 { + println!("connection_listener entered"); + + // handle incoming connections + for stream in tcp_listener.incoming() { + let stream = match stream { + Ok(s) => s, + Err(e) => { + println!("connection listener: error: {}", e); + return 1; + } + }; + + println!("received a new connection"); + http_handler(&http_handler_trigger, stream); + } + + exitcode::OK + } + + // run function + std::process::exit(connection_listener(http_handler_trigger, tcp_listener)); +} + +fn http_handler(trigger_socket: &File, stream: TcpStream) { + // imports + use nix::sys::socket::{sendmsg, ControlMessage, MsgFlags}; + use std::os::unix::io::AsRawFd; + + // send file descriptor(s) + let sockfd = trigger_socket.as_raw_fd(); + let fds = [stream.as_raw_fd()]; + + sendmsg::<()>( + sockfd, + &[], + &[ControlMessage::ScmRights(&fds)], + MsgFlags::empty(), + None, + ) + .unwrap(); +} + +fn http_handler_entrypoint() { + // imports + use std::os::unix::io::{FromRawFd, RawFd}; + + // argument parsing + let mut args = std::env::args(); + + let _bin = args.next(); + let _entrypoint = args.next(); + + let stream = args.next(); + let stream: RawFd = stream + .expect("request stream required") + .parse() + .expect("request stream should be a file descriptor"); + let stream = unsafe { TcpStream::from_raw_fd(stream) }; + + std::process::exit(http::handler(stream)); +} diff --git a/src/tls/spec.json b/src/tls/spec.json new file mode 100644 index 0000000..ece8101 --- /dev/null +++ b/src/tls/spec.json @@ -0,0 +1,76 @@ +{ + "entrypoints": { + "connection_listener": { + "args": [ + "BinaryName", + "Entrypoint", + { + "FileSocket": { + "Tx": "http" + } + }, + { + "TcpListener": { + "addr": "0.0.0.0:8443" + } + } + ], + "environment": [ + { + "Filesystem": { + "host_path": "/lib/x86_64-linux-gnu/libgcc_s.so.1", + "environment_path": "/lib/libgcc_s.so.1" + } + }, + { + "Filesystem": { + "host_path": "/lib/x86_64-linux-gnu/libc.so.6", + "environment_path": "/lib/libc.so.6" + } + }, + { + "Filesystem": { + "host_path": "/lib64/ld-linux-x86-64.so.2", + "environment_path": "/lib64/ld-linux-x86-64.so.2" + } + } + ] + }, + "http_handler": { + "trigger": { + "FileSocket": "http" + }, + "args": [ + "BinaryName", + "Entrypoint", + "Trigger" + ], + "environment": [ + { + "Filesystem": { + "host_path": "/var/www/html", + "environment_path": "/var/www/html" + } + }, + { + "Filesystem": { + "host_path": "/lib/x86_64-linux-gnu/libgcc_s.so.1", + "environment_path": "/lib/libgcc_s.so.1" + } + }, + { + "Filesystem": { + "host_path": "/lib/x86_64-linux-gnu/libc.so.6", + "environment_path": "/lib/libc.so.6" + } + }, + { + "Filesystem": { + "host_path": "/lib64/ld-linux-x86-64.so.2", + "environment_path": "/lib64/ld-linux-x86-64.so.2" + } + } + ] + } + } +} \ No newline at end of file