Compare commits

..

10 Commits

Author SHA1 Message Date
_ b642142332 🐛 bug: fix content length when byte serving 2021-11-13 21:31:30 -06:00
_ 80f1c21fd0 Merge remote-tracking branch 'origin/main' 2021-11-13 20:29:22 -06:00
_ 16aaac0965 🐛 bug: used the wrong PathBuf function in resolving the merge 2021-10-14 18:51:12 -05:00
_ 134035f198 Merge remote-tracking branch 'origin/main' 2021-10-14 18:35:31 -05:00
_ ba4f830927 Merge commit 'b8c370a0a6b37ce41078c1fd3e03c6b60e3ab2c2' 2021-10-03 16:03:47 -05:00
_ 9e8e44eae0 📝 working on draft readme 2021-10-03 15:53:38 -05:00
_ 1abf1d194c 🚧 maybe HTTP Basic Auth? 2021-08-29 20:56:32 -05:00
_ 5376e8bba0 🚧 wip: add placeholder for client tokens 2021-08-29 20:17:25 -05:00
_ 324c1f7cd6 ♻️ refactor: remove pointless `Option <>` for file server root 2021-08-29 19:49:32 -05:00
_ 259f71b478 run test relay on TCP 40000 so tests can pass
even if a real relay is on TCP 4000
2021-08-29 19:27:43 -05:00
6 changed files with 59 additions and 40 deletions

View File

