♻️ Extract load_templates fn for file server

main
_ 2020-10-31 12:56:36 -05:00
parent bf48eb2dbd
commit 9244953e57
6 changed files with 39 additions and 63 deletions

View File

@ -18,6 +18,11 @@ use hyper::{
StatusCode,
};
use ptth::{
http_serde::RequestParts,
server::file_server,
};
struct ServerState <'a> {
handlebars: Arc <handlebars::Handlebars <'a>>,
}
@ -41,11 +46,6 @@ fn prefix_match <'a> (hay: &'a str, needle: &str) -> Option <&'a str>
async fn handle_all (req: Request <Body>, state: Arc <ServerState <'static>>)
-> Result <Response <Body>, Infallible>
{
use ptth::{
http_serde::RequestParts,
server::file_server,
};
let path = req.uri ().path ();
//println! ("{}", path);
@ -90,16 +90,7 @@ async fn handle_all (req: Request <Body>, state: Arc <ServerState <'static>>)
async fn main () -> Result <(), Box <dyn Error>> {
let addr = SocketAddr::from(([0, 0, 0, 0], 4000));
let mut handlebars = handlebars::Handlebars::new ();
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"),
].into_iter () {
handlebars.register_template_file (k, v)?;
}
let handlebars = Arc::new (handlebars);
let handlebars = Arc::new (file_server::load_templates ()?);
let state = Arc::new (ServerState {
handlebars,

View File

@ -44,7 +44,7 @@ mod tests {
spawn (async move {
let opt = server::Opt {
relay_url: relay_url_2,
file_server_root: ".".into (),
file_server_root: "./".into (),
};
server::main (opt).await.unwrap ();
@ -57,7 +57,7 @@ mod tests {
assert_eq! (resp, "Relay is up\n");
let resp = client.get (&format! ("{}/http_request/alien_wildlands/COPYING", relay_url))
let resp = client.get (&format! ("{}/servers/alien_wildlands/COPYING", relay_url))
.send ().await.unwrap ().bytes ().await.unwrap ();
assert_eq! (blake3::hash (&resp), blake3::Hash::from ([

View File

@ -32,7 +32,6 @@ use crate::{
use watcher::*;
enum Message {
Meow,
HttpRequestResponse (http_serde::WrappedRequest),
HttpResponseResponseStream ((http_serde::ResponseParts, Body)),
}
@ -48,35 +47,13 @@ fn status_reply <B: Into <Body>> (status: StatusCode, b: B)
Response::builder ().status (status).body (b.into ()).unwrap ()
}
async fn handle_watch (state: Arc <ServerState>, watcher_code: String)
-> Response <Body>
{
match Watchers::long_poll (state.watchers.clone (), watcher_code).await {
None => status_reply (StatusCode::OK, "no\n"),
Some (_) => status_reply (StatusCode::OK, "actually, yes\n"),
}
}
async fn handle_wake (state: Arc <ServerState>, watcher_code: String)
-> Response <Body>
{
let mut watchers = state.watchers.lock ().await;
if watchers.wake_one (Message::Meow, &watcher_code) {
status_reply (StatusCode::OK, "ok\n")
}
else {
status_reply (StatusCode::BAD_REQUEST, "no\n")
}
}
async fn handle_http_listen (state: Arc <ServerState>, watcher_code: String)
-> Response <Body>
{
//println! ("Step 1");
match Watchers::long_poll (state.watchers.clone (), watcher_code).await {
Some (Message::HttpRequestResponse (parts)) => {
println! ("Step 3");
//println! ("Step 3");
status_reply (StatusCode::OK, rmp_serde::to_vec (&parts).unwrap ())
},
_ => status_reply (StatusCode::GATEWAY_TIMEOUT, "no\n"),
@ -90,21 +67,21 @@ async fn handle_http_response (
)
-> Response <Body>
{
println! ("Step 6");
//println! ("Step 6");
let (parts, body) = req.into_parts ();
let resp_parts: http_serde::ResponseParts = rmp_serde::from_read_ref (&base64::decode (parts.headers.get (crate::PTTH_MAGIC_HEADER).unwrap ()).unwrap ()).unwrap ();
{
let mut watchers = state.watchers.lock ().await;
println! ("Step 7");
//println! ("Step 7");
if ! watchers.wake_one (Message::HttpResponseResponseStream ((resp_parts, body)), &req_id)
{
println! ("Step 8 (bad thing)");
status_reply (StatusCode::BAD_REQUEST, "A bad thing happened.\n")
}
else {
println! ("Step 8");
//println! ("Step 8");
status_reply (StatusCode::OK, "ok\n")
}
}
@ -131,7 +108,7 @@ async fn handle_http_request (
}
};
println! ("Step 2 {}", parts.id);
//println! ("Step 2 {}", parts.id);
let (s, r) = oneshot::channel ();
let timeout = Duration::from_secs (5);
@ -148,7 +125,7 @@ async fn handle_http_request (
{
let mut watchers = state.watchers.lock ().await;
println! ("Step 3");
//println! ("Step 3");
if ! watchers.wake_one (Message::HttpRequestResponse (parts), &watcher_code) {
watchers.remove_watcher (&req_id);
}
@ -163,7 +140,7 @@ async fn handle_http_request (
match r.await {
Ok (Message::HttpResponseResponseStream ((resp_parts, body))) => {
println! ("Step 7");
//println! ("Step 7");
let mut resp = Response::builder ()
.status (hyper::StatusCode::from (resp_parts.status_code));
@ -200,7 +177,7 @@ async fn handle_all (req: Request <Body>, state: Arc <ServerState>)
// This is stuff the server can use. Clients can't
// POST right now
return Ok (if let Some (request_code) = prefix_match (path, "/http_response/") {
return Ok (if let Some (request_code) = prefix_match (path, "/7ZSFUKGV_http_response/") {
let request_code = request_code.into ();
handle_http_response (req, state, request_code).await
}
@ -209,16 +186,10 @@ async fn handle_all (req: Request <Body>, state: Arc <ServerState>)
});
}
if let Some (watch_code) = prefix_match (path, "/watch/") {
Ok (handle_watch (state, watch_code.into ()).await)
}
else if let Some (watch_code) = prefix_match (path, "/wake/") {
Ok (handle_wake (state, watch_code.into ()).await)
}
else if let Some (listen_code) = prefix_match (path, "/http_listen/") {
if let Some (listen_code) = prefix_match (path, "/7ZSFUKGV_http_listen/") {
Ok (handle_http_listen (state, listen_code.into ()).await)
}
else if let Some (rest) = prefix_match (path, "/http_request/") {
else if let Some (rest) = prefix_match (path, "/servers/") {
if let Some (idx) = rest.find ('/') {
let listen_code = String::from (&rest [0..idx]);
let path = String::from (&rest [idx..]);

View File

@ -3,6 +3,7 @@
use std::{
cmp::{min, max},
convert::{Infallible, TryInto},
error::Error,
io::SeekFrom,
path::{Path, PathBuf},
sync::Arc,
@ -283,6 +284,21 @@ pub async fn serve_all (
}
}
pub fn load_templates ()
-> Result <handlebars::Handlebars <'static>, Box <dyn Error>>
{
let mut handlebars = handlebars::Handlebars::new ();
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"),
].into_iter () {
handlebars.register_template_file (k, v)?;
}
Ok (handlebars)
}
#[cfg (test)]
mod tests {
#[test]

View File

@ -45,7 +45,7 @@ async fn handle_req_resp <'a> (
let response = file_server::serve_all (handlebars, &opt.file_server_root, parts).await;
let mut resp_req = client
.post (&format! ("{}/http_response/{}", opt.relay_url, req_id))
.post (&format! ("{}/7ZSFUKGV_http_response/{}", opt.relay_url, req_id))
.header (crate::PTTH_MAGIC_HEADER, base64::encode (rmp_serde::to_vec (&response.parts).unwrap ()));
if let Some (body) = response.body {
@ -67,11 +67,7 @@ pub async fn main (opt: Opt) -> Result <(), Box <dyn Error>> {
let client = Arc::new (Client::new ());
let opt = Arc::new (opt);
let mut handlebars = handlebars::Handlebars::new ();
handlebars.register_template_file ("file_server_dir_entry", "ptth_handlebars/file_server_dir_entry.html")?;
let handlebars = Arc::new (handlebars);
let handlebars = Arc::new (file_server::load_templates ()?);
let mut backoff_delay = 0;
@ -80,7 +76,7 @@ pub async fn main (opt: Opt) -> Result <(), Box <dyn Error>> {
delay_for (Duration::from_millis (backoff_delay)).await;
}
let req_req = client.get (&format! ("{}/http_listen/{}", opt.relay_url, SERVER_NAME));
let req_req = client.get (&format! ("{}/7ZSFUKGV_http_listen/{}", opt.relay_url, SERVER_NAME));
let req_resp = match req_req.send ().await {
Err (e) => {

View File

@ -8,3 +8,5 @@ impersonate servers
- Prevent directory traversal attacks
- Fix possible timing gap when refreshing http_listen (Just have client wait a few seconds?)
- Error handling
- Reverse proxy to other local servers