Add server list page

main
_ 2020-10-31 15:46:38 -05:00
parent 9244953e57
commit f57777c72f
7 changed files with 148 additions and 22 deletions

View File

@ -1,5 +0,0 @@
<li>
<a href="{{encoded_file_name}}{{trailing_slash}}">
{{file_name}}{{trailing_slash}}
</a>
</li>

View File

@ -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>

View File

@ -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>

View File

@ -11,6 +11,7 @@ use std::{
};
use futures::channel::oneshot;
use handlebars::Handlebars;
use hyper::{
Body,
Method,
@ -20,7 +21,7 @@ use hyper::{
StatusCode,
};
use hyper::service::{make_service_fn, service_fn};
use serde::Serialize;
use tokio::{
sync::Mutex,
time::delay_for,
@ -38,6 +39,7 @@ enum Message {
#[derive (Default)]
struct ServerState {
handlebars: Arc <Handlebars <'static>>,
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 (handle_http_listen (state, listen_code.into ()).await)
Ok (if let Some (listen_code) = prefix_match (path, "/7ZSFUKGV_http_listen/") {
handle_http_listen (state, listen_code.into ()).await
}
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 path = String::from (&rest [idx..]);
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 {
Ok (status_reply (StatusCode::BAD_REQUEST, "Bad URI format"))
status_reply (StatusCode::BAD_REQUEST, "Bad URI format")
}
}
else if path == "/relay_up_check" {
Ok (status_reply (StatusCode::OK, "Relay is up\n"))
status_reply (StatusCode::OK, "Relay is up\n")
}
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>> {
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 state = state.clone ();

View File

@ -58,13 +58,15 @@ impl <T: 'static + Send + Sync> Watchers <T> {
let id_2 = id.clone ();
{
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 {
delay_for (timeout).await;
let mut that = that.lock ().await;
that.remove_watcher (&id);
//println! ("Removed server {}", id);
});
if let Ok (message) = r.await {

View File

@ -285,15 +285,15 @@ pub async fn serve_all (
}
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! [
("file_server_dir_entry", "ptth_handlebars/file_server_dir_entry.html"),
("file_server_dir", "ptth_handlebars/file_server_dir.html"),
("file_server_dir", "file_server_dir.html"),
].into_iter () {
handlebars.register_template_file (k, v)?;
handlebars.register_template_file (k, format! ("ptth_handlebars/{}", v))?;
}
Ok (handlebars)

View File

@ -1,7 +1,6 @@
- Offer list of clients at server root
- Parameter for server URL
- 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
impersonate servers