♻️ Package interesting request fields into MsgPack
parent
15b18a9335
commit
406b13c3b1
|
@ -1,16 +1,17 @@
|
|||
use std::{
|
||||
collections::*,
|
||||
error::Error,
|
||||
};
|
||||
use std::convert::{Infallible};
|
||||
use std::io::Write;
|
||||
use std::net::SocketAddr;
|
||||
use std::path::Path;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{
|
||||
convert::{
|
||||
Infallible,
|
||||
TryInto,
|
||||
},
|
||||
net::SocketAddr,
|
||||
str::FromStr,
|
||||
sync::{
|
||||
Arc
|
||||
},
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use futures::channel::oneshot;
|
||||
use hyper::{
|
||||
|
@ -24,22 +25,18 @@ use hyper::{
|
|||
use hyper::service::{make_service_fn, service_fn};
|
||||
|
||||
use tokio::{
|
||||
sync::mpsc::{
|
||||
channel,
|
||||
Receiver,
|
||||
},
|
||||
sync::Mutex,
|
||||
time::delay_for,
|
||||
};
|
||||
|
||||
use ptth::watcher::Watchers;
|
||||
use ptth::{
|
||||
http_serde::*,
|
||||
watcher::Watchers,
|
||||
};
|
||||
|
||||
enum Message {
|
||||
Meow,
|
||||
//HttpRequestRequest (String),
|
||||
HttpRequestResponse (String),
|
||||
// HttpResponseRequest (String),
|
||||
HttpResponseResponse (Vec <u8>),
|
||||
HttpRequestResponse (RequestParts),
|
||||
HttpResponseResponseStream (Body),
|
||||
}
|
||||
|
||||
|
@ -79,11 +76,11 @@ async fn handle_wake (state: Arc <ServerState>, watcher_code: String)
|
|||
async fn handle_http_listen (state: Arc <ServerState>, watcher_code: String)
|
||||
-> Response <Body>
|
||||
{
|
||||
println! ("Step 1");
|
||||
//println! ("Step 1");
|
||||
match Watchers::long_poll (state.watchers.clone (), watcher_code).await {
|
||||
Some (Message::HttpRequestResponse (uri)) => {
|
||||
Some (Message::HttpRequestResponse (parts)) => {
|
||||
println! ("Step 3");
|
||||
status_reply (StatusCode::OK, uri)
|
||||
status_reply (StatusCode::OK, rmp_serde::to_vec (&parts).unwrap ())
|
||||
},
|
||||
_ => status_reply (StatusCode::GATEWAY_TIMEOUT, "no\n"),
|
||||
}
|
||||
|
@ -105,7 +102,7 @@ async fn handle_http_response (
|
|||
println! ("Step 7");
|
||||
if ! watchers.wake_one (Message::HttpResponseResponseStream (body), &req_id)
|
||||
{
|
||||
println! ("Step 8");
|
||||
println! ("Step 8 (bad thing)");
|
||||
return status_reply (StatusCode::BAD_REQUEST, "A bad thing happened.\n");
|
||||
}
|
||||
else {
|
||||
|
@ -116,31 +113,31 @@ async fn handle_http_response (
|
|||
}
|
||||
|
||||
async fn handle_http_request (
|
||||
parts: RequestParts,
|
||||
state: Arc <ServerState>,
|
||||
watcher_code: String,
|
||||
uri: String
|
||||
watcher_code: String
|
||||
)
|
||||
-> Response <Body>
|
||||
{
|
||||
let req_id = format! ("client_{}", ulid::Ulid::new ().to_string ());
|
||||
|
||||
println! ("Step 2 {}", req_id);
|
||||
println! ("Step 2 {}", parts.id);
|
||||
|
||||
let (s, r) = oneshot::channel ();
|
||||
let timeout = Duration::from_secs (5);
|
||||
|
||||
let id_2 = req_id.clone ();
|
||||
let id_2 = parts.id.clone ();
|
||||
{
|
||||
let mut that = state.watchers.lock ().await;
|
||||
that.add_watcher_with_id (s, id_2)
|
||||
}
|
||||
|
||||
let req_id = parts.id.clone ();
|
||||
|
||||
tokio::spawn (async move {
|
||||
{
|
||||
let mut watchers = state.watchers.lock ().await;
|
||||
|
||||
println! ("Step 3");
|
||||
if ! watchers.wake_one (Message::HttpRequestResponse (req_id.clone ()), &watcher_code) {
|
||||
if ! watchers.wake_one (Message::HttpRequestResponse (parts), &watcher_code) {
|
||||
watchers.remove_watcher (&req_id);
|
||||
}
|
||||
}
|
||||
|
@ -201,7 +198,7 @@ async fn handle_all (req: Request <Body>, state: Arc <ServerState>)
|
|||
-> Result <Response <Body>, Infallible>
|
||||
{
|
||||
let path = req.uri ().path ();
|
||||
println! ("{}", path);
|
||||
//println! ("{}", path);
|
||||
|
||||
if req.method () == Method::POST {
|
||||
return Ok (if let Some (request_code) = prefix_match (path, "/http_response/") {
|
||||
|
@ -224,9 +221,14 @@ async fn handle_all (req: Request <Body>, state: Arc <ServerState>)
|
|||
}
|
||||
else if let Some (rest) = prefix_match (path, "/http_request/") {
|
||||
if let Some (idx) = rest.find ('/') {
|
||||
let listen_code = &rest [0..idx];
|
||||
let path = &rest [idx + 1..];
|
||||
Ok (handle_http_request (state, listen_code.into (), path.into ()).await)
|
||||
let listen_code = String::from (&rest [0..idx]);
|
||||
let path = String::from (&rest [idx + 1..]);
|
||||
let (parts, _) = req.into_parts ();
|
||||
let parts = match parts.try_into () {
|
||||
Ok (x) => x,
|
||||
_ => return Ok (status_reply (StatusCode::BAD_REQUEST, "Couldn't convert request")),
|
||||
};
|
||||
Ok (handle_http_request (parts, state, listen_code).await)
|
||||
}
|
||||
else {
|
||||
Ok (status_reply (StatusCode::BAD_REQUEST, "Bad URI format"))
|
||||
|
|
|
@ -23,6 +23,8 @@ use tokio::{
|
|||
time::delay_for,
|
||||
};
|
||||
|
||||
use ptth::http_serde::*;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main () -> Result <(), Box <dyn Error>> {
|
||||
let client = Arc::new (Client::new ());
|
||||
|
@ -42,7 +44,7 @@ async fn main () -> Result <(), Box <dyn Error>> {
|
|||
|
||||
let req_req = client.get ("http://127.0.0.1:4000/http_listen/alien_wildlands");
|
||||
|
||||
println! ("Step 1");
|
||||
//println! ("Step 1");
|
||||
let req_resp = match req_req.send ().await {
|
||||
Err (e) => {
|
||||
println! ("Err: {:?}", e);
|
||||
|
@ -62,12 +64,15 @@ async fn main () -> Result <(), Box <dyn Error>> {
|
|||
println! ("Step 3");
|
||||
|
||||
let body = req_resp.bytes ().await?;
|
||||
let body = String::from (std::str::from_utf8 (&body)?);
|
||||
let parts: RequestParts = match rmp_serde::from_read_ref (&body)
|
||||
{
|
||||
Ok (x) => x,
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
println! ("Client requested {}", body);
|
||||
println! ("Client requested {}", parts.uri);
|
||||
|
||||
println! ("Step 4/5");
|
||||
let payload = String::from ("Ha ha hue hue it worked.\n");
|
||||
|
||||
println! ("Step 6");
|
||||
let client = client.clone ();
|
||||
|
@ -84,6 +89,8 @@ async fn main () -> Result <(), Box <dyn Error>> {
|
|||
tokio::spawn (async move {
|
||||
let path = "/home/user/pictures/bzqcChY.jpg";
|
||||
let path = "/home/user/videos/Decearing Egg.webm";
|
||||
let path = "/home/user/projects/2020/ptth/README.md";
|
||||
|
||||
let mut f = File::open (path).await.unwrap ();
|
||||
let mut tx = tx;
|
||||
let mut bytes_sent = 0;
|
||||
|
@ -98,7 +105,7 @@ async fn main () -> Result <(), Box <dyn Error>> {
|
|||
break;
|
||||
}
|
||||
|
||||
tx.send (Ok::<_, Infallible> (buffer)).await;
|
||||
tx.send (Ok::<_, Infallible> (buffer)).await.unwrap ();
|
||||
bytes_sent += bytes_read;
|
||||
|
||||
println! ("Sent {} bytes", bytes_sent);
|
||||
|
@ -107,7 +114,7 @@ async fn main () -> Result <(), Box <dyn Error>> {
|
|||
}
|
||||
});
|
||||
|
||||
let resp_req = client.post (&format! ("http://127.0.0.1:4000/http_response/{}", body)).body (Body::wrap_stream (rx));
|
||||
let resp_req = client.post (&format! ("http://127.0.0.1:4000/http_response/{}", parts.id)).body (Body::wrap_stream (rx));
|
||||
|
||||
println! ("Step 6");
|
||||
match resp_req.send ().await {
|
||||
|
|
|
@ -44,6 +44,7 @@ impl From <Method> for hyper::Method {
|
|||
|
||||
#[derive (Deserialize, Serialize)]
|
||||
pub struct RequestParts {
|
||||
pub id: String,
|
||||
pub method: Method,
|
||||
|
||||
// Technically URIs are subtle and complex but I don't care
|
||||
|
@ -70,6 +71,7 @@ impl TryFrom <http::request::Parts> for RequestParts {
|
|||
);
|
||||
|
||||
Ok (Self {
|
||||
id: ulid::Ulid::new ().to_string (),
|
||||
method,
|
||||
uri,
|
||||
headers,
|
||||
|
|
|
@ -34,7 +34,7 @@ impl <T: 'static + Send + Sync> Watchers <T> {
|
|||
}
|
||||
|
||||
pub fn wake_one (&mut self, msg: T, id: &str) -> bool {
|
||||
println! ("wake_one {}", id);
|
||||
//println! ("wake_one {}", id);
|
||||
|
||||
if let Some (waiter) = self.senders.remove (id) {
|
||||
waiter.send (msg).ok ();
|
||||
|
@ -50,7 +50,7 @@ impl <T: 'static + Send + Sync> Watchers <T> {
|
|||
}
|
||||
|
||||
pub async fn long_poll (that: Arc <Mutex <Self>>, id: String) -> Option <T> {
|
||||
println! ("long_poll {}", id);
|
||||
//println! ("long_poll {}", id);
|
||||
|
||||
let (s, r) = oneshot::channel ();
|
||||
let timeout = Duration::from_secs (5);
|
||||
|
|
Loading…
Reference in New Issue