mirror of
https://github.com/uqbar-dao/nectar.git
synced 2024-12-29 19:41:39 +03:00
switch all modules to uqbar@0.2.0
This commit is contained in:
parent
4693b5c14f
commit
d40989f8f7
@ -195,10 +195,7 @@ impl Guest for Component {
|
||||
};
|
||||
match message {
|
||||
Message::Request(req) => {
|
||||
let Some(ref ipc) = req.ipc else {
|
||||
continue;
|
||||
};
|
||||
match &serde_json::from_str::<Req>(ipc) {
|
||||
match &serde_json::from_slice::<Req>(&req.ipc) {
|
||||
Ok(Req::LocalRequest(local_request)) => {
|
||||
match handle_local_request(&our, &source, local_request, &mut state) {
|
||||
Ok(None) => continue,
|
||||
@ -207,7 +204,7 @@ impl Guest for Component {
|
||||
send_response(
|
||||
&Response {
|
||||
inherit: false,
|
||||
ipc: Some(serde_json::to_string(&resp).unwrap()),
|
||||
ipc: serde_json::to_vec(&resp).unwrap(),
|
||||
metadata: None,
|
||||
},
|
||||
None,
|
||||
@ -230,7 +227,7 @@ impl Guest for Component {
|
||||
send_response(
|
||||
&Response {
|
||||
inherit: false,
|
||||
ipc: Some(serde_json::to_string(&resp).unwrap()),
|
||||
ipc: serde_json::to_vec(&resp).unwrap(),
|
||||
metadata: None,
|
||||
},
|
||||
None,
|
||||
@ -270,15 +267,13 @@ impl Guest for Component {
|
||||
&Request {
|
||||
inherit: true, // will inherit payload!
|
||||
expects_response: None,
|
||||
ipc: Some(
|
||||
serde_json::to_string(&Req::LocalRequest(
|
||||
LocalRequest::NewPackage {
|
||||
package: package_id,
|
||||
mirror: true,
|
||||
},
|
||||
))
|
||||
.unwrap(),
|
||||
),
|
||||
ipc: serde_json::to_vec(&Req::LocalRequest(
|
||||
LocalRequest::NewPackage {
|
||||
package: package_id,
|
||||
mirror: true,
|
||||
},
|
||||
))
|
||||
.unwrap(),
|
||||
metadata: None,
|
||||
},
|
||||
None,
|
||||
@ -287,22 +282,19 @@ impl Guest for Component {
|
||||
}
|
||||
}
|
||||
Ok(Req::FTWorkerCommand(_)) => {
|
||||
spawn_receive_transfer(&our, ipc);
|
||||
spawn_receive_transfer(&our, &req.ipc);
|
||||
}
|
||||
e => {
|
||||
print_to_terminal(
|
||||
0,
|
||||
&format!("app store bad request: {}, error {:?}", ipc, e),
|
||||
&format!("app store bad request: {:?}, error {:?}", req.ipc, e),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
Message::Response((response, context)) => {
|
||||
let Some(ref ipc) = response.ipc else {
|
||||
continue;
|
||||
};
|
||||
match &serde_json::from_str::<Resp>(ipc) {
|
||||
match &serde_json::from_slice::<Resp>(&response.ipc) {
|
||||
Ok(Resp::RemoteResponse(remote_response)) => match remote_response {
|
||||
RemoteResponse::DownloadApproved => {
|
||||
print_to_terminal(
|
||||
@ -318,7 +310,7 @@ impl Guest for Component {
|
||||
}
|
||||
},
|
||||
Ok(Resp::FTWorkerResult(ft_worker_result)) => {
|
||||
let Ok(context) = serde_json::from_str::<FileTransferContext>(&context.unwrap_or_default()) else {
|
||||
let Ok(context) = serde_json::from_slice::<FileTransferContext>(&context.unwrap_or_default()) else {
|
||||
print_to_terminal(0, "file_transfer: got weird local request");
|
||||
continue;
|
||||
};
|
||||
@ -347,7 +339,10 @@ impl Guest for Component {
|
||||
e => {
|
||||
print_to_terminal(
|
||||
0,
|
||||
&format!("app store bad response: {}, error {:?}", ipc, e),
|
||||
&format!(
|
||||
"app store bad response: {:?}, error {:?}",
|
||||
response.ipc, e
|
||||
),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
@ -385,10 +380,10 @@ fn handle_local_request(
|
||||
let _ = process_lib::send_and_await_response(
|
||||
&vfs_address,
|
||||
false,
|
||||
Some(serde_json::to_string(&kt::VfsRequest {
|
||||
serde_json::to_vec(&kt::VfsRequest {
|
||||
drive: package.to_string(),
|
||||
action: kt::VfsAction::New,
|
||||
})?),
|
||||
})?,
|
||||
None,
|
||||
None,
|
||||
5,
|
||||
@ -399,13 +394,13 @@ fn handle_local_request(
|
||||
let _ = process_lib::send_and_await_response(
|
||||
&vfs_address,
|
||||
true,
|
||||
Some(serde_json::to_string(&kt::VfsRequest {
|
||||
serde_json::to_vec(&kt::VfsRequest {
|
||||
drive: package.to_string(),
|
||||
action: kt::VfsAction::Add {
|
||||
full_path: package.to_string(),
|
||||
entry_type: kt::AddEntryType::ZipArchive,
|
||||
},
|
||||
})?),
|
||||
})?,
|
||||
None,
|
||||
Some(&payload),
|
||||
5,
|
||||
@ -416,13 +411,13 @@ fn handle_local_request(
|
||||
let _ = process_lib::send_and_await_response(
|
||||
&vfs_address,
|
||||
true,
|
||||
Some(serde_json::to_string(&kt::VfsRequest {
|
||||
serde_json::to_vec(&kt::VfsRequest {
|
||||
drive: package.to_string(),
|
||||
action: kt::VfsAction::Add {
|
||||
full_path: format!("/{}.zip", package.to_string()),
|
||||
entry_type: kt::AddEntryType::NewFile,
|
||||
},
|
||||
})?),
|
||||
})?,
|
||||
None,
|
||||
Some(&payload),
|
||||
5,
|
||||
@ -431,10 +426,10 @@ fn handle_local_request(
|
||||
let _ = process_lib::send_and_await_response(
|
||||
&vfs_address,
|
||||
false,
|
||||
Some(serde_json::to_string(&kt::VfsRequest {
|
||||
serde_json::to_vec(&kt::VfsRequest {
|
||||
drive: package.to_string(),
|
||||
action: kt::VfsAction::GetEntry("/metadata.json".into()),
|
||||
})?),
|
||||
})?,
|
||||
None,
|
||||
None,
|
||||
5,
|
||||
@ -473,18 +468,13 @@ fn handle_local_request(
|
||||
process: our.process.clone(),
|
||||
},
|
||||
true,
|
||||
Some(serde_json::to_string(&RemoteRequest::Download(
|
||||
package.clone(),
|
||||
))?),
|
||||
serde_json::to_vec(&RemoteRequest::Download(package.clone()))?,
|
||||
None,
|
||||
None,
|
||||
5,
|
||||
) {
|
||||
Ok((_source, Message::Response((resp, _context)))) => {
|
||||
let Some(ipc) = resp.ipc else {
|
||||
return Err(anyhow::anyhow!("no ipc in response"))
|
||||
};
|
||||
let resp = serde_json::from_str::<Resp>(&ipc)?;
|
||||
let resp = serde_json::from_slice::<Resp>(&resp.ipc)?;
|
||||
match resp {
|
||||
Resp::RemoteResponse(RemoteResponse::DownloadApproved) => {
|
||||
state.requested_packages.insert(package.clone());
|
||||
@ -505,10 +495,10 @@ fn handle_local_request(
|
||||
let _ = process_lib::send_and_await_response(
|
||||
&vfs_address,
|
||||
false,
|
||||
Some(serde_json::to_string(&kt::VfsRequest {
|
||||
serde_json::to_vec(&kt::VfsRequest {
|
||||
drive: package.to_string(),
|
||||
action: kt::VfsAction::GetEntry("/manifest.json".into()),
|
||||
})?),
|
||||
})?,
|
||||
None,
|
||||
None,
|
||||
5,
|
||||
@ -528,19 +518,19 @@ fn handle_local_request(
|
||||
let (_, hash_response) = process_lib::send_and_await_response(
|
||||
&vfs_address,
|
||||
false,
|
||||
Some(serde_json::to_string(&kt::VfsRequest {
|
||||
serde_json::to_vec(&kt::VfsRequest {
|
||||
drive: package.to_string(),
|
||||
action: kt::VfsAction::GetHash(path.clone()),
|
||||
})?),
|
||||
})?,
|
||||
None,
|
||||
None,
|
||||
5,
|
||||
)?;
|
||||
|
||||
let Message::Response((Response { ipc: Some(ipc), .. }, _)) = hash_response else {
|
||||
let Message::Response((Response { ipc, .. }, _)) = hash_response else {
|
||||
return Err(anyhow::anyhow!("bad vfs response"));
|
||||
};
|
||||
let kt::VfsResponse::GetHash(Some(hash)) = serde_json::from_str(&ipc)? else {
|
||||
let kt::VfsResponse::GetHash(Some(hash)) = serde_json::from_slice(&ipc)? else {
|
||||
return Err(anyhow::anyhow!("no hash in vfs"));
|
||||
};
|
||||
|
||||
@ -607,9 +597,9 @@ fn handle_local_request(
|
||||
process: ProcessId::from_str("kernel:sys:uqbar")?,
|
||||
},
|
||||
false,
|
||||
Some(serde_json::to_string(&kt::KernelCommand::KillProcess(
|
||||
kt::ProcessId::de_wit(parsed_new_process_id.clone()),
|
||||
))?),
|
||||
serde_json::to_vec(&kt::KernelCommand::KillProcess(kt::ProcessId::de_wit(
|
||||
parsed_new_process_id.clone(),
|
||||
)))?,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
@ -620,10 +610,10 @@ fn handle_local_request(
|
||||
let (_, _bytes_response) = process_lib::send_and_await_response(
|
||||
&vfs_address,
|
||||
false,
|
||||
Some(serde_json::to_string(&kt::VfsRequest {
|
||||
serde_json::to_vec(&kt::VfsRequest {
|
||||
drive: package.to_string(),
|
||||
action: kt::VfsAction::GetEntry(path),
|
||||
})?),
|
||||
})?,
|
||||
None,
|
||||
None,
|
||||
5,
|
||||
@ -639,13 +629,13 @@ fn handle_local_request(
|
||||
process: ProcessId::from_str("kernel:sys:uqbar")?,
|
||||
},
|
||||
false,
|
||||
Some(serde_json::to_string(&kt::KernelCommand::StartProcess {
|
||||
serde_json::to_vec(&kt::KernelCommand::StartProcess {
|
||||
id: kt::ProcessId::de_wit(parsed_new_process_id),
|
||||
wasm_bytes_handle: hash,
|
||||
on_panic: entry.on_panic,
|
||||
initial_capabilities,
|
||||
public: entry.public,
|
||||
})?),
|
||||
})?,
|
||||
None,
|
||||
Some(&payload),
|
||||
5,
|
||||
@ -687,10 +677,10 @@ fn handle_remote_request(
|
||||
let _ = process_lib::send_and_await_response(
|
||||
&vfs_address,
|
||||
false,
|
||||
Some(serde_json::to_string(&kt::VfsRequest {
|
||||
serde_json::to_vec(&kt::VfsRequest {
|
||||
drive: package.to_string(),
|
||||
action: kt::VfsAction::GetEntry(file_name.clone()),
|
||||
})?),
|
||||
})?,
|
||||
None,
|
||||
None,
|
||||
5,
|
||||
|
@ -76,33 +76,29 @@ pub fn spawn_transfer(
|
||||
&Request {
|
||||
inherit: !payload_or_inherit.is_some(),
|
||||
expects_response: Some(61),
|
||||
ipc: Some(
|
||||
serde_json::to_string(&FTWorkerCommand::Send {
|
||||
target: to_addr.to_string(),
|
||||
file_name: file_name.into(),
|
||||
timeout: 60,
|
||||
})
|
||||
.unwrap(),
|
||||
),
|
||||
metadata: None,
|
||||
},
|
||||
Some(
|
||||
&serde_json::to_string(&FileTransferContext {
|
||||
ipc: serde_json::to_vec(&FTWorkerCommand::Send {
|
||||
target: to_addr.to_string(),
|
||||
file_name: file_name.into(),
|
||||
file_size: match &payload_or_inherit {
|
||||
Some(p) => Some(p.bytes.len() as u64),
|
||||
None => None, // TODO
|
||||
},
|
||||
start_time: std::time::SystemTime::now(),
|
||||
timeout: 60,
|
||||
})
|
||||
.unwrap(),
|
||||
),
|
||||
metadata: None,
|
||||
},
|
||||
Some(&serde_json::to_vec(&FileTransferContext {
|
||||
file_name: file_name.into(),
|
||||
file_size: match &payload_or_inherit {
|
||||
Some(p) => Some(p.bytes.len() as u64),
|
||||
None => None, // TODO
|
||||
},
|
||||
start_time: std::time::SystemTime::now(),
|
||||
})
|
||||
.unwrap()),
|
||||
payload_or_inherit.as_ref(),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn spawn_receive_transfer(our: &Address, ipc: &str) {
|
||||
let Ok(FTWorkerCommand::Receive { transfer_id, .. }) = serde_json::from_str(ipc) else {
|
||||
pub fn spawn_receive_transfer(our: &Address, ipc: &[u8]) {
|
||||
let Ok(FTWorkerCommand::Receive { transfer_id, .. }) = serde_json::from_slice(ipc) else {
|
||||
print_to_terminal(0, "file_transfer: got weird request");
|
||||
return;
|
||||
};
|
||||
@ -125,7 +121,7 @@ pub fn spawn_receive_transfer(our: &Address, ipc: &str) {
|
||||
&Request {
|
||||
inherit: true,
|
||||
expects_response: None,
|
||||
ipc: Some(ipc.to_string()),
|
||||
ipc: ipc.to_vec(),
|
||||
metadata: None,
|
||||
},
|
||||
None,
|
||||
|
@ -25,10 +25,8 @@ impl Guest for Component {
|
||||
panic!("ft_worker: got bad init message");
|
||||
};
|
||||
|
||||
let command = serde_json::from_str::<FTWorkerCommand>(
|
||||
&req.ipc.expect("ft_worker: got empty init message"),
|
||||
)
|
||||
.expect("ft_worker: got unparseable init message");
|
||||
let command = serde_json::from_slice::<FTWorkerCommand>(&req.ipc)
|
||||
.expect("ft_worker: got unparseable init message");
|
||||
|
||||
match command {
|
||||
FTWorkerCommand::Send {
|
||||
@ -56,16 +54,14 @@ impl Guest for Component {
|
||||
&Request {
|
||||
inherit: false,
|
||||
expects_response: Some(timeout),
|
||||
ipc: Some(
|
||||
serde_json::to_string(&FTWorkerCommand::Receive {
|
||||
transfer_id,
|
||||
file_name,
|
||||
file_size,
|
||||
total_chunks,
|
||||
timeout,
|
||||
})
|
||||
.unwrap(),
|
||||
),
|
||||
ipc: serde_json::to_vec(&FTWorkerCommand::Receive {
|
||||
transfer_id,
|
||||
file_name,
|
||||
file_size,
|
||||
total_chunks,
|
||||
timeout,
|
||||
})
|
||||
.unwrap(),
|
||||
metadata: None,
|
||||
},
|
||||
None,
|
||||
@ -77,7 +73,7 @@ impl Guest for Component {
|
||||
}))
|
||||
}
|
||||
Ok((opp_worker, Message::Response((response, _)))) => {
|
||||
let Ok(FTWorkerProtocol::Ready) = serde_json::from_str(&response.ipc.expect("ft_worker: got empty response")) else {
|
||||
let Ok(FTWorkerProtocol::Ready) = serde_json::from_slice(&response.ipc) else {
|
||||
respond_to_parent(FTWorkerResult::Err(TransferError::TargetRejected));
|
||||
return;
|
||||
};
|
||||
@ -97,7 +93,7 @@ impl Guest for Component {
|
||||
&Request {
|
||||
inherit: false,
|
||||
expects_response: Some(timeout),
|
||||
ipc: None,
|
||||
ipc: vec![],
|
||||
metadata: None,
|
||||
},
|
||||
None,
|
||||
@ -116,7 +112,7 @@ impl Guest for Component {
|
||||
&Request {
|
||||
inherit: false,
|
||||
expects_response: None,
|
||||
ipc: None,
|
||||
ipc: vec![],
|
||||
metadata: None,
|
||||
},
|
||||
None,
|
||||
@ -130,9 +126,7 @@ impl Guest for Component {
|
||||
respond_to_parent(FTWorkerResult::Err(TransferError::TargetRejected));
|
||||
return;
|
||||
};
|
||||
let Ok(FTWorkerProtocol::Finished) = serde_json::from_str(
|
||||
&resp.ipc.expect("ft_worker: got empty response"),
|
||||
) else {
|
||||
let Ok(FTWorkerProtocol::Finished) = serde_json::from_slice(&resp.ipc) else {
|
||||
respond_to_parent(FTWorkerResult::Err(TransferError::TargetRejected));
|
||||
return;
|
||||
};
|
||||
@ -153,7 +147,7 @@ impl Guest for Component {
|
||||
send_response(
|
||||
&Response {
|
||||
inherit: false,
|
||||
ipc: Some(serde_json::to_string(&FTWorkerProtocol::Ready).unwrap()),
|
||||
ipc: serde_json::to_vec(&FTWorkerProtocol::Ready).unwrap(),
|
||||
metadata: None,
|
||||
},
|
||||
None,
|
||||
@ -187,7 +181,7 @@ impl Guest for Component {
|
||||
send_response(
|
||||
&Response {
|
||||
inherit: false,
|
||||
ipc: Some(serde_json::to_string(&FTWorkerProtocol::Finished).unwrap()),
|
||||
ipc: serde_json::to_vec(&FTWorkerProtocol::Finished).unwrap(),
|
||||
metadata: None,
|
||||
},
|
||||
None,
|
||||
@ -198,10 +192,8 @@ impl Guest for Component {
|
||||
&Request {
|
||||
inherit: false,
|
||||
expects_response: None,
|
||||
ipc: Some(
|
||||
serde_json::to_string(&FTWorkerResult::ReceiveSuccess(file_name))
|
||||
.unwrap(),
|
||||
),
|
||||
ipc: serde_json::to_vec(&FTWorkerResult::ReceiveSuccess(file_name))
|
||||
.unwrap(),
|
||||
metadata: None,
|
||||
},
|
||||
None,
|
||||
@ -219,7 +211,7 @@ fn respond_to_parent(result: FTWorkerResult) {
|
||||
send_response(
|
||||
&Response {
|
||||
inherit: false,
|
||||
ipc: Some(serde_json::to_string(&result).unwrap()),
|
||||
ipc: serde_json::to_vec(&result).unwrap(),
|
||||
metadata: None,
|
||||
},
|
||||
None,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,9 @@
|
||||
cargo_component_bindings::generate!();
|
||||
|
||||
use bindings::{print_to_terminal, receive, send_request, send_requests, send_response, get_payload, Guest};
|
||||
use bindings::component::uq_process::types::*;
|
||||
use bindings::{
|
||||
get_payload, print_to_terminal, receive, send_request, send_requests, send_response, Guest,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
#[allow(dead_code)]
|
||||
@ -11,23 +13,30 @@ struct Component;
|
||||
|
||||
const HOME_PAGE: &str = include_str!("home.html");
|
||||
|
||||
fn generate_http_binding(add: Address, path: &str, authenticated: bool) -> (Address, Request, Option<Context>, Option<Payload>) {
|
||||
fn generate_http_binding(
|
||||
add: Address,
|
||||
path: &str,
|
||||
authenticated: bool,
|
||||
) -> (Address, Request, Option<Context>, Option<Payload>) {
|
||||
(
|
||||
add,
|
||||
Request {
|
||||
inherit: false,
|
||||
expects_response: None,
|
||||
ipc: Some(json!({
|
||||
ipc: json!({
|
||||
"BindPath": {
|
||||
"path": path,
|
||||
"authenticated": authenticated,
|
||||
"local_only": false
|
||||
}
|
||||
}).to_string()),
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
metadata: None,
|
||||
},
|
||||
None,
|
||||
None
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
@ -41,9 +50,8 @@ impl Guest for Component {
|
||||
};
|
||||
|
||||
// <address, request, option<context>, option<payload>>
|
||||
let http_endpoint_binding_requests: [(Address, Request, Option<Context>, Option<Payload>); 1] = [
|
||||
generate_http_binding(bindings_address.clone(), "/", true),
|
||||
];
|
||||
let http_endpoint_binding_requests: [(Address, Request, Option<Context>, Option<Payload>);
|
||||
1] = [generate_http_binding(bindings_address.clone(), "/", true)];
|
||||
send_requests(&http_endpoint_binding_requests);
|
||||
|
||||
loop {
|
||||
@ -56,122 +64,136 @@ impl Guest for Component {
|
||||
continue;
|
||||
};
|
||||
|
||||
if let Some(json) = request.ipc {
|
||||
print_to_terminal(1, format!("homepage: JSON {}", json).as_str());
|
||||
let message_json: serde_json::Value = match serde_json::from_str(&json) {
|
||||
Ok(v) => v,
|
||||
Err(_) => {
|
||||
print_to_terminal(1, "homepage: failed to parse ipc JSON, skipping");
|
||||
continue;
|
||||
let message_json: serde_json::Value = match serde_json::from_slice(&request.ipc) {
|
||||
Ok(v) => v,
|
||||
Err(_) => {
|
||||
print_to_terminal(1, "homepage: failed to parse ipc JSON, skipping");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
if message_json["path"] == "/" && message_json["method"] == "GET" {
|
||||
print_to_terminal(1, "homepage: sending response");
|
||||
|
||||
send_response(
|
||||
&Response {
|
||||
inherit: false,
|
||||
ipc: serde_json::json!({
|
||||
"action": "response",
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"Content-Type": "text/html",
|
||||
},
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
metadata: None,
|
||||
},
|
||||
};
|
||||
|
||||
print_to_terminal(1, "homepage: parsed ipc JSON");
|
||||
|
||||
if message_json["path"] == "/" && message_json["method"] == "GET" {
|
||||
print_to_terminal(1, "homepage: sending response");
|
||||
|
||||
send_response(
|
||||
&Response {
|
||||
inherit: false,
|
||||
ipc: Some(serde_json::json!({
|
||||
"action": "response",
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"Content-Type": "text/html",
|
||||
Some(&Payload {
|
||||
mime: Some("text/html".to_string()),
|
||||
bytes: HOME_PAGE
|
||||
.replace("${our}", &our.node)
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
}),
|
||||
);
|
||||
} else if message_json["path"].is_string() {
|
||||
send_response(
|
||||
&Response {
|
||||
inherit: false,
|
||||
ipc: json!({
|
||||
"action": "response",
|
||||
"status": 404,
|
||||
"headers": {
|
||||
"Content-Type": "text/html",
|
||||
},
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
metadata: None,
|
||||
},
|
||||
Some(&Payload {
|
||||
mime: Some("text/html".to_string()),
|
||||
bytes: "Not Found".to_string().as_bytes().to_vec(),
|
||||
}),
|
||||
);
|
||||
} else if message_json["hello"] == "world" {
|
||||
send_response(
|
||||
&Response {
|
||||
inherit: false,
|
||||
ipc: serde_json::json!({
|
||||
"hello": "to you too"
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
metadata: None,
|
||||
},
|
||||
Some(&Payload {
|
||||
mime: Some("application/json".to_string()),
|
||||
bytes: serde_json::json!({
|
||||
"hello": "to you too"
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
if let Some(payload) = get_payload() {
|
||||
if let Ok(json) = serde_json::from_slice::<serde_json::Value>(&payload.bytes) {
|
||||
print_to_terminal(1, format!("JSON: {}", json).as_str());
|
||||
if json["message"] == "ping" {
|
||||
// WebSocket pushes are sent as requests
|
||||
send_request(
|
||||
&Address {
|
||||
node: our.node.clone(),
|
||||
process: ProcessId::from_str("encryptor:sys:uqbar").unwrap(),
|
||||
},
|
||||
}).to_string()),
|
||||
metadata: None,
|
||||
},
|
||||
Some(&Payload {
|
||||
mime: Some("text/html".to_string()),
|
||||
bytes: HOME_PAGE.replace("${our}", &our.node).to_string().as_bytes().to_vec(),
|
||||
}),
|
||||
);
|
||||
} else if message_json["path"].is_string() {
|
||||
send_response(
|
||||
&Response {
|
||||
inherit: false,
|
||||
ipc: Some(json!({
|
||||
"action": "response",
|
||||
"status": 404,
|
||||
"headers": {
|
||||
"Content-Type": "text/html",
|
||||
},
|
||||
}).to_string()),
|
||||
metadata: None,
|
||||
},
|
||||
Some(&Payload {
|
||||
mime: Some("text/html".to_string()),
|
||||
bytes: "Not Found"
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
}),
|
||||
);
|
||||
} else if message_json["hello"] == "world" {
|
||||
send_response(
|
||||
&Response {
|
||||
inherit: false,
|
||||
ipc: Some(serde_json::json!({
|
||||
"hello": "to you too"
|
||||
}).to_string()),
|
||||
metadata: None,
|
||||
},
|
||||
Some(&Payload {
|
||||
mime: Some("application/json".to_string()),
|
||||
bytes: serde_json::json!({
|
||||
"hello": "to you too"
|
||||
}).to_string().as_bytes().to_vec(),
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
if let Some(payload) = get_payload() {
|
||||
if let Ok(json) = serde_json::from_slice::<serde_json::Value>(&payload.bytes) {
|
||||
print_to_terminal(1, format!("JSON: {}", json).as_str());
|
||||
if json["message"] == "ping" {
|
||||
// WebSocket pushes are sent as requests
|
||||
send_request(
|
||||
&Address {
|
||||
node: our.node.clone(),
|
||||
process: ProcessId::from_str("encryptor:sys:uqbar").unwrap(),
|
||||
},
|
||||
&Request {
|
||||
inherit: false,
|
||||
expects_response: None,
|
||||
ipc: Some(serde_json::json!({
|
||||
"EncryptAndForwardAction": {
|
||||
"channel_id": "homepage",
|
||||
"forward_to": {
|
||||
"node": our.node.clone(),
|
||||
"process": {
|
||||
"process_name": "http_server",
|
||||
"package_name": "sys",
|
||||
"publisher_node": "uqbar"
|
||||
&Request {
|
||||
inherit: false,
|
||||
expects_response: None,
|
||||
ipc: serde_json::json!({
|
||||
"EncryptAndForwardAction": {
|
||||
"channel_id": "homepage",
|
||||
"forward_to": {
|
||||
"node": our.node.clone(),
|
||||
"process": {
|
||||
"process_name": "http_server",
|
||||
"package_name": "sys",
|
||||
"publisher_node": "uqbar"
|
||||
}
|
||||
}, // node, process
|
||||
"json": Some(serde_json::json!({ // this is the JSON to forward
|
||||
"WebSocketPush": {
|
||||
"target": {
|
||||
"node": our.node.clone(),
|
||||
"id": "homepage", // If the message passed in an ID then we could send to just that ID
|
||||
}
|
||||
}, // node, process
|
||||
"json": Some(serde_json::json!({ // this is the JSON to forward
|
||||
"WebSocketPush": {
|
||||
"target": {
|
||||
"node": our.node.clone(),
|
||||
"id": "homepage", // If the message passed in an ID then we could send to just that ID
|
||||
}
|
||||
}
|
||||
})),
|
||||
}
|
||||
}
|
||||
})),
|
||||
}
|
||||
|
||||
}).to_string()),
|
||||
metadata: None,
|
||||
},
|
||||
None,
|
||||
Some(&Payload {
|
||||
mime: Some("application/json".to_string()),
|
||||
bytes: serde_json::json!({
|
||||
"pong": true
|
||||
}).to_string().as_bytes().to_vec(),
|
||||
}),
|
||||
);
|
||||
}
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
metadata: None,
|
||||
},
|
||||
None,
|
||||
Some(&Payload {
|
||||
mime: Some("application/json".to_string()),
|
||||
bytes: serde_json::json!({
|
||||
"pong": true
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,18 +16,17 @@ const PROXY_HOME_PAGE: &str = include_str!("http_proxy.html");
|
||||
|
||||
struct Component;
|
||||
|
||||
|
||||
fn send_http_response(status: u16, headers: HashMap<String, String>, payload_bytes: Vec<u8>) {
|
||||
send_response(
|
||||
&Response {
|
||||
inherit: false,
|
||||
ipc: Some(
|
||||
serde_json::json!({
|
||||
"status": status,
|
||||
"headers": headers,
|
||||
})
|
||||
.to_string(),
|
||||
),
|
||||
ipc: serde_json::json!({
|
||||
"status": status,
|
||||
"headers": headers,
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
metadata: None,
|
||||
},
|
||||
Some(&Payload {
|
||||
@ -64,13 +63,16 @@ impl Guest for Component {
|
||||
Request {
|
||||
inherit: false,
|
||||
expects_response: None,
|
||||
ipc: Some(json!({
|
||||
ipc: json!({
|
||||
"BindPath": {
|
||||
"path": "/",
|
||||
"authenticated": true,
|
||||
"local_only": false
|
||||
}
|
||||
}).to_string()),
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
metadata: None,
|
||||
},
|
||||
None,
|
||||
@ -81,13 +83,16 @@ impl Guest for Component {
|
||||
Request {
|
||||
inherit: false,
|
||||
expects_response: None,
|
||||
ipc: Some(json!({
|
||||
ipc: json!({
|
||||
"BindPath": {
|
||||
"path": "/static/*",
|
||||
"authenticated": true,
|
||||
"local_only": false
|
||||
}
|
||||
}).to_string()),
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
metadata: None,
|
||||
},
|
||||
None,
|
||||
@ -98,13 +103,16 @@ impl Guest for Component {
|
||||
Request {
|
||||
inherit: false,
|
||||
expects_response: None,
|
||||
ipc: Some(json!({
|
||||
ipc: json!({
|
||||
"BindPath": {
|
||||
"path": "/list",
|
||||
"authenticated": true,
|
||||
"local_only": false
|
||||
}
|
||||
}).to_string()),
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
metadata: None,
|
||||
},
|
||||
None,
|
||||
@ -115,13 +123,16 @@ impl Guest for Component {
|
||||
Request {
|
||||
inherit: false,
|
||||
expects_response: None,
|
||||
ipc: Some(json!({
|
||||
ipc: json!({
|
||||
"BindPath": {
|
||||
"path": "/register",
|
||||
"authenticated": true,
|
||||
"local_only": false
|
||||
}
|
||||
}).to_string()),
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
metadata: None,
|
||||
},
|
||||
None,
|
||||
@ -132,13 +143,16 @@ impl Guest for Component {
|
||||
Request {
|
||||
inherit: false,
|
||||
expects_response: None,
|
||||
ipc: Some(json!({
|
||||
ipc: json!({
|
||||
"BindPath": {
|
||||
"path": "/serve/:username/*",
|
||||
"authenticated": true,
|
||||
"local_only": false
|
||||
}
|
||||
}).to_string()),
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
metadata: None,
|
||||
},
|
||||
None,
|
||||
@ -160,12 +174,7 @@ impl Guest for Component {
|
||||
continue;
|
||||
};
|
||||
|
||||
let Some(json) = request.ipc else {
|
||||
print_to_terminal(1, "http_proxy: no ipc json");
|
||||
continue;
|
||||
};
|
||||
|
||||
let message_json: serde_json::Value = match serde_json::from_str(&json) {
|
||||
let message_json: serde_json::Value = match serde_json::from_slice(&request.ipc) {
|
||||
Ok(v) => v,
|
||||
Err(_) => {
|
||||
print_to_terminal(1, "http_proxy: failed to parse ipc JSON, skipping");
|
||||
@ -182,16 +191,16 @@ impl Guest for Component {
|
||||
send_response(
|
||||
&Response {
|
||||
inherit: false,
|
||||
ipc: Some(
|
||||
serde_json::json!({
|
||||
"action": "response",
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"Content-Type": "text/html",
|
||||
},
|
||||
})
|
||||
.to_string(),
|
||||
),
|
||||
ipc: serde_json::json!({
|
||||
"action": "response",
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"Content-Type": "text/html",
|
||||
},
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
metadata: None,
|
||||
},
|
||||
Some(&Payload {
|
||||
@ -202,21 +211,20 @@ impl Guest for Component {
|
||||
.to_vec(),
|
||||
}),
|
||||
);
|
||||
} else if message_json["path"] == "/list" && message_json["method"] == "GET"
|
||||
{
|
||||
} else if message_json["path"] == "/list" && message_json["method"] == "GET" {
|
||||
send_response(
|
||||
&Response {
|
||||
inherit: false,
|
||||
ipc: Some(
|
||||
serde_json::json!({
|
||||
"action": "response",
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
.to_string(),
|
||||
),
|
||||
ipc: serde_json::json!({
|
||||
"action": "response",
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
metadata: None,
|
||||
},
|
||||
Some(&Payload {
|
||||
@ -227,9 +235,7 @@ impl Guest for Component {
|
||||
.to_vec(),
|
||||
}),
|
||||
);
|
||||
} else if message_json["path"] == "/register"
|
||||
&& message_json["method"] == "POST"
|
||||
{
|
||||
} else if message_json["path"] == "/register" && message_json["method"] == "POST" {
|
||||
let mut status = 204;
|
||||
|
||||
let Some(payload) = get_payload() else {
|
||||
@ -258,16 +264,16 @@ impl Guest for Component {
|
||||
send_response(
|
||||
&Response {
|
||||
inherit: false,
|
||||
ipc: Some(
|
||||
serde_json::json!({
|
||||
"action": "response",
|
||||
"status": status,
|
||||
"headers": {
|
||||
"Content-Type": "text/html",
|
||||
},
|
||||
})
|
||||
.to_string(),
|
||||
),
|
||||
ipc: serde_json::json!({
|
||||
"action": "response",
|
||||
"status": status,
|
||||
"headers": {
|
||||
"Content-Type": "text/html",
|
||||
},
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
metadata: None,
|
||||
},
|
||||
Some(&Payload {
|
||||
@ -282,9 +288,7 @@ impl Guest for Component {
|
||||
.to_vec(),
|
||||
}),
|
||||
);
|
||||
} else if message_json["path"] == "/register"
|
||||
&& message_json["method"] == "DELETE"
|
||||
{
|
||||
} else if message_json["path"] == "/register" && message_json["method"] == "DELETE" {
|
||||
print_to_terminal(1, "HERE IN /register to delete something");
|
||||
let username = message_json["query_params"]["username"]
|
||||
.as_str()
|
||||
@ -301,16 +305,16 @@ impl Guest for Component {
|
||||
send_response(
|
||||
&Response {
|
||||
inherit: false,
|
||||
ipc: Some(
|
||||
serde_json::json!({
|
||||
"action": "response",
|
||||
"status": status,
|
||||
"headers": {
|
||||
"Content-Type": "text/html",
|
||||
},
|
||||
})
|
||||
.to_string(),
|
||||
),
|
||||
ipc: serde_json::json!({
|
||||
"action": "response",
|
||||
"status": status,
|
||||
"headers": {
|
||||
"Content-Type": "text/html",
|
||||
},
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
metadata: None,
|
||||
},
|
||||
Some(&Payload {
|
||||
@ -338,16 +342,16 @@ impl Guest for Component {
|
||||
send_response(
|
||||
&Response {
|
||||
inherit: false,
|
||||
ipc: Some(
|
||||
json!({
|
||||
"action": "response",
|
||||
"status": 403,
|
||||
"headers": {
|
||||
"Content-Type": "text/html",
|
||||
},
|
||||
})
|
||||
.to_string(),
|
||||
),
|
||||
ipc: json!({
|
||||
"action": "response",
|
||||
"status": 403,
|
||||
"headers": {
|
||||
"Content-Type": "text/html",
|
||||
},
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
metadata: None,
|
||||
},
|
||||
Some(&Payload {
|
||||
@ -374,16 +378,16 @@ impl Guest for Component {
|
||||
&Request {
|
||||
inherit: true,
|
||||
expects_response: None,
|
||||
ipc: Some(
|
||||
json!({
|
||||
"method": message_json["method"],
|
||||
"path": proxied_path,
|
||||
"headers": message_json["headers"],
|
||||
"proxy_path": raw_path,
|
||||
"query_params": message_json["query_params"],
|
||||
})
|
||||
.to_string(),
|
||||
),
|
||||
ipc: json!({
|
||||
"method": message_json["method"],
|
||||
"path": proxied_path,
|
||||
"headers": message_json["headers"],
|
||||
"proxy_path": raw_path,
|
||||
"query_params": message_json["query_params"],
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
metadata: None,
|
||||
},
|
||||
None,
|
||||
|
@ -5,7 +5,10 @@ use std::collections::HashMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use bindings::component::uq_process::types::*;
|
||||
use bindings::{create_capability, get_capability, has_capability, Guest, print_to_terminal, receive, send_request, send_response, spawn};
|
||||
use bindings::{
|
||||
create_capability, get_capability, has_capability, print_to_terminal, receive, send_request,
|
||||
send_response, spawn, Guest,
|
||||
};
|
||||
|
||||
mod kernel_types;
|
||||
use kernel_types as kt;
|
||||
@ -23,14 +26,16 @@ fn make_vfs_cap(kind: &str, drive: &str) -> String {
|
||||
serde_json::to_string(&serde_json::json!({
|
||||
"kind": kind,
|
||||
"drive": drive,
|
||||
})).unwrap()
|
||||
}))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn make_db_cap(kind: &str, db: &str) -> String {
|
||||
serde_json::to_string(&serde_json::json!({
|
||||
"kind": kind,
|
||||
"db": db,
|
||||
})).unwrap()
|
||||
}))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn forward_if_have_cap(
|
||||
@ -38,7 +43,7 @@ fn forward_if_have_cap(
|
||||
operation_type: &str,
|
||||
// operation_type: OperationType,
|
||||
db: &str,
|
||||
ipc: Option<String>,
|
||||
ipc: Vec<u8>,
|
||||
db_to_process: &mut DbToProcess,
|
||||
) -> anyhow::Result<()> {
|
||||
if has_capability(&make_db_cap(operation_type, db)) {
|
||||
@ -67,10 +72,7 @@ fn forward_if_have_cap(
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_message (
|
||||
our: &Address,
|
||||
db_to_process: &mut DbToProcess,
|
||||
) -> anyhow::Result<()> {
|
||||
fn handle_message(our: &Address, db_to_process: &mut DbToProcess) -> anyhow::Result<()> {
|
||||
let (source, message) = receive().unwrap();
|
||||
// let (source, message) = receive()?;
|
||||
|
||||
@ -81,9 +83,9 @@ fn handle_message (
|
||||
match message {
|
||||
Message::Response(_) => {
|
||||
return Err(kv::KeyValueError::UnexpectedResponse.into());
|
||||
},
|
||||
}
|
||||
Message::Request(Request { ipc, .. }) => {
|
||||
match process_lib::parse_message_ipc(ipc.clone())? {
|
||||
match process_lib::parse_message_ipc(&ipc)? {
|
||||
kv::KeyValueMessage::New { ref db } => {
|
||||
// TODO: make atomic
|
||||
// (1): create vfs drive
|
||||
@ -104,36 +106,38 @@ fn handle_message (
|
||||
let _ = process_lib::send_and_await_response(
|
||||
&vfs_address,
|
||||
false,
|
||||
Some(serde_json::to_string(&kt::VfsRequest {
|
||||
serde_json::to_vec(&kt::VfsRequest {
|
||||
drive: vfs_drive.clone(),
|
||||
action: kt::VfsAction::New,
|
||||
}).unwrap()),
|
||||
})
|
||||
.unwrap(),
|
||||
None,
|
||||
None,
|
||||
15,
|
||||
).unwrap();
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// (2)
|
||||
let vfs_read = get_capability(
|
||||
&vfs_address,
|
||||
&make_vfs_cap("read", &vfs_drive),
|
||||
).ok_or(anyhow::anyhow!("New failed: no vfs 'read' capability found"))?;
|
||||
let vfs_write = get_capability(
|
||||
&vfs_address,
|
||||
&make_vfs_cap("write", &vfs_drive),
|
||||
).ok_or(anyhow::anyhow!("New failed: no vfs 'write' capability found"))?;
|
||||
let vfs_read = get_capability(&vfs_address, &make_vfs_cap("read", &vfs_drive))
|
||||
.ok_or(anyhow::anyhow!(
|
||||
"New failed: no vfs 'read' capability found"
|
||||
))?;
|
||||
let vfs_write =
|
||||
get_capability(&vfs_address, &make_vfs_cap("write", &vfs_drive)).ok_or(
|
||||
anyhow::anyhow!("New failed: no vfs 'write' capability found"),
|
||||
)?;
|
||||
let spawned_process_id = match spawn(
|
||||
None,
|
||||
"/key_value_worker.wasm",
|
||||
&OnPanic::None, // TODO: notify us
|
||||
&OnPanic::None, // TODO: notify us
|
||||
&Capabilities::Some(vec![vfs_read, vfs_write]),
|
||||
false, // not public
|
||||
) {
|
||||
Ok(spawned_process_id) => spawned_process_id,
|
||||
Err(e) => {
|
||||
print_to_terminal(0, &format!("couldn't spawn: {}", e));
|
||||
panic!("couldn't spawn"); // TODO
|
||||
},
|
||||
panic!("couldn't spawn"); // TODO
|
||||
}
|
||||
};
|
||||
// grant caps
|
||||
create_capability(&source.process, &make_db_cap("read", db));
|
||||
@ -166,20 +170,20 @@ fn handle_message (
|
||||
},
|
||||
None,
|
||||
);
|
||||
},
|
||||
}
|
||||
kv::KeyValueMessage::Write { ref db, .. } => {
|
||||
forward_if_have_cap(our, "write", db, ipc, db_to_process)?;
|
||||
},
|
||||
}
|
||||
kv::KeyValueMessage::Read { ref db, .. } => {
|
||||
forward_if_have_cap(our, "read", db, ipc, db_to_process)?;
|
||||
},
|
||||
}
|
||||
kv::KeyValueMessage::Err { error } => {
|
||||
return Err(error.into());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,23 +195,20 @@ impl Guest for Component {
|
||||
|
||||
loop {
|
||||
match handle_message(&our, &mut db_to_process) {
|
||||
Ok(()) => {},
|
||||
Ok(()) => {}
|
||||
Err(e) => {
|
||||
print_to_terminal(0, format!(
|
||||
"key_value: error: {:?}",
|
||||
e,
|
||||
).as_str());
|
||||
print_to_terminal(0, format!("key_value: error: {:?}", e,).as_str());
|
||||
if let Some(e) = e.downcast_ref::<kv::KeyValueError>() {
|
||||
send_response(
|
||||
&Response {
|
||||
inherit: false,
|
||||
ipc: Some(serde_json::to_string(&e).unwrap()),
|
||||
ipc: serde_json::to_vec(&e).unwrap(),
|
||||
metadata: None,
|
||||
},
|
||||
None,
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ fn send_and_await_response_wrapped(
|
||||
&Request {
|
||||
inherit: false,
|
||||
expects_response: Some(timeout),
|
||||
ipc: request_ipc,
|
||||
ipc: request_ipc.unwrap_or_default().into_bytes(),
|
||||
metadata: request_metadata,
|
||||
},
|
||||
match payload {
|
||||
@ -65,7 +65,7 @@ fn send_and_await_response_wrapped(
|
||||
).unwrap() else {
|
||||
panic!("");
|
||||
};
|
||||
(ipc, metadata)
|
||||
(serde_json::from_slice(&ipc).ok(), metadata)
|
||||
}
|
||||
|
||||
fn handle_message (
|
||||
@ -82,7 +82,7 @@ fn handle_message (
|
||||
match message {
|
||||
Message::Response(_) => { unimplemented!() },
|
||||
Message::Request(Request { inherit: _ , expects_response: _, ipc, metadata: _ }) => {
|
||||
match process_lib::parse_message_ipc(ipc.clone())? {
|
||||
match process_lib::parse_message_ipc(&ipc)? {
|
||||
kv::KeyValueMessage::New { db } => {
|
||||
let vfs_drive = format!("{}{}", PREFIX, db);
|
||||
match db_handle {
|
||||
@ -197,7 +197,7 @@ impl Guest for Component {
|
||||
send_response(
|
||||
&Response {
|
||||
inherit: false,
|
||||
ipc: Some(serde_json::to_string(&e).unwrap()),
|
||||
ipc: serde_json::to_vec(&e).unwrap(),
|
||||
metadata: None,
|
||||
},
|
||||
None,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -75,7 +75,7 @@ sol! {
|
||||
event NodeRegistered(uint256 indexed node, bytes name);
|
||||
}
|
||||
|
||||
fn subscribe_to_qns(from_block: u64) -> String {
|
||||
fn subscribe_to_qns(from_block: u64) -> Vec<u8> {
|
||||
json!({
|
||||
"SubscribeEvents": {
|
||||
"addresses": [
|
||||
@ -94,6 +94,8 @@ fn subscribe_to_qns(from_block: u64) -> String {
|
||||
}
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec()
|
||||
}
|
||||
|
||||
impl UqProcess for Component {
|
||||
@ -127,12 +129,10 @@ impl UqProcess for Component {
|
||||
inherit: false,
|
||||
expects_response: None,
|
||||
metadata: None,
|
||||
ipc: Some(
|
||||
serde_json::to_string(&NetActions::QnsBatchUpdate(
|
||||
state.nodes.values().cloned().collect::<Vec<_>>(),
|
||||
))
|
||||
.unwrap(),
|
||||
),
|
||||
ipc: serde_json::to_vec(&NetActions::QnsBatchUpdate(
|
||||
state.nodes.values().cloned().collect::<Vec<_>>(),
|
||||
))
|
||||
.unwrap(),
|
||||
},
|
||||
None,
|
||||
None,
|
||||
@ -148,7 +148,7 @@ impl UqProcess for Component {
|
||||
expects_response: Some(5), // TODO evaluate
|
||||
metadata: None,
|
||||
// -1 because there could be other events in the last processed block
|
||||
ipc: Some(subscribe_to_qns(state.block - 1)),
|
||||
ipc: subscribe_to_qns(state.block - 1),
|
||||
},
|
||||
None,
|
||||
None,
|
||||
@ -165,16 +165,16 @@ impl UqProcess for Component {
|
||||
inherit: false,
|
||||
expects_response: None,
|
||||
metadata: None,
|
||||
ipc: Some(
|
||||
json!({
|
||||
"BindPath": {
|
||||
"path": "/node/:name",
|
||||
"authenticated": false,
|
||||
"local_only": false
|
||||
}
|
||||
})
|
||||
.to_string(),
|
||||
),
|
||||
ipc: json!({
|
||||
"BindPath": {
|
||||
"path": "/node/:name",
|
||||
"authenticated": false,
|
||||
"local_only": false
|
||||
}
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
},
|
||||
None,
|
||||
None,
|
||||
@ -193,24 +193,24 @@ impl UqProcess for Component {
|
||||
};
|
||||
|
||||
if source.process == http_server_address {
|
||||
if let Ok(ipc_json) = serde_json::from_str::<serde_json::Value>(
|
||||
&request.ipc.clone().unwrap_or_default(),
|
||||
) {
|
||||
if let Ok(ipc_json) =
|
||||
serde_json::from_slice::<serde_json::Value>(&request.ipc)
|
||||
{
|
||||
if ipc_json["path"].as_str().unwrap_or_default() == "/node/:name" {
|
||||
if let Some(name) = ipc_json["url_params"]["name"].as_str() {
|
||||
if let Some(node) = state.nodes.get(name) {
|
||||
send_response(
|
||||
&Response {
|
||||
inherit: false,
|
||||
ipc: Some(
|
||||
serde_json::json!({
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
.to_string(),
|
||||
),
|
||||
ipc: serde_json::json!({
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
metadata: None,
|
||||
},
|
||||
Some(&Payload {
|
||||
@ -229,15 +229,15 @@ impl UqProcess for Component {
|
||||
send_response(
|
||||
&Response {
|
||||
inherit: false,
|
||||
ipc: Some(
|
||||
serde_json::json!({
|
||||
"status": 404,
|
||||
"headers": {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
.to_string(),
|
||||
),
|
||||
ipc: serde_json::json!({
|
||||
"status": 404,
|
||||
"headers": {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
metadata: None,
|
||||
},
|
||||
Some(&Payload {
|
||||
@ -248,14 +248,8 @@ impl UqProcess for Component {
|
||||
continue;
|
||||
}
|
||||
|
||||
let Ok(msg) = serde_json::from_str::<AllActions>(request.ipc.as_ref().unwrap()) else {
|
||||
print_to_terminal(
|
||||
0,
|
||||
&format!(
|
||||
"qns_indexer: got invalid message: {}",
|
||||
request.ipc.unwrap_or_default()
|
||||
),
|
||||
);
|
||||
let Ok(msg) = serde_json::from_slice::<AllActions>(&request.ipc) else {
|
||||
print_to_terminal(0, "qns_indexer: got invalid message");
|
||||
continue;
|
||||
};
|
||||
|
||||
@ -332,12 +326,8 @@ impl UqProcess for Component {
|
||||
inherit: false,
|
||||
expects_response: None,
|
||||
metadata: None,
|
||||
ipc: Some(
|
||||
serde_json::to_string(&NetActions::QnsUpdate(
|
||||
update.clone(),
|
||||
))
|
||||
ipc: serde_json::to_vec(&NetActions::QnsUpdate(update.clone()))
|
||||
.unwrap(),
|
||||
),
|
||||
},
|
||||
None,
|
||||
None,
|
||||
|
@ -36,7 +36,7 @@ fn forward_if_have_cap(
|
||||
operation_type: &str,
|
||||
// operation_type: OperationType,
|
||||
db: &str,
|
||||
ipc: Option<String>,
|
||||
ipc: Vec<u8>,
|
||||
db_to_process: &mut DbToProcess,
|
||||
) -> anyhow::Result<()> {
|
||||
if has_capability(&make_db_cap(operation_type, db)) {
|
||||
@ -83,7 +83,7 @@ fn handle_message (
|
||||
return Err(sq::SqliteError::UnexpectedResponse.into());
|
||||
},
|
||||
Message::Request(Request { ipc, .. }) => {
|
||||
match process_lib::parse_message_ipc(ipc.clone())? {
|
||||
match process_lib::parse_message_ipc(&ipc)? {
|
||||
sq::SqliteMessage::New { ref db } => {
|
||||
// TODO: make atomic
|
||||
// (1): create vfs drive
|
||||
@ -104,10 +104,10 @@ fn handle_message (
|
||||
let _ = process_lib::send_and_await_response(
|
||||
&vfs_address,
|
||||
false,
|
||||
Some(serde_json::to_string(&kt::VfsRequest {
|
||||
serde_json::to_vec(&kt::VfsRequest {
|
||||
drive: vfs_drive.clone(),
|
||||
action: kt::VfsAction::New,
|
||||
}).unwrap()),
|
||||
}).unwrap(),
|
||||
None,
|
||||
None,
|
||||
15,
|
||||
@ -249,7 +249,7 @@ impl Guest for Component {
|
||||
send_response(
|
||||
&Response {
|
||||
inherit: false,
|
||||
ipc: Some(serde_json::to_string(&e).unwrap()),
|
||||
ipc: serde_json::to_vec(&e).unwrap(),
|
||||
metadata: None,
|
||||
},
|
||||
None,
|
||||
|
@ -93,7 +93,7 @@ pub struct CIpcMetadata {
|
||||
}
|
||||
|
||||
impl CPreOptionStr {
|
||||
fn new(s: Option<String>) -> Self {
|
||||
fn new(s: Option<Vec<u8>>) -> Self {
|
||||
let (is_empty, string) = match s {
|
||||
None => (0, CString::new("").unwrap()),
|
||||
Some(s) => (1, CString::new(s).unwrap()),
|
||||
@ -106,7 +106,7 @@ impl CPreOptionStr {
|
||||
}
|
||||
|
||||
impl COptionStr {
|
||||
fn new(s: Option<String>) -> Self {
|
||||
fn new(s: Option<Vec<u8>>) -> Self {
|
||||
let (is_empty, string) = match s {
|
||||
None => (0, CString::new("").unwrap()),
|
||||
Some(s) => (1, CString::new(s).unwrap()),
|
||||
@ -118,6 +118,14 @@ impl COptionStr {
|
||||
}
|
||||
}
|
||||
|
||||
fn from_coptionstr_to_bytes(s: *const COptionStr) -> Vec<u8> {
|
||||
if unsafe { (*s).is_empty == 0 } {
|
||||
vec![]
|
||||
} else {
|
||||
from_cstr_to_string(unsafe { (*s).string }).as_bytes().to_vec()
|
||||
}
|
||||
}
|
||||
|
||||
fn from_coptionstr_to_option_string(s: *const COptionStr) -> Option<String> {
|
||||
if unsafe { (*s).is_empty == 0 } {
|
||||
None
|
||||
@ -163,7 +171,13 @@ impl From<Option<Payload>> for CPrePayload {
|
||||
fn from(p: Option<Payload>) -> Self {
|
||||
let (is_empty, mime, bytes) = match p {
|
||||
None => (0, COptionStr::new(None), CBytes::new_empty()),
|
||||
Some(Payload { mime, bytes }) => (1, COptionStr::new(mime), CBytes::new(bytes)),
|
||||
Some(Payload { mime, bytes }) => {
|
||||
let mime = match mime {
|
||||
Some(s) => Some(s.as_bytes().to_vec()),
|
||||
None => None,
|
||||
};
|
||||
(1, COptionStr::new(mime), CBytes::new(bytes))
|
||||
}
|
||||
};
|
||||
CPrePayload {
|
||||
is_empty,
|
||||
@ -299,7 +313,7 @@ pub extern "C" fn send_and_await_response_wrapped(
|
||||
let target_node = from_cstr_to_string(target_node);
|
||||
let target_process = from_cprocessid_to_processid(target_process);
|
||||
let payload = from_cpayload_to_option_payload(payload);
|
||||
let request_ipc = from_coptionstr_to_option_string(request_ipc);
|
||||
let request_ipc = from_coptionstr_to_bytes(request_ipc);
|
||||
let request_metadata = from_coptionstr_to_option_string(request_metadata);
|
||||
let (
|
||||
_,
|
||||
@ -322,8 +336,11 @@ pub extern "C" fn send_and_await_response_wrapped(
|
||||
).unwrap() else {
|
||||
panic!("");
|
||||
};
|
||||
let ipc = CPreOptionStr::new(ipc);
|
||||
let metadata = CPreOptionStr::new(metadata);
|
||||
let ipc = CPreOptionStr::new(Some(ipc));
|
||||
let metadata = CPreOptionStr::new(match metadata {
|
||||
None => None,
|
||||
Some(s) => Some(s.as_bytes().to_vec())
|
||||
});
|
||||
|
||||
CIpcMetadata::copy_to_ptr(return_val, ipc, metadata);
|
||||
}
|
||||
@ -342,7 +359,7 @@ fn handle_message (
|
||||
match message {
|
||||
Message::Response(_) => { unimplemented!() },
|
||||
Message::Request(Request { ipc, .. }) => {
|
||||
match process_lib::parse_message_ipc(ipc.clone())? {
|
||||
match process_lib::parse_message_ipc(&ipc)? {
|
||||
sq::SqliteMessage::New { db } => {
|
||||
let vfs_address = Address {
|
||||
node: our.node.clone(),
|
||||
|
@ -264,15 +264,11 @@ where
|
||||
super::bindings::set_state(&bincode::serialize(state).unwrap());
|
||||
}
|
||||
|
||||
pub fn parse_message_ipc<T>(json_string: Option<String>) -> anyhow::Result<T>
|
||||
pub fn parse_message_ipc<T>(json_bytes: &[u8]) -> anyhow::Result<T>
|
||||
where
|
||||
for<'a> T: serde::Deserialize<'a>,
|
||||
{
|
||||
let parsed: T = serde_json::from_str(
|
||||
json_string
|
||||
.ok_or(anyhow::anyhow!("json payload empty"))?
|
||||
.as_str(),
|
||||
)?;
|
||||
let parsed: T = serde_json::from_slice(json_bytes)?;
|
||||
Ok(parsed)
|
||||
}
|
||||
|
||||
|
@ -1,26 +0,0 @@
|
||||
// https://github.com/bytecodealliance/wasmtime/blob/432b5471ec4bf6d51173def284cd418be6849a49/crates/wasi/wit/deps/random/insecure-seed.wit
|
||||
|
||||
/// The insecure-seed interface for seeding hash-map DoS resistance.
|
||||
///
|
||||
/// It is intended to be portable at least between Unix-family platforms and
|
||||
/// Windows.
|
||||
interface insecure-seed {
|
||||
/// Return a 128-bit value that may contain a pseudo-random value.
|
||||
///
|
||||
/// The returned value is not required to be computed from a CSPRNG, and may
|
||||
/// even be entirely deterministic. Host implementations are encouraged to
|
||||
/// provide pseudo-random values to any program exposed to
|
||||
/// attacker-controlled content, to enable DoS protection built into many
|
||||
/// languages' hash-map implementations.
|
||||
///
|
||||
/// This function is intended to only be called once, by a source language
|
||||
/// to initialize Denial Of Service (DoS) protection in its hash-map
|
||||
/// implementation.
|
||||
///
|
||||
/// # Expected future evolution
|
||||
///
|
||||
/// This will likely be changed to a value import, to prevent it from being
|
||||
/// called multiple times and potentially used for purposes other than DoS
|
||||
/// protection.
|
||||
insecure-seed: func() -> tuple<u64, u64>
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
// https://github.com/bytecodealliance/wasmtime/blob/432b5471ec4bf6d51173def284cd418be6849a49/crates/wasi/wit/deps/random/insecure.wit
|
||||
|
||||
/// The insecure interface for insecure pseudo-random numbers.
|
||||
///
|
||||
/// It is intended to be portable at least between Unix-family platforms and
|
||||
/// Windows.
|
||||
interface insecure {
|
||||
/// Return `len` insecure pseudo-random bytes.
|
||||
///
|
||||
/// This function is not cryptographically secure. Do not use it for
|
||||
/// anything related to security.
|
||||
///
|
||||
/// There are no requirements on the values of the returned bytes, however
|
||||
/// implementations are encouraged to return evenly distributed values with
|
||||
/// a long period.
|
||||
get-insecure-random-bytes: func(len: u64) -> list<u8>
|
||||
|
||||
/// Return an insecure pseudo-random `u64` value.
|
||||
///
|
||||
/// This function returns the same type of pseudo-random data as
|
||||
/// `get-insecure-random-bytes`, represented as a `u64`.
|
||||
get-insecure-random-u64: func() -> u64
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
// https://github.com/bytecodealliance/wasmtime/blob/432b5471ec4bf6d51173def284cd418be6849a49/crates/wasi/wit/deps/random/random.wit
|
||||
|
||||
package wasi:random
|
||||
|
||||
interface random {
|
||||
/// Return `len` cryptographically-secure pseudo-random bytes.
|
||||
///
|
||||
/// This function must produce data from an adequately seeded
|
||||
/// cryptographically-secure pseudo-random number generator (CSPRNG), so it
|
||||
/// must not block, from the perspective of the calling program, and the
|
||||
/// returned data is always unpredictable.
|
||||
///
|
||||
/// This function must always return fresh pseudo-random data. Deterministic
|
||||
/// environments must omit this function, rather than implementing it with
|
||||
/// deterministic data.
|
||||
get-random-bytes: func(len: u64) -> list<u8>
|
||||
|
||||
/// Return a cryptographically-secure pseudo-random `u64` value.
|
||||
///
|
||||
/// This function returns the same type of pseudo-random data as
|
||||
/// `get-random-bytes`, represented as a `u64`.
|
||||
get-random-u64: func() -> u64
|
||||
}
|
@ -1,183 +0,0 @@
|
||||
package component:uq-process
|
||||
|
||||
interface types {
|
||||
// JSON is passed over WASM boundary as a string.
|
||||
type json = string
|
||||
|
||||
// context is a string of UTF-8 JSON.
|
||||
// it is used when building a Request to save information
|
||||
// that will not be part of a Response, in order to more
|
||||
// easily handle ("contextualize") that Response.
|
||||
type context = json
|
||||
|
||||
variant process-id {
|
||||
id(u64),
|
||||
name(string),
|
||||
}
|
||||
|
||||
// TODO better name for this
|
||||
record address {
|
||||
node: string,
|
||||
process: process-id,
|
||||
}
|
||||
|
||||
record payload {
|
||||
mime: option<string>,
|
||||
bytes: list<u8>,
|
||||
}
|
||||
|
||||
record request {
|
||||
// if true, this request inherits context AND payload of incipient
|
||||
// request, and cannot have its own context.
|
||||
inherit: bool,
|
||||
// if Some, this request expects a response in the number of seconds given
|
||||
expects-response: option<u64>,
|
||||
ipc: option<json>,
|
||||
metadata: option<json>,
|
||||
// to grab payload, use get_payload()
|
||||
}
|
||||
|
||||
record response {
|
||||
ipc: option<json>,
|
||||
metadata: option<json>,
|
||||
// to grab payload, use get_payload()
|
||||
}
|
||||
|
||||
// a message can be a request or a response.
|
||||
// within a response, there is a result which surfaces any error
|
||||
// that happened because of a request.
|
||||
// a successful response will contain the context of the request
|
||||
// it matches, if any was set.
|
||||
variant message {
|
||||
request(request),
|
||||
response(tuple<response, option<context>>),
|
||||
}
|
||||
|
||||
variant capabilities {
|
||||
none,
|
||||
all,
|
||||
some(list<signed-capability>),
|
||||
}
|
||||
|
||||
record signed-capability {
|
||||
issuer: address,
|
||||
params: json,
|
||||
signature: list<u8>,
|
||||
}
|
||||
|
||||
// network errors come from trying to send a message to another node.
|
||||
// a message can fail by timing out, or by the node being entirely unreachable (offline).
|
||||
// in either case, the message is not delivered, and the process that sent it
|
||||
// receives that message along with any assigned context and/or payload,
|
||||
// and is free to handle it as it sees fit.
|
||||
// note that if the message is a response, the process can issue a response again,
|
||||
// and it will be directed to the same (remote) request as the original.
|
||||
record send-error {
|
||||
kind: send-error-kind,
|
||||
message: message,
|
||||
payload: option<payload>,
|
||||
}
|
||||
|
||||
enum send-error-kind {
|
||||
offline,
|
||||
timeout,
|
||||
}
|
||||
|
||||
// on-panic is a setting that determines what happens when a process panics.
|
||||
// NOTE: requests should have expects-response set to false, will always be set to that by kernel
|
||||
variant on-panic {
|
||||
none,
|
||||
restart,
|
||||
requests(list<tuple<address, request, option<payload>>>),
|
||||
}
|
||||
}
|
||||
|
||||
world uq-process {
|
||||
use types.{
|
||||
json,
|
||||
context,
|
||||
address,
|
||||
process-id,
|
||||
|
||||
payload,
|
||||
request,
|
||||
response,
|
||||
message,
|
||||
|
||||
capabilities,
|
||||
signed-capability,
|
||||
|
||||
send-error,
|
||||
send-error-kind,
|
||||
on-panic,
|
||||
}
|
||||
|
||||
// entry point to all programs
|
||||
export init: func(our: address)
|
||||
|
||||
// system utils:
|
||||
|
||||
import print-to-terminal: func(verbosity: u8, message: string)
|
||||
import get-unix-time: func() -> u64
|
||||
import get-eth-block: func() -> u64
|
||||
|
||||
// process management:
|
||||
|
||||
import set-on-panic: func(on-panic: on-panic)
|
||||
|
||||
import get-state: func() -> option<list<u8>>
|
||||
|
||||
import set-state: func(bytes: list<u8>)
|
||||
|
||||
import clear-state: func()
|
||||
|
||||
import spawn: func(id: process-id, %package: string, full-path: string, on-panic: on-panic, capabilities: capabilities) ->
|
||||
option<process-id>
|
||||
|
||||
// capabilities management
|
||||
|
||||
// gives us all our signed capabilities so we can send them to others
|
||||
import get-capabilities: func() -> list<signed-capability>
|
||||
|
||||
// gets a single specific capability
|
||||
import get-capability: func(issuer: address, params: json) -> option<signed-capability>
|
||||
|
||||
// attaches a specific signed capability to our next message
|
||||
import attach-capability: func(capability: signed-capability)
|
||||
|
||||
// saves capabilities to our store, so we can use them
|
||||
import save-capabilities: func(capabilities: list<signed-capability>)
|
||||
|
||||
// check to see if the sender of a prompting message has a given capability, issued by us
|
||||
// if the prompting message has a remote source, they must have attached it.
|
||||
import has-capability: func(params: json) -> bool
|
||||
|
||||
|
||||
// message I/O:
|
||||
|
||||
// ingest next message when it arrives along with its source.
|
||||
// almost all long-running processes will call this in a loop
|
||||
import receive: func() -> result<tuple<address, message>, tuple<send-error, option<context>>>
|
||||
|
||||
// gets payload, if any, of the message we just received
|
||||
import get-payload: func() -> option<payload>
|
||||
|
||||
// send message(s) to target(s)
|
||||
import send-request:
|
||||
func(target: address, request: request, context: option<context>, payload: option<payload>)
|
||||
import send-requests:
|
||||
func(requests: list<tuple<address, request, option<context>, option<payload>>>)
|
||||
import send-response:
|
||||
func(response: response, payload: option<payload>)
|
||||
|
||||
// send a single request, then block (internally) until its response
|
||||
// the type is Message but will always contain Response
|
||||
import send-and-await-response:
|
||||
func(target: address, request: request, payload: option<payload>) ->
|
||||
result<tuple<address, message>, send-error>
|
||||
|
||||
// wasi
|
||||
import wasi:random/insecure
|
||||
import wasi:random/insecure-seed
|
||||
import wasi:random/random
|
||||
}
|
Loading…
Reference in New Issue
Block a user