From b39531166e9c084aba672cb7d25b3849255ce15c Mon Sep 17 00:00:00 2001 From: dr-frmr Date: Fri, 17 Nov 2023 12:59:52 -0500 Subject: [PATCH] move everything into http module --- src/{http_client.rs => http/client.rs} | 38 +- src/http/mod.rs | 4 + src/{http_server/mod.rs => http/server.rs} | 46 +- src/http/types.rs | 121 +++++ .../server_fns.rs => http/utils.rs} | 11 + src/kernel/mod.rs | 2 +- src/kernel_types.rs | 422 ------------------ src/main.rs | 9 +- src/register.rs | 5 +- src/types.rs | 176 +------- 10 files changed, 183 insertions(+), 651 deletions(-) rename src/{http_client.rs => http/client.rs} (86%) create mode 100644 src/http/mod.rs rename src/{http_server/mod.rs => http/server.rs} (97%) create mode 100644 src/http/types.rs rename src/{http_server/server_fns.rs => http/utils.rs} (97%) delete mode 100644 src/kernel_types.rs diff --git a/src/http_client.rs b/src/http/client.rs similarity index 86% rename from src/http_client.rs rename to src/http/client.rs index 260891e5..23660e50 100644 --- a/src/http_client.rs +++ b/src/http/client.rs @@ -1,51 +1,15 @@ use crate::types::*; +use crate::http::types::*; use anyhow::Result; use http::header::{HeaderMap, HeaderName, HeaderValue}; -use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::sync::Arc; -use thiserror::Error; // Test http_client with these commands in the terminal // !message our http_client {"method": "GET", "url": "https://jsonplaceholder.typicode.com/posts", "headers": {}} // !message our http_client {"method": "POST", "url": "https://jsonplaceholder.typicode.com/posts", "headers": {"Content-Type": "application/json"}} // !message our http_client {"method": "PUT", "url": "https://jsonplaceholder.typicode.com/posts", "headers": {"Content-Type": "application/json"}} -// -// http_client.rs types -// - -#[derive(Debug, Serialize, Deserialize)] -pub struct HttpRequest { - pub method: String, // must parse to http::Method - pub version: Option, // must parse to http::Version - pub url: String, // must parse to url::Url - pub headers: HashMap, - // BODY is stored in the payload, as bytes - // TIMEOUT is stored in the message expect_response -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct HttpResponse { - pub status: u16, - pub headers: HashMap, - // BODY is stored in the payload, as bytes -} - -#[derive(Error, Debug, Serialize, Deserialize)] -pub enum HttpClientError { - #[error("http_client: request could not be parsed to HttpRequest: {}.", req)] - BadRequest { req: String }, - #[error("http_client: http method not supported: {}", method)] - BadMethod { method: String }, - #[error("http_client: url could not be parsed: {}", url)] - BadUrl { url: String }, - #[error("http_client: http version not supported: {}", version)] - BadVersion { version: String }, - #[error("http_client: failed to execute request {}", error)] - RequestFailed { error: String }, -} - pub async fn http_client( our_name: String, send_to_loop: MessageSender, diff --git a/src/http/mod.rs b/src/http/mod.rs new file mode 100644 index 00000000..d47abc33 --- /dev/null +++ b/src/http/mod.rs @@ -0,0 +1,4 @@ +pub mod client; +pub mod server; +pub mod types; +pub mod utils; \ No newline at end of file diff --git a/src/http_server/mod.rs b/src/http/server.rs similarity index 97% rename from src/http_server/mod.rs rename to src/http/server.rs index cfb0e4bc..832bd786 100644 --- a/src/http_server/mod.rs +++ b/src/http/server.rs @@ -1,11 +1,10 @@ -use crate::http_server::server_fns::*; +use crate::http::utils::*; +use crate::http::types::*; use crate::register; use crate::types::*; use anyhow::Result; - use futures::SinkExt; use futures::StreamExt; - use route_recognizer::Router; use std::collections::HashMap; use std::net::SocketAddr; @@ -17,16 +16,26 @@ use warp::http::{header::HeaderValue, StatusCode}; use warp::ws::{WebSocket, Ws}; use warp::{Filter, Reply}; -mod server_fns; - // types and constants type HttpSender = tokio::sync::oneshot::Sender; type HttpResponseSenders = Arc>>; type PathBindings = Arc>>; -// node -> ID -> random ID - -/// http driver +/// HTTP server: a runtime module that handles HTTP requests at a given port. +/// The server accepts bindings-requests from apps. These can be used in two ways: +/// +/// 1. The app can bind to a path and receive all subsequent requests in the form +/// of an [`HttpRequest`] to that path. +/// They will be responsible for generating HTTP responses in the form of an +/// [`HttpResponse`] to those requests. +/// +/// 2. The app can bind static content to a path. The server will handle all subsequent +/// requests, serving that static content. It will only respond to `GET` requests. +/// +/// +/// In addition to binding on paths, the HTTP server can receive incoming WebSocket connections +/// and pass them to a targeted app. The server will handle encrypting and decrypting messages +/// over these connections. pub async fn http_server( our_name: String, our_port: u16, @@ -37,7 +46,6 @@ pub async fn http_server( ) -> Result<()> { let http_response_senders = Arc::new(Mutex::new(HashMap::new())); let websockets: WebSockets = Arc::new(Mutex::new(HashMap::new())); - let ws_proxies: WebSocketProxies = Arc::new(Mutex::new(HashMap::new())); // channel_id -> node // Add RPC path let mut bindings_map: Router = Router::new(); @@ -49,15 +57,6 @@ pub async fn http_server( }; bindings_map.add("/rpc:sys:uqbar/message", rpc_bound_path); - // Add encryptor binding - let encryptor_bound_path = BoundPath { - app: ProcessId::from_str("encryptor:sys:uqbar").unwrap(), - authenticated: false, - local_only: true, - original_path: "/encryptor:sys:uqbar".to_string(), - }; - bindings_map.add("/encryptor:sys:uqbar", encryptor_bound_path); - let path_bindings: PathBindings = Arc::new(RwLock::new(bindings_map)); let _ = tokio::join!( @@ -90,7 +89,6 @@ pub async fn http_server( http_response_senders.clone(), path_bindings.clone(), websockets.clone(), - ws_proxies.clone(), jwt_secret_bytes.clone(), send_to_loop.clone(), print_tx.clone(), @@ -848,13 +846,3 @@ async fn handler( } Ok(response) } - -pub async fn find_open_port(start_at: u16) -> Option { - for port in start_at..=u16::MAX { - let bind_addr = format!("0.0.0.0:{}", port); - if is_port_available(&bind_addr).await { - return Some(port); - } - } - None -} diff --git a/src/http/types.rs b/src/http/types.rs new file mode 100644 index 00000000..22df57b7 --- /dev/null +++ b/src/http/types.rs @@ -0,0 +1,121 @@ +use crate::types::Address; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; +use thiserror::Error; + +/// HTTP Request type that can be shared over WASM boundary to apps. +#[derive(Debug, Serialize, Deserialize)] +pub struct HttpRequest { + pub method: String, // must parse to http::Method + pub version: Option, // must parse to http::Version + pub url: String, // must parse to url::Url + pub headers: HashMap, + // BODY is stored in the payload, as bytes + // TIMEOUT is stored in the message expect_response +} + +/// HTTP Response type that can be shared over WASM boundary to apps. +#[derive(Debug, Serialize, Deserialize)] +pub struct HttpResponse { + pub status: u16, + pub headers: HashMap, + // BODY is stored in the payload, as bytes +} + +#[derive(Error, Debug, Serialize, Deserialize)] +pub enum HttpClientError { + #[error("http_client: request could not be parsed to HttpRequest: {}.", req)] + BadRequest { req: String }, + #[error("http_client: http method not supported: {}", method)] + BadMethod { method: String }, + #[error("http_client: url could not be parsed: {}", url)] + BadUrl { url: String }, + #[error("http_client: http version not supported: {}", version)] + BadVersion { version: String }, + #[error("http_client: failed to execute request {}", error)] + RequestFailed { error: String }, +} + +#[derive(Error, Debug, Serialize, Deserialize)] +pub enum HttpServerError { + #[error("http_server: json is None")] + NoJson, + #[error("http_server: response not ok")] + ResponseError, + #[error("http_server: bytes are None")] + NoBytes, + #[error( + "http_server: JSON payload could not be parsed to HttpClientRequest: {error}. Got {:?}.", + json + )] + BadJson { json: String, error: String }, + #[error("http_server: path binding error: {:?}", error)] + PathBind { error: String }, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct JwtClaims { + pub username: String, + pub expiration: u64, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct WebSocketServerTarget { + pub node: String, + pub id: Option, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct WebSocketPush { + pub target: WebSocketServerTarget, + pub is_text: Option, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct ServerAction { + pub action: String, +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum HttpServerAction { + BindPath { + path: String, + authenticated: bool, + local_only: bool, + }, + WebSocketPush(WebSocketPush), + ServerAction(ServerAction), +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct WsRegister { + pub ws_auth_token: String, + pub auth_token: String, + pub channel_id: String, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct WsMessage { + pub ws_auth_token: String, + pub auth_token: String, + pub channel_id: String, + pub target: Address, + pub json: Option, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct EncryptedWsMessage { + pub ws_auth_token: String, + pub auth_token: String, + pub channel_id: String, + pub target: Address, + pub encrypted: String, // Encrypted JSON as hex with the 32-byte authentication tag appended + pub nonce: String, // Hex of the 12-byte nonce +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum WebSocketClientMessage { + WsRegister(WsRegister), + WsMessage(WsMessage), + EncryptedWsMessage(EncryptedWsMessage), +} diff --git a/src/http_server/server_fns.rs b/src/http/utils.rs similarity index 97% rename from src/http_server/server_fns.rs rename to src/http/utils.rs index d641a8ad..164a50d2 100644 --- a/src/http_server/server_fns.rs +++ b/src/http/utils.rs @@ -1,3 +1,4 @@ +use crate::http::types::*; use crate::types::*; use futures::stream::SplitSink; use hmac::{Hmac, Mac}; @@ -230,6 +231,16 @@ pub fn deserialize_headers(hashmap: HashMap) -> HeaderMap { header_map } +pub async fn find_open_port(start_at: u16) -> Option { + for port in start_at..=u16::MAX { + let bind_addr = format!("0.0.0.0:{}", port); + if is_port_available(&bind_addr).await { + return Some(port); + } + } + None +} + pub async fn is_port_available(bind_addr: &str) -> bool { TcpListener::bind(bind_addr).await.is_ok() } diff --git a/src/kernel/mod.rs b/src/kernel/mod.rs index 038dec67..c26fe59a 100644 --- a/src/kernel/mod.rs +++ b/src/kernel/mod.rs @@ -2169,7 +2169,7 @@ async fn make_event_loop( let _ = persist_state(&our_name, &send_to_loop, &process_map).await; let _ = responder.send(true); }, - t::CapMessage::Drop { on, cap, responder } => { + t::CapMessage::_Drop { on, cap, responder } => { // remove cap from process map let Some(entry) = process_map.get_mut(&on) else { let _ = responder.send(false); diff --git a/src/kernel_types.rs b/src/kernel_types.rs deleted file mode 100644 index c88ef069..00000000 --- a/src/kernel_types.rs +++ /dev/null @@ -1,422 +0,0 @@ -use super::bindings::component::uq_process::types as wit; -use serde::{Deserialize, Serialize}; -use std::collections::HashSet; - -// -// process-facing kernel types, used for process -// management and message-passing -// matches types in uqbar.wit -// - -pub type Context = Vec; -pub type NodeId = String; // QNS domain name - -/// process ID is a formatted unique identifier that contains -/// the publishing node's ID, the package name, and finally the process name. -/// the process name can be a random number, or a name chosen by the user. -/// the formatting is as follows: -/// `[process name]:[package name]:[node ID]` -#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] -pub struct ProcessId { - process_name: String, - package_name: String, - publisher_node: NodeId, -} - -#[allow(dead_code)] -impl ProcessId { - /// generates a random u64 number if process_name is not declared - pub fn new(process_name: &str, package_name: &str, publisher_node: &str) -> Self { - ProcessId { - process_name: process_name.into(), - package_name: package_name.into(), - publisher_node: publisher_node.into(), - } - } - pub fn from_str(input: &str) -> Result { - // split string on colons into 3 segments - let mut segments = input.split(':'); - let process_name = segments - .next() - .ok_or(ProcessIdParseError::MissingField)? - .to_string(); - let package_name = segments - .next() - .ok_or(ProcessIdParseError::MissingField)? - .to_string(); - let publisher_node = segments - .next() - .ok_or(ProcessIdParseError::MissingField)? - .to_string(); - if segments.next().is_some() { - return Err(ProcessIdParseError::TooManyColons); - } - Ok(ProcessId { - process_name, - package_name, - publisher_node, - }) - } - pub fn to_string(&self) -> String { - [ - self.process_name.as_str(), - self.package_name.as_str(), - self.publisher_node.as_str(), - ] - .join(":") - } - pub fn process(&self) -> &str { - &self.process_name - } - pub fn package(&self) -> &str { - &self.package_name - } - pub fn publisher_node(&self) -> &str { - &self.publisher_node - } - pub fn en_wit(&self) -> wit::ProcessId { - wit::ProcessId { - process_name: self.process_name.clone(), - package_name: self.package_name.clone(), - publisher_node: self.publisher_node.clone(), - } - } - pub fn de_wit(wit: wit::ProcessId) -> ProcessId { - ProcessId { - process_name: wit.process_name, - package_name: wit.package_name, - publisher_node: wit.publisher_node, - } - } -} - -#[derive(Debug)] -pub enum ProcessIdParseError { - TooManyColons, - MissingField, -} - -#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)] -pub struct Address { - pub node: NodeId, - pub process: ProcessId, -} - -impl Address { - pub fn en_wit(&self) -> wit::Address { - wit::Address { - node: self.node.clone(), - process: self.process.en_wit(), - } - } - pub fn de_wit(wit: wit::Address) -> Address { - Address { - node: wit.node, - process: ProcessId { - process_name: wit.process.process_name, - package_name: wit.process.package_name, - publisher_node: wit.process.publisher_node, - }, - } - } -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Payload { - pub mime: Option, // MIME type - pub bytes: Vec, -} - -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -pub struct Request { - pub inherit: bool, - pub expects_response: Option, // number of seconds until timeout - pub ipc: Vec, - pub metadata: Option, // JSON-string -} - -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -pub struct Response { - pub inherit: bool, - pub ipc: Vec, - pub metadata: Option, // JSON-string -} - -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -pub enum Message { - Request(Request), - Response((Response, Option)), -} - -#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] -pub struct Capability { - pub issuer: Address, - pub params: String, // JSON-string -} - -#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] -pub struct SignedCapability { - pub issuer: Address, - pub params: String, // JSON-string - pub signature: Vec, // signed by the kernel, so we can verify that the kernel issued it -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct SendError { - pub kind: SendErrorKind, - pub target: Address, - pub message: Message, - pub payload: Option, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub enum SendErrorKind { - Offline, - Timeout, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub enum OnPanic { - None, - Restart, - Requests(Vec<(Address, Request, Option)>), -} - -impl OnPanic { - pub fn is_restart(&self) -> bool { - match self { - OnPanic::None => false, - OnPanic::Restart => true, - OnPanic::Requests(_) => false, - } - } -} - -#[derive(Debug, Serialize, Deserialize)] -pub enum KernelCommand { - StartProcess { - id: ProcessId, - wasm_bytes_handle: u128, - on_panic: OnPanic, - initial_capabilities: HashSet, - public: bool, - }, - KillProcess(ProcessId), // this is extrajudicial killing: we might lose messages! - // kernel only - RebootProcess { - process_id: ProcessId, - persisted: PersistedProcess, - }, - Shutdown, -} - -#[derive(Debug, Serialize, Deserialize)] -pub enum KernelResponse { - StartedProcess, - StartProcessError, - KilledProcess(ProcessId), -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct PersistedProcess { - pub wasm_bytes_handle: u128, - // pub drive: String, - // pub full_path: String, - pub on_panic: OnPanic, - pub capabilities: HashSet, - pub public: bool, // marks if a process allows messages from any process -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct VfsRequest { - pub drive: String, - pub action: VfsAction, -} - -#[derive(Debug, Serialize, Deserialize)] -pub enum VfsAction { - New, - Add { - full_path: String, - entry_type: AddEntryType, - }, - Rename { - full_path: String, - new_full_path: String, - }, - Delete(String), - WriteOffset { - full_path: String, - offset: u64, - }, - SetSize { - full_path: String, - size: u64, - }, - GetPath(u128), - GetHash(String), - GetEntry(String), - GetFileChunk { - full_path: String, - offset: u64, - length: u64, - }, - GetEntryLength(String), -} - -#[derive(Debug, Serialize, Deserialize)] -pub enum AddEntryType { - Dir, - NewFile, // add a new file to fs and add name in vfs - ExistingFile { hash: u128 }, // link an existing file in fs to a new name in vfs - ZipArchive, -} - -#[derive(Debug, Serialize, Deserialize)] -pub enum GetEntryType { - Dir, - File, -} - -#[derive(Debug, Serialize, Deserialize)] -pub enum VfsResponse { - Ok, - Err(VfsError), - GetPath(Option), - GetHash(Option), - GetEntry { - // file bytes in payload, if entry was a file - is_file: bool, - children: Vec, - }, - GetFileChunk, // chunk in payload - GetEntryLength(u64), -} - -#[derive(Debug, Serialize, Deserialize)] -pub enum VfsError { - BadDriveName, - BadDescriptor, - NoCap, - EntryNotFound, -} - -#[allow(dead_code)] -impl VfsError { - pub fn kind(&self) -> &str { - match *self { - VfsError::BadDriveName => "BadDriveName", - VfsError::BadDescriptor => "BadDescriptor", - VfsError::NoCap => "NoCap", - VfsError::EntryNotFound => "EntryNotFound", - } - } -} - -// -// package types -// - -pub type PackageVersion = (u32, u32, u32); - -/// the type that gets deserialized from `metadata.json` in a package -#[derive(Debug, Serialize, Deserialize)] -pub struct PackageMetadata { - pub package: String, - pub publisher: String, - pub version: PackageVersion, - pub description: Option, - pub website: Option, -} - -/// the type that gets deserialized from each entry in the array in `manifest.json` -#[derive(Debug, Serialize, Deserialize)] -pub struct PackageManifestEntry { - pub process_name: String, - pub process_wasm_path: String, - pub on_panic: OnPanic, - pub request_networking: bool, - pub request_messaging: Vec, - pub public: bool, -} - -// -// conversions between wit types and kernel types (annoying!) -// - -pub fn de_wit_request(wit: wit::Request) -> Request { - Request { - inherit: wit.inherit, - expects_response: wit.expects_response, - ipc: wit.ipc, - metadata: wit.metadata, - } -} - -pub fn en_wit_request(request: Request) -> wit::Request { - wit::Request { - inherit: request.inherit, - expects_response: request.expects_response, - ipc: request.ipc, - metadata: request.metadata, - } -} - -pub fn de_wit_response(wit: wit::Response) -> Response { - Response { - inherit: wit.inherit, - ipc: wit.ipc, - metadata: wit.metadata, - } -} - -pub fn en_wit_response(response: Response) -> wit::Response { - wit::Response { - inherit: response.inherit, - ipc: response.ipc, - metadata: response.metadata, - } -} - -pub fn de_wit_payload(wit: Option) -> Option { - match wit { - None => None, - Some(wit) => Some(Payload { - mime: wit.mime, - bytes: wit.bytes, - }), - } -} - -pub fn en_wit_payload(load: Option) -> Option { - match load { - None => None, - Some(load) => Some(wit::Payload { - mime: load.mime, - bytes: load.bytes, - }), - } -} - -pub fn de_wit_signed_capability(wit: wit::SignedCapability) -> SignedCapability { - SignedCapability { - issuer: Address { - node: wit.issuer.node, - process: ProcessId { - process_name: wit.issuer.process.process_name, - package_name: wit.issuer.process.package_name, - publisher_node: wit.issuer.process.publisher_node, - }, - }, - params: wit.params, - signature: wit.signature, - } -} - -pub fn en_wit_signed_capability(cap: SignedCapability) -> wit::SignedCapability { - wit::SignedCapability { - issuer: cap.issuer.en_wit(), - params: cap.params, - signature: cap.signature, - } -} diff --git a/src/main.rs b/src/main.rs index 11b766ef..74c54a2d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,8 +10,7 @@ use tokio::{fs, time::timeout}; mod eth_rpc; mod filesystem; -mod http_client; -mod http_server; +mod http; mod kernel; mod keygen; mod net; @@ -193,7 +192,7 @@ async fn main() { // username, networking key, and routing info. // if any do not match, we should prompt user to create a "transaction" // that updates their PKI info on-chain. - let http_server_port = http_server::find_open_port(8080).await.unwrap(); + let http_server_port = http::utils::find_open_port(8080).await.unwrap(); println!("login or register at http://localhost:{}", http_server_port); let (kill_tx, kill_rx) = oneshot::channel::(); @@ -317,7 +316,7 @@ async fn main() { fs_kill_recv, fs_kill_confirm_send, )); - tasks.spawn(http_server::http_server( + tasks.spawn(http::server::http_server( our.name.clone(), http_server_port, decoded_keyfile.jwt_secret_bytes.clone(), @@ -325,7 +324,7 @@ async fn main() { kernel_message_sender.clone(), print_sender.clone(), )); - tasks.spawn(http_client::http_client( + tasks.spawn(http::client::http_client( our.name.clone(), kernel_message_sender.clone(), http_client_receiver, diff --git a/src/register.rs b/src/register.rs index 5c11df33..20ff1e23 100644 --- a/src/register.rs +++ b/src/register.rs @@ -17,7 +17,6 @@ use warp::{ Filter, Rejection, Reply, }; -use crate::http_server; use crate::keygen; use crate::types::*; @@ -29,7 +28,7 @@ pub fn generate_jwt(jwt_secret_bytes: &[u8], username: String) -> Option Err(_) => return None, }; - let claims = JwtClaims { + let claims = crate::http::types::JwtClaims { username: username.clone(), expiration: 0, }; @@ -304,7 +303,7 @@ async fn handle_info( }; // TODO: if IP is localhost, don't allow registration as direct - let ws_port = http_server::find_open_port(9000).await.unwrap(); + let ws_port = crate::http::utils::find_open_port(9000).await.unwrap(); let our = Identity { networking_key: format!("0x{}", public_key), diff --git a/src/types.rs b/src/types.rs index 6a4ac41e..ce8ff2f2 100644 --- a/src/types.rs +++ b/src/types.rs @@ -18,10 +18,10 @@ lazy_static::lazy_static! { // // types shared between kernel and processes. frustratingly, this is an exact copy -// of the types in process_lib/src/kernel_types.rs +// of the types in process_lib // this is because even though the types are identical, they will not match when // used in the kernel context which generates bindings differently than the process -// standard library. make sure to keep this synced with kernel_types.rs +// standard library. make sure to keep this synced with process_lib. // pub type Context = Vec; pub type NodeId = String; // QNS domain name @@ -382,7 +382,7 @@ pub fn de_wit_on_panic(wit: wit::OnPanic) -> OnPanic { } } // -// END SYNC WITH kernel_types.rs +// END SYNC WITH process_lib // // @@ -488,6 +488,24 @@ pub struct KernelMessage { pub signed_capabilities: Option>, } +impl std::fmt::Display for KernelMessage { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!( + f, + "{{\n id: {},\n source: {},\n target: {},\n rsvp: {},\n message: {},\n payload: {}\n}}", + self.id, + self.source, + self.target, + match &self.rsvp { + Some(rsvp) => rsvp.to_string(), + None => "None".to_string() + }, + self.message, + self.payload.is_some(), + ) + } +} + #[derive(Clone, Debug, Serialize, Deserialize)] pub struct WrappedSendError { pub id: u64, @@ -509,17 +527,6 @@ pub struct Printout { // -> kernel sets `Some(A) = Rsvp` for B's request to C pub type Rsvp = Option
; -// -// boot/startup specific types??? -// - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct BootOutboundRequest { - pub target_process: ProcessId, - pub json: Option, - pub bytes: Option>, -} - #[derive(Debug, Serialize, Deserialize)] pub enum DebugCommand { Toggle, @@ -545,7 +552,6 @@ pub enum KernelCommand { Shutdown, } -#[allow(dead_code)] #[derive(Debug)] pub enum CapMessage { Add { @@ -553,7 +559,7 @@ pub enum CapMessage { cap: Capability, responder: tokio::sync::oneshot::Sender, }, - Drop { + _Drop { // not used yet! on: ProcessId, cap: Capability, @@ -598,14 +604,6 @@ pub struct ProcessContext { pub context: Option, } -// -// runtime-module-specific types -// - -// -// filesystem.rs types -// - pub type PackageVersion = (u32, u32, u32); /// the type that gets deserialized from `metadata.json` in a package @@ -832,133 +830,3 @@ impl VfsError { } } } - -// -// custom kernel displays -// - -impl std::fmt::Display for KernelMessage { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!( - f, - "{{\n id: {},\n source: {},\n target: {},\n rsvp: {},\n message: {},\n payload: {}\n}}", - self.id, - self.source, - self.target, - match &self.rsvp { - Some(rsvp) => rsvp.to_string(), - None => "None".to_string() - }, - self.message, - self.payload.is_some(), - ) - } -} - -// -// http_server.rs types -// - -#[derive(Debug, Serialize, Deserialize)] -pub struct HttpResponse { - pub status: u16, - pub headers: HashMap, - pub body: Option>, // TODO does this use a lot of memory? -} - -#[derive(Error, Debug, Serialize, Deserialize)] -pub enum HttpServerError { - #[error("http_server: json is None")] - NoJson, - #[error("http_server: response not ok")] - ResponseError, - #[error("http_server: bytes are None")] - NoBytes, - #[error( - "http_server: JSON payload could not be parsed to HttpClientRequest: {error}. Got {:?}.", - json - )] - BadJson { json: String, error: String }, - #[error("http_server: path binding error: {:?}", error)] - PathBind { error: String }, -} - -#[allow(dead_code)] -impl HttpServerError { - pub fn kind(&self) -> &str { - match *self { - HttpServerError::NoJson { .. } => "NoJson", - HttpServerError::NoBytes { .. } => "NoBytes", - HttpServerError::BadJson { .. } => "BadJson", - HttpServerError::ResponseError { .. } => "ResponseError", - HttpServerError::PathBind { .. } => "PathBind", - } - } -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct JwtClaims { - pub username: String, - pub expiration: u64, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct WebSocketServerTarget { - pub node: String, - pub id: Option, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct WebSocketPush { - pub target: WebSocketServerTarget, - pub is_text: Option, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct ServerAction { - pub action: String, -} - -#[derive(Debug, Serialize, Deserialize)] -pub enum HttpServerMessage { - BindPath { - path: String, - authenticated: bool, - local_only: bool, - }, - WebSocketPush(WebSocketPush), - ServerAction(ServerAction), -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct WsRegister { - pub ws_auth_token: String, - pub auth_token: String, - pub channel_id: String, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct WsMessage { - pub ws_auth_token: String, - pub auth_token: String, - pub channel_id: String, - pub target: Address, - pub json: Option, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct EncryptedWsMessage { - pub ws_auth_token: String, - pub auth_token: String, - pub channel_id: String, - pub target: Address, - pub encrypted: String, // Encrypted JSON as hex with the 32-byte authentication tag appended - pub nonce: String, // Hex of the 12-byte nonce -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub enum WebSocketClientMessage { - WsRegister(WsRegister), - WsMessage(WsMessage), - EncryptedWsMessage(EncryptedWsMessage), -}