Add server list page
parent
9244953e57
commit
f57777c72f
|
@ -1,5 +0,0 @@
|
||||||
<li>
|
|
||||||
<a href="{{encoded_file_name}}{{trailing_slash}}">
|
|
||||||
{{file_name}}{{trailing_slash}}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: sans;
|
||||||
|
}
|
||||||
|
.entry {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 20px;
|
||||||
|
min-width: 50%;
|
||||||
|
}
|
||||||
|
.entry_list div:nth-child(odd) {
|
||||||
|
background-color: #ddd;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<title>Server list</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>Server list</h1>
|
||||||
|
|
||||||
|
<div class="entry_list">
|
||||||
|
|
||||||
|
{{#if servers}}
|
||||||
|
{{#each servers}}
|
||||||
|
<div>
|
||||||
|
<a class="entry" href="{{this.path}}/">{{this.name}}</a>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
{{else}}
|
||||||
|
(No servers are running)
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,37 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: sans;
|
||||||
|
}
|
||||||
|
.entry {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 20px;
|
||||||
|
min-width: 50%;
|
||||||
|
}
|
||||||
|
.entry_list div:nth-child(odd) {
|
||||||
|
background-color: #ddd;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<title>Server list</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>Server list</h1>
|
||||||
|
|
||||||
|
<div class="entry_list">
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<a class="entry" href="alice/">alice</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<a class="entry" href="beth/">beth</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -11,6 +11,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use futures::channel::oneshot;
|
use futures::channel::oneshot;
|
||||||
|
use handlebars::Handlebars;
|
||||||
use hyper::{
|
use hyper::{
|
||||||
Body,
|
Body,
|
||||||
Method,
|
Method,
|
||||||
|
@ -20,7 +21,7 @@ use hyper::{
|
||||||
StatusCode,
|
StatusCode,
|
||||||
};
|
};
|
||||||
use hyper::service::{make_service_fn, service_fn};
|
use hyper::service::{make_service_fn, service_fn};
|
||||||
|
use serde::Serialize;
|
||||||
use tokio::{
|
use tokio::{
|
||||||
sync::Mutex,
|
sync::Mutex,
|
||||||
time::delay_for,
|
time::delay_for,
|
||||||
|
@ -38,6 +39,7 @@ enum Message {
|
||||||
|
|
||||||
#[derive (Default)]
|
#[derive (Default)]
|
||||||
struct ServerState {
|
struct ServerState {
|
||||||
|
handlebars: Arc <Handlebars <'static>>,
|
||||||
watchers: Arc <Mutex <Watchers <Message>>>,
|
watchers: Arc <Mutex <Watchers <Message>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,33 +188,85 @@ async fn handle_all (req: Request <Body>, state: Arc <ServerState>)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some (listen_code) = prefix_match (path, "/7ZSFUKGV_http_listen/") {
|
Ok (if let Some (listen_code) = prefix_match (path, "/7ZSFUKGV_http_listen/") {
|
||||||
Ok (handle_http_listen (state, listen_code.into ()).await)
|
handle_http_listen (state, listen_code.into ()).await
|
||||||
}
|
}
|
||||||
else if let Some (rest) = prefix_match (path, "/servers/") {
|
else if let Some (rest) = prefix_match (path, "/servers/") {
|
||||||
if let Some (idx) = rest.find ('/') {
|
if rest == "" {
|
||||||
|
#[derive (Serialize)]
|
||||||
|
struct ServerEntry <'a> {
|
||||||
|
path: &'a str,
|
||||||
|
name: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive (Serialize)]
|
||||||
|
struct ServerListPage <'a> {
|
||||||
|
servers: Vec <ServerEntry <'a>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
let names: Vec <_> = {
|
||||||
|
state.watchers.lock ().await.senders.iter ()
|
||||||
|
.map (|(k, _)| (*k).clone ())
|
||||||
|
.collect ()
|
||||||
|
};
|
||||||
|
|
||||||
|
//println! ("Found {} servers", names.len ());
|
||||||
|
|
||||||
|
let page = ServerListPage {
|
||||||
|
servers: names.iter ()
|
||||||
|
.map (|name| ServerEntry {
|
||||||
|
name: &name,
|
||||||
|
path: &name,
|
||||||
|
})
|
||||||
|
.collect (),
|
||||||
|
};
|
||||||
|
|
||||||
|
let s = state.handlebars.render ("relay_server_list", &page).unwrap ();
|
||||||
|
status_reply (StatusCode::OK, s)
|
||||||
|
}
|
||||||
|
else if let Some (idx) = rest.find ('/') {
|
||||||
let listen_code = String::from (&rest [0..idx]);
|
let listen_code = String::from (&rest [0..idx]);
|
||||||
let path = String::from (&rest [idx..]);
|
let path = String::from (&rest [idx..]);
|
||||||
let (parts, _) = req.into_parts ();
|
let (parts, _) = req.into_parts ();
|
||||||
|
|
||||||
Ok (handle_http_request (parts, path, state, listen_code).await)
|
handle_http_request (parts, path, state, listen_code).await
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Ok (status_reply (StatusCode::BAD_REQUEST, "Bad URI format"))
|
status_reply (StatusCode::BAD_REQUEST, "Bad URI format")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if path == "/relay_up_check" {
|
else if path == "/relay_up_check" {
|
||||||
Ok (status_reply (StatusCode::OK, "Relay is up\n"))
|
status_reply (StatusCode::OK, "Relay is up\n")
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Ok (status_reply (StatusCode::OK, "Hi\n"))
|
status_reply (StatusCode::OK, "Hi\n")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_templates ()
|
||||||
|
-> Result <Handlebars <'static>, Box <dyn Error>>
|
||||||
|
{
|
||||||
|
let mut handlebars = Handlebars::new ();
|
||||||
|
handlebars.set_strict_mode (true);
|
||||||
|
|
||||||
|
for (k, v) in vec! [
|
||||||
|
("relay_server_list", "relay_server_list.html"),
|
||||||
|
].into_iter () {
|
||||||
|
handlebars.register_template_file (k, format! ("ptth_handlebars/{}", v))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok (handlebars)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn main () -> Result <(), Box <dyn Error>> {
|
pub async fn main () -> Result <(), Box <dyn Error>> {
|
||||||
let addr = SocketAddr::from(([0, 0, 0, 0], 4000));
|
let addr = SocketAddr::from(([0, 0, 0, 0], 4000));
|
||||||
|
|
||||||
let state = Arc::new (ServerState::default ());
|
let state = ServerState {
|
||||||
|
handlebars: Arc::new (load_templates ()?),
|
||||||
|
watchers: Default::default (),
|
||||||
|
};
|
||||||
|
|
||||||
|
let state = Arc::new (state);
|
||||||
|
|
||||||
let make_svc = make_service_fn (|_conn| {
|
let make_svc = make_service_fn (|_conn| {
|
||||||
let state = state.clone ();
|
let state = state.clone ();
|
||||||
|
|
|
@ -58,13 +58,15 @@ impl <T: 'static + Send + Sync> Watchers <T> {
|
||||||
let id_2 = id.clone ();
|
let id_2 = id.clone ();
|
||||||
{
|
{
|
||||||
let mut that = that.lock ().await;
|
let mut that = that.lock ().await;
|
||||||
that.add_watcher_with_id (s, id_2)
|
that.add_watcher_with_id (s, id_2);
|
||||||
|
//println! ("Added server {}", id);
|
||||||
}
|
}
|
||||||
|
|
||||||
tokio::spawn (async move {
|
tokio::spawn (async move {
|
||||||
delay_for (timeout).await;
|
delay_for (timeout).await;
|
||||||
let mut that = that.lock ().await;
|
let mut that = that.lock ().await;
|
||||||
that.remove_watcher (&id);
|
that.remove_watcher (&id);
|
||||||
|
//println! ("Removed server {}", id);
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Ok (message) = r.await {
|
if let Ok (message) = r.await {
|
||||||
|
|
|
@ -285,15 +285,15 @@ pub async fn serve_all (
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_templates ()
|
pub fn load_templates ()
|
||||||
-> Result <handlebars::Handlebars <'static>, Box <dyn Error>>
|
-> Result <Handlebars <'static>, Box <dyn Error>>
|
||||||
{
|
{
|
||||||
let mut handlebars = handlebars::Handlebars::new ();
|
let mut handlebars = Handlebars::new ();
|
||||||
|
handlebars.set_strict_mode (true);
|
||||||
|
|
||||||
for (k, v) in vec! [
|
for (k, v) in vec! [
|
||||||
("file_server_dir_entry", "ptth_handlebars/file_server_dir_entry.html"),
|
("file_server_dir", "file_server_dir.html"),
|
||||||
("file_server_dir", "ptth_handlebars/file_server_dir.html"),
|
|
||||||
].into_iter () {
|
].into_iter () {
|
||||||
handlebars.register_template_file (k, v)?;
|
handlebars.register_template_file (k, format! ("ptth_handlebars/{}", v))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok (handlebars)
|
Ok (handlebars)
|
||||||
|
|
3
todo.md
3
todo.md
|
@ -1,7 +1,6 @@
|
||||||
- Offer list of clients at server root
|
|
||||||
- Parameter for server URL
|
- Parameter for server URL
|
||||||
- Parameter for static file serve path
|
- Parameter for static file serve path
|
||||||
- Parameter for sererv name
|
- Parameter for server name
|
||||||
- Set up tokens or privkeys or tripcodes or something so clients can't trivially
|
- Set up tokens or privkeys or tripcodes or something so clients can't trivially
|
||||||
impersonate servers
|
impersonate servers
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue