139 lines
2.4 KiB
Rust
139 lines
2.4 KiB
Rust
use std::{
|
|
sync::Arc,
|
|
time::Duration,
|
|
};
|
|
|
|
use hyper::{
|
|
Body,
|
|
Method,
|
|
Request,
|
|
Response,
|
|
StatusCode,
|
|
};
|
|
use tokio::{
|
|
spawn,
|
|
sync::mpsc,
|
|
time::interval,
|
|
};
|
|
use tracing::{
|
|
info, trace,
|
|
};
|
|
use tracing_subscriber::{
|
|
fmt,
|
|
fmt::format::FmtSpan,
|
|
EnvFilter,
|
|
};
|
|
use ulid::Ulid;
|
|
|
|
pub struct RelayState {
|
|
|
|
}
|
|
|
|
pub struct HttpService {
|
|
state: Arc <RelayState>
|
|
}
|
|
|
|
impl HttpService {
|
|
pub fn new () -> Self {
|
|
Self {
|
|
state: Arc::new (RelayState {}),
|
|
}
|
|
}
|
|
|
|
pub async fn serve (&self, port: u16) -> Result <(), hyper::Error> {
|
|
use std::net::SocketAddr;
|
|
|
|
use hyper::{
|
|
server::Server,
|
|
service::{
|
|
make_service_fn,
|
|
service_fn,
|
|
},
|
|
};
|
|
|
|
let make_svc = make_service_fn (|_conn| {
|
|
let state = self.state.clone ();
|
|
|
|
async {
|
|
Ok::<_, String> (service_fn (move |req| {
|
|
let state = state.clone ();
|
|
|
|
Self::handle_all (req, state)
|
|
}))
|
|
}
|
|
});
|
|
|
|
let addr = SocketAddr::from(([127, 0, 0, 1], port));
|
|
|
|
let server = Server::bind (&addr)
|
|
.serve (make_svc)
|
|
;
|
|
|
|
server.await
|
|
}
|
|
|
|
async fn handle_all (req: Request <Body>, state: Arc <RelayState>)
|
|
-> Result <Response <Body>, anyhow::Error>
|
|
{
|
|
if req.method () == Method::GET {
|
|
return Self::handle_gets (req, &*state).await;
|
|
}
|
|
|
|
Ok::<_, anyhow::Error> (Response::builder ()
|
|
.body (Body::from ("hello\n"))?)
|
|
}
|
|
|
|
async fn handle_gets (req: Request <Body>, state: &RelayState)
|
|
-> Result <Response <Body>, anyhow::Error>
|
|
{
|
|
let (mut tx, rx) = mpsc::channel (1);
|
|
|
|
spawn (async move {
|
|
let id = Ulid::new ().to_string ();
|
|
trace! ("Downstream {} started", id);
|
|
Self::handle_downstream (tx).await.ok ();
|
|
trace! ("Downstream {} ended", id);
|
|
});
|
|
|
|
Ok::<_, anyhow::Error> (Response::builder ()
|
|
.body (Body::wrap_stream (rx))?)
|
|
}
|
|
|
|
async fn handle_downstream (mut tx: mpsc::Sender <anyhow::Result <String>>) -> Result <(), anyhow::Error> {
|
|
let mut int = interval (Duration::from_secs (1));
|
|
let mut counter = 0u64;
|
|
|
|
loop {
|
|
int.tick ().await;
|
|
|
|
tx.send (Ok::<_, anyhow::Error> (format! ("Counter: {}\n", counter))).await?;
|
|
counter += 1;
|
|
}
|
|
|
|
Ok (())
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
async fn main () -> Result <(), anyhow::Error> {
|
|
use std::time::Duration;
|
|
|
|
use tokio::{
|
|
spawn,
|
|
time::interval,
|
|
};
|
|
|
|
fmt ()
|
|
.with_env_filter (EnvFilter::from_default_env ())
|
|
.with_span_events (FmtSpan::CLOSE)
|
|
.init ()
|
|
;
|
|
|
|
let service = HttpService::new ();
|
|
|
|
info! ("Starting relay");
|
|
Ok (service.serve (4003).await?)
|
|
}
|