@ -111,7 +111,7 @@ pub async fn main (_args: &[OsString]) -> anyhow::Result <()> {
}); });
let state = Arc::new (FileServer::new ( let state = Arc::new (FileServer::new (
file_server_root, file_server_root.unwrap_or_else (|| PathBuf::from (".")),
&PathBuf::new (), &PathBuf::new (),
name, name,
metrics_interval, metrics_interval,

View File

@ -56,7 +56,7 @@ use errors::FileServerError;
#[derive (Default)] #[derive (Default)]
pub struct Config { pub struct Config {
pub file_server_root: Option <PathBuf>, pub file_server_root: PathBuf,
} }
pub struct FileServer { pub struct FileServer {
@ -69,7 +69,7 @@ pub struct FileServer {
impl FileServer { impl FileServer {
pub fn new ( pub fn new (
file_server_root: Option <PathBuf>, file_server_root: PathBuf,
asset_root: &Path, asset_root: &Path,
name: String, name: String,
metrics_interval: Arc <ArcSwap <Option <metrics::Interval>>>, metrics_interval: Arc <ArcSwap <Option <metrics::Interval>>>,
@ -312,12 +312,12 @@ async fn stream_file (
break; break;
} }
buffer.truncate (bytes_read);
let bytes_read_64 = u64::try_from (bytes_read).expect ("Couldn't fit usize into u64"); let bytes_read_64 = u64::try_from (bytes_read).expect ("Couldn't fit usize into u64");
let bytes_read_64 = min (bytes_left, bytes_read_64); let bytes_read_64 = min (bytes_left, bytes_read_64);
buffer.truncate (bytes_read_64 as usize);
if tx.send (Ok::<_, Infallible> (buffer)).await.is_err () { if tx.send (Ok::<_, Infallible> (buffer)).await.is_err () {
warn! ("Cancelling file stream (Sent {} out of {} bytes)", bytes_sent, content_length); warn! ("Cancelling file stream (Sent {} out of {} bytes)", bytes_sent, content_length);
break; break;
@ -371,10 +371,7 @@ impl FileServer {
resp resp
} }
let default_root = PathBuf::from ("./"); let root: &std::path::Path = &self.config.file_server_root;
let root: &std::path::Path = self.config.file_server_root
.as_ref ()
.unwrap_or (&default_root);
Ok (match internal::serve_all (root, method, uri, headers, self.hidden_path.as_deref ()).await? { Ok (match internal::serve_all (root, method, uri, headers, self.hidden_path.as_deref ()).await? {
Favicon => serve_error (StatusCode::NotFound, "Not found\n"), Favicon => serve_error (StatusCode::NotFound, "Not found\n"),

View File

@ -51,6 +51,7 @@ pub mod load_toml;
pub mod prelude; pub mod prelude;
use std::{ use std::{
collections::*,
future::Future, future::Future,
path::PathBuf, path::PathBuf,
sync::Arc, sync::Arc,
@ -70,6 +71,7 @@ use tokio_stream::wrappers::ReceiverStream;
use ptth_core::{ use ptth_core::{
http_serde, http_serde,
}; };
// use crate::key_validity::BlakeHashWrapper;
use errors::ServerError; use errors::ServerError;
use prelude::*; use prelude::*;
@ -214,10 +216,14 @@ pub struct ConfigFile {
/// Directory that the file server module will expose to clients /// Directory that the file server module will expose to clients
/// over the relay. If None, the current working dir is used. /// over the relay. If None, the current working dir is used.
pub file_server_root: Option <PathBuf>, pub file_server_root: PathBuf,
/// For debugging. /// For debugging.
pub throttle_upload: bool, pub throttle_upload: bool,
pub client_keys: HashSet <String>,
pub allow_any_client: bool,
} }
impl ConfigFile { impl ConfigFile {
@ -227,8 +233,10 @@ impl ConfigFile {
name, name,
api_key, api_key,
relay_url, relay_url,
file_server_root: None, file_server_root: PathBuf::from ("."),
throttle_upload: false, throttle_upload: false,
client_keys: Default::default (),
allow_any_client: true,
} }
} }
@ -267,8 +275,10 @@ impl Builder {
name, name,
api_key: ptth_core::gen_key (), api_key: ptth_core::gen_key (),
relay_url, relay_url,
file_server_root: None, file_server_root: PathBuf::from ("."),
throttle_upload: false, throttle_upload: false,
client_keys: Default::default (),
allow_any_client: true,
}; };
Self { Self {
@ -311,7 +321,7 @@ pub async fn run_server (
let file_server = file_server::FileServer::new ( let file_server = file_server::FileServer::new (
config_file.file_server_root.clone (), config_file.file_server_root.clone (),
&asset_root.clone ().unwrap_or_else (PathBuf::new), &asset_root.clone ().unwrap_or_else (|| PathBuf::from (".")),
config_file.name.clone (), config_file.name.clone (),
metrics_interval, metrics_interval,
hidden_path.clone (), hidden_path.clone (),
@ -520,8 +530,10 @@ pub mod executable {
name: opt.name.or (config_file.name).ok_or (anyhow::anyhow! ("`name` must be provided in command line or config file"))?, name: opt.name.or (config_file.name).ok_or (anyhow::anyhow! ("`name` must be provided in command line or config file"))?,
api_key: config_file.api_key, api_key: config_file.api_key,
relay_url: opt.relay_url.or (config_file.relay_url).ok_or (anyhow::anyhow! ("`--relay-url` must be provided in command line or `relay_url` in config file"))?, relay_url: opt.relay_url.or (config_file.relay_url).ok_or (anyhow::anyhow! ("`--relay-url` must be provided in command line or `relay_url` in config file"))?,
file_server_root: opt.file_server_root.or (config_file.file_server_root), file_server_root: opt.file_server_root.or (config_file.file_server_root).unwrap_or_else (PathBuf::new),
throttle_upload: opt.throttle_upload, throttle_upload: opt.throttle_upload,
allow_any_client: true,
client_keys: Default::default (),
}; };
if opt.print_tripcode { if opt.print_tripcode {

View File

@ -57,8 +57,10 @@ fn main ()
name: gui.input_name.value ().to_string (), name: gui.input_name.value ().to_string (),
api_key: gui.input_api_key.value ().to_string (), api_key: gui.input_api_key.value ().to_string (),
relay_url: gui.input_relay_url.value ().to_string (), relay_url: gui.input_relay_url.value ().to_string (),
file_server_root: Some (std::path::PathBuf::from (gui.input_file_server_root.value ())), file_server_root: std::path::PathBuf::from (gui.input_file_server_root.value ()),
throttle_upload: false, throttle_upload: false,
client_keys: Default::default (),
allow_any_client: true,
}; };
let task = rt.spawn (async { let task = rt.spawn (async {

View File

@ -4,35 +4,43 @@ TODO: "Splitting a server in half" diagram
# PTTH # PTTH
PTTH lets you run file servers from behind NAT / firewalls. PTTH is a web server.
A web server has:
1. A public host
2. Files to serve
**With PTTH, the files can live outside of the public host.**
If you want to host 1 TB of files, normally you'd put them on the
cloud server:
``` ```
HTTP clients ptth_server instances Cloud
HTTP server ----> 1 TB of files
Firefox ---> | | <--- Server 1 ^
Chromium --> | | <--- Server 2 Not cloud |
Wget ------> | ptth_relay | <--- Server 3 HTTP client
Curl ------> | | <--- Server 4
Reqwest ---> | | <--- Server 5
``` ```
# Setup But uploading 1 TB to the cloud is expensive and slow, even if
you're sending it to S3-like blob storage.
Pick a relay computer and a server computer. With PTTH, the files can live outside of the cloud:
The relay must be able to accept incoming HTTP connections. If the relay ```
will be exposed to the Internet, you should use Nginx, Caddy, or Apache as a Cloud
reverse proxy to terminate TLS in front of ptth_relay. Relays on the Internet +-----> ptth_relay <------+
will typically have a domain name so that clients and servers can find them. | |
Not cloud | |
HTTP client ptth_server
1 TB of files
```
The server must have read access to the files you want to serve, and it must The PTTH server lives where the files live.
be able to make outgoing HTTP(S) connections to the relay. The server The cloud host runs a relay which streams files from the end
does not need a static IP, since it won't accept any incoming HTTP connections. server as the client demands.
Begin installing PTTH. Run `cargo install ptth_relay` on the relay and For home users, this can save you money - The relay server
`cargo install ptth_server` on the server. ptth_server is manually tested on doesn't need to store any of your files.
Windows and Linux. ptth_relay is manually tested on Linux only.
- Run ptth_relay on cloud host
- Configure ptth_server for relay, with auto keygen
- Add tripcode to relay config

View File

@ -175,7 +175,7 @@ async fn end_to_end () {
//tracing_subscriber::fmt ().try_init ().ok (); //tracing_subscriber::fmt ().try_init ().ok ();
let relay_port = 4000; let relay_port = 40000;
// No proxy // No proxy
let proxy_port = relay_port; let proxy_port = relay_port;
let server_name = "aliens_wildland"; let server_name = "aliens_wildland";