2020-10-27 01:42:10 +00:00
|
|
|
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::{
|
|
|
|
Arc
|
|
|
|
};
|
|
|
|
use std::time::{Duration, Instant};
|
|
|
|
|
|
|
|
use futures::channel::oneshot;
|
|
|
|
use hyper::{Body, Request, Response, Server, StatusCode};
|
|
|
|
use hyper::service::{make_service_fn, service_fn};
|
|
|
|
|
|
|
|
use tokio::{
|
|
|
|
sync::Mutex,
|
|
|
|
time::delay_for,
|
|
|
|
};
|
|
|
|
|
2020-10-27 01:55:47 +00:00
|
|
|
use ptth::watcher::Watchers;
|
2020-10-27 01:42:10 +00:00
|
|
|
|
|
|
|
#[derive (Clone)]
|
|
|
|
enum Message {
|
|
|
|
Meow,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive (Default)]
|
|
|
|
struct ServerState {
|
|
|
|
watchers: Arc <Mutex <Watchers <Message>>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
fn status_reply <B: Into <Body>> (status: StatusCode, b: B)
|
|
|
|
-> Response <Body>
|
|
|
|
{
|
|
|
|
Response::builder ().status (status).body (b.into ()).unwrap ()
|
|
|
|
}
|
|
|
|
|
2020-10-27 02:20:37 +00:00
|
|
|
async fn handle_watch (state: Arc <ServerState>, watcher_code: String)
|
2020-10-27 01:42:10 +00:00
|
|
|
-> Response <Body>
|
|
|
|
{
|
2020-10-27 02:20:37 +00:00
|
|
|
match Watchers::long_poll (state.watchers.clone (), watcher_code).await {
|
2020-10-27 01:42:10 +00:00
|
|
|
None => status_reply (StatusCode::OK, "no\n"),
|
|
|
|
Some (_) => status_reply (StatusCode::OK, "actually, yes\n"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-27 02:20:37 +00:00
|
|
|
async fn handle_wake (state: Arc <ServerState>, watcher_code: String)
|
2020-10-27 01:42:10 +00:00
|
|
|
-> Response <Body>
|
|
|
|
{
|
|
|
|
let mut watchers = state.watchers.lock ().await;
|
|
|
|
|
2020-10-27 02:20:37 +00:00
|
|
|
if watchers.wake_one (Message::Meow, &watcher_code) {
|
|
|
|
status_reply (StatusCode::OK, "ok\n")
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
status_reply (StatusCode::BAD_REQUEST, "no\n")
|
|
|
|
}
|
2020-10-27 01:42:10 +00:00
|
|
|
}
|
|
|
|
|
2020-10-27 01:55:47 +00:00
|
|
|
async fn handle_udp_send () -> Response <Body>
|
|
|
|
{
|
|
|
|
use tokio::net::UdpSocket;
|
|
|
|
|
|
|
|
let mut sock = UdpSocket::bind (SocketAddr::from (([0,0,0,0], 0))).await.unwrap ();
|
|
|
|
|
|
|
|
sock.send_to (b"handle_udp_send\n", SocketAddr::from (([127,0,0,1], 9000u16))).await.unwrap ();
|
|
|
|
|
|
|
|
status_reply (StatusCode::OK, "ok\n")
|
|
|
|
}
|
|
|
|
|
2020-10-27 02:00:09 +00:00
|
|
|
async fn handle_udp_recv () -> Response <Body>
|
|
|
|
{
|
|
|
|
use tokio::net::UdpSocket;
|
|
|
|
|
|
|
|
let mut sock = UdpSocket::bind (SocketAddr::from (([0,0,0,0], 4001))).await.unwrap ();
|
|
|
|
|
|
|
|
let mut buffer = vec! [0u8; 4096];
|
|
|
|
|
|
|
|
let (bytes_received, _addr) = sock.recv_from (&mut buffer [..]).await.unwrap ();
|
|
|
|
|
|
|
|
buffer.truncate (bytes_received);
|
|
|
|
|
|
|
|
status_reply (StatusCode::OK, buffer)
|
|
|
|
}
|
|
|
|
|
2020-10-27 02:20:37 +00:00
|
|
|
fn prefix_match <'a> (hay: &'a str, needle: &str) -> Option <&'a str>
|
|
|
|
{
|
|
|
|
if hay.starts_with (needle) {
|
|
|
|
Some (&hay [needle.len ()..])
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-27 01:42:10 +00:00
|
|
|
async fn handle_all (req: Request <Body>, state: Arc <ServerState>)
|
|
|
|
-> Result <Response <Body>, Infallible>
|
|
|
|
{
|
2020-10-27 02:20:37 +00:00
|
|
|
let path = req.uri ().path ();
|
|
|
|
println! ("{}", path);
|
2020-10-27 01:42:10 +00:00
|
|
|
|
2020-10-27 02:20:37 +00:00
|
|
|
if let Some (watch_code) = prefix_match (path, "/watch/") {
|
|
|
|
Ok (handle_watch (state, watch_code.into ()).await)
|
2020-10-27 01:42:10 +00:00
|
|
|
}
|
2020-10-27 02:20:37 +00:00
|
|
|
else if let Some (watch_code) = prefix_match (path, "/wake/") {
|
|
|
|
Ok (handle_wake (state, watch_code.into ()).await)
|
2020-10-27 01:42:10 +00:00
|
|
|
}
|
2020-10-27 02:20:37 +00:00
|
|
|
/*
|
|
|
|
else if let Some (name) = prefix_match (path, "/udp_send/") {
|
2020-10-27 01:55:47 +00:00
|
|
|
Ok (handle_udp_send ().await)
|
|
|
|
}
|
2020-10-27 02:20:37 +00:00
|
|
|
else if let Some (name) = prefix_match (path, "/udp_recv/") {
|
2020-10-27 02:00:09 +00:00
|
|
|
Ok (handle_udp_recv ().await)
|
|
|
|
}
|
2020-10-27 02:20:37 +00:00
|
|
|
*/
|
2020-10-27 01:42:10 +00:00
|
|
|
else {
|
|
|
|
Ok (status_reply (StatusCode::OK, "Hi\n"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
async fn main () -> Result <(), Box <dyn Error>> {
|
|
|
|
let addr = SocketAddr::from(([0, 0, 0, 0], 4000));
|
|
|
|
|
|
|
|
let state = Arc::new (ServerState::default ());
|
|
|
|
|
|
|
|
let make_svc = make_service_fn (|_conn| {
|
|
|
|
let state = state.clone ();
|
|
|
|
|
|
|
|
async {
|
|
|
|
Ok::<_, Infallible> (service_fn (move |req| {
|
|
|
|
let state = state.clone ();
|
|
|
|
|
|
|
|
handle_all (req, state)
|
|
|
|
}))
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
let server = Server::bind (&addr).serve (make_svc);
|
|
|
|
|
|
|
|
server.await?;
|
|
|
|
|
|
|
|
Ok (())
|
|
|
|
}
|