♻️ Extract load_templates fn for file server
parent
bf48eb2dbd
commit
9244953e57
|
@ -18,6 +18,11 @@ use hyper::{
|
||||||
StatusCode,
|
StatusCode,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use ptth::{
|
||||||
|
http_serde::RequestParts,
|
||||||
|
server::file_server,
|
||||||
|
};
|
||||||
|
|
||||||
struct ServerState <'a> {
|
struct ServerState <'a> {
|
||||||
handlebars: Arc <handlebars::Handlebars <'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>>)
|
async fn handle_all (req: Request <Body>, state: Arc <ServerState <'static>>)
|
||||||
-> Result <Response <Body>, Infallible>
|
-> Result <Response <Body>, Infallible>
|
||||||
{
|
{
|
||||||
use ptth::{
|
|
||||||
http_serde::RequestParts,
|
|
||||||
server::file_server,
|
|
||||||
};
|
|
||||||
|
|
||||||
let path = req.uri ().path ();
|
let path = req.uri ().path ();
|
||||||
//println! ("{}", 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>> {
|
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 mut handlebars = handlebars::Handlebars::new ();
|
let handlebars = Arc::new (file_server::load_templates ()?);
|
||||||
|
|
||||||
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 state = Arc::new (ServerState {
|
let state = Arc::new (ServerState {
|
||||||
handlebars,
|
handlebars,
|
||||||
|
|
|
@ -44,7 +44,7 @@ mod tests {
|
||||||
spawn (async move {
|
spawn (async move {
|
||||||
let opt = server::Opt {
|
let opt = server::Opt {
|
||||||
relay_url: relay_url_2,
|
relay_url: relay_url_2,
|
||||||
file_server_root: ".".into (),
|
file_server_root: "./".into (),
|
||||||
};
|
};
|
||||||
|
|
||||||
server::main (opt).await.unwrap ();
|
server::main (opt).await.unwrap ();
|
||||||
|
@ -57,7 +57,7 @@ mod tests {
|
||||||
|
|
||||||
assert_eq! (resp, "Relay is up\n");
|
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 ();
|
.send ().await.unwrap ().bytes ().await.unwrap ();
|
||||||
|
|
||||||
assert_eq! (blake3::hash (&resp), blake3::Hash::from ([
|
assert_eq! (blake3::hash (&resp), blake3::Hash::from ([
|
||||||
|
|
|
@ -32,7 +32,6 @@ use crate::{
|
||||||
use watcher::*;
|
use watcher::*;
|
||||||
|
|
||||||
enum Message {
|
enum Message {
|
||||||
Meow,
|
|
||||||
HttpRequestResponse (http_serde::WrappedRequest),
|
HttpRequestResponse (http_serde::WrappedRequest),
|
||||||
HttpResponseResponseStream ((http_serde::ResponseParts, Body)),
|
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 ()
|
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)
|
async fn handle_http_listen (state: Arc <ServerState>, watcher_code: String)
|
||||||
-> Response <Body>
|
-> Response <Body>
|
||||||
{
|
{
|
||||||
//println! ("Step 1");
|
//println! ("Step 1");
|
||||||
match Watchers::long_poll (state.watchers.clone (), watcher_code).await {
|
match Watchers::long_poll (state.watchers.clone (), watcher_code).await {
|
||||||
Some (Message::HttpRequestResponse (parts)) => {
|
Some (Message::HttpRequestResponse (parts)) => {
|
||||||
println! ("Step 3");
|
//println! ("Step 3");
|
||||||
status_reply (StatusCode::OK, rmp_serde::to_vec (&parts).unwrap ())
|
status_reply (StatusCode::OK, rmp_serde::to_vec (&parts).unwrap ())
|
||||||
},
|
},
|
||||||
_ => status_reply (StatusCode::GATEWAY_TIMEOUT, "no\n"),
|
_ => status_reply (StatusCode::GATEWAY_TIMEOUT, "no\n"),
|
||||||
|
@ -90,21 +67,21 @@ async fn handle_http_response (
|
||||||
)
|
)
|
||||||
-> Response <Body>
|
-> Response <Body>
|
||||||
{
|
{
|
||||||
println! ("Step 6");
|
//println! ("Step 6");
|
||||||
let (parts, body) = req.into_parts ();
|
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 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;
|
let mut watchers = state.watchers.lock ().await;
|
||||||
|
|
||||||
println! ("Step 7");
|
//println! ("Step 7");
|
||||||
if ! watchers.wake_one (Message::HttpResponseResponseStream ((resp_parts, body)), &req_id)
|
if ! watchers.wake_one (Message::HttpResponseResponseStream ((resp_parts, body)), &req_id)
|
||||||
{
|
{
|
||||||
println! ("Step 8 (bad thing)");
|
println! ("Step 8 (bad thing)");
|
||||||
status_reply (StatusCode::BAD_REQUEST, "A bad thing happened.\n")
|
status_reply (StatusCode::BAD_REQUEST, "A bad thing happened.\n")
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
println! ("Step 8");
|
//println! ("Step 8");
|
||||||
status_reply (StatusCode::OK, "ok\n")
|
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 (s, r) = oneshot::channel ();
|
||||||
let timeout = Duration::from_secs (5);
|
let timeout = Duration::from_secs (5);
|
||||||
|
@ -148,7 +125,7 @@ async fn handle_http_request (
|
||||||
{
|
{
|
||||||
let mut watchers = state.watchers.lock ().await;
|
let mut watchers = state.watchers.lock ().await;
|
||||||
|
|
||||||
println! ("Step 3");
|
//println! ("Step 3");
|
||||||
if ! watchers.wake_one (Message::HttpRequestResponse (parts), &watcher_code) {
|
if ! watchers.wake_one (Message::HttpRequestResponse (parts), &watcher_code) {
|
||||||
watchers.remove_watcher (&req_id);
|
watchers.remove_watcher (&req_id);
|
||||||
}
|
}
|
||||||
|
@ -163,7 +140,7 @@ async fn handle_http_request (
|
||||||
|
|
||||||
match r.await {
|
match r.await {
|
||||||
Ok (Message::HttpResponseResponseStream ((resp_parts, body))) => {
|
Ok (Message::HttpResponseResponseStream ((resp_parts, body))) => {
|
||||||
println! ("Step 7");
|
//println! ("Step 7");
|
||||||
|
|
||||||
let mut resp = Response::builder ()
|
let mut resp = Response::builder ()
|
||||||
.status (hyper::StatusCode::from (resp_parts.status_code));
|
.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
|
// This is stuff the server can use. Clients can't
|
||||||
// POST right now
|
// 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 ();
|
let request_code = request_code.into ();
|
||||||
handle_http_response (req, state, request_code).await
|
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/") {
|
if let Some (listen_code) = prefix_match (path, "/7ZSFUKGV_http_listen/") {
|
||||||
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/") {
|
|
||||||
Ok (handle_http_listen (state, listen_code.into ()).await)
|
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 ('/') {
|
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..]);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
use std::{
|
use std::{
|
||||||
cmp::{min, max},
|
cmp::{min, max},
|
||||||
convert::{Infallible, TryInto},
|
convert::{Infallible, TryInto},
|
||||||
|
error::Error,
|
||||||
io::SeekFrom,
|
io::SeekFrom,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::Arc,
|
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)]
|
#[cfg (test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -45,7 +45,7 @@ async fn handle_req_resp <'a> (
|
||||||
let response = file_server::serve_all (handlebars, &opt.file_server_root, parts).await;
|
let response = file_server::serve_all (handlebars, &opt.file_server_root, parts).await;
|
||||||
|
|
||||||
let mut resp_req = client
|
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 ()));
|
.header (crate::PTTH_MAGIC_HEADER, base64::encode (rmp_serde::to_vec (&response.parts).unwrap ()));
|
||||||
|
|
||||||
if let Some (body) = response.body {
|
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 client = Arc::new (Client::new ());
|
||||||
let opt = Arc::new (opt);
|
let opt = Arc::new (opt);
|
||||||
|
|
||||||
let mut handlebars = handlebars::Handlebars::new ();
|
let handlebars = Arc::new (file_server::load_templates ()?);
|
||||||
|
|
||||||
handlebars.register_template_file ("file_server_dir_entry", "ptth_handlebars/file_server_dir_entry.html")?;
|
|
||||||
|
|
||||||
let handlebars = Arc::new (handlebars);
|
|
||||||
|
|
||||||
let mut backoff_delay = 0;
|
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;
|
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 {
|
let req_resp = match req_req.send ().await {
|
||||||
Err (e) => {
|
Err (e) => {
|
||||||
|
|
2
todo.md
2
todo.md
|
@ -8,3 +8,5 @@ impersonate servers
|
||||||
- Prevent directory traversal attacks
|
- Prevent directory traversal attacks
|
||||||
- Fix possible timing gap when refreshing http_listen (Just have client wait a few seconds?)
|
- Fix possible timing gap when refreshing http_listen (Just have client wait a few seconds?)
|
||||||
- Error handling
|
- Error handling
|
||||||
|
|
||||||
|
- Reverse proxy to other local servers
|
||||||
|
|
Loading…
Reference in New Issue