# PTTH An HTTP server that can run behind a firewall by connecting out to a relay. ``` Outside the tunnel +--------+ +------------+ +-------------+ | Client | ------> | PTTH relay | <----- | PTTH server | +--------+ +------------+ +-------------+ Inside the tunnel +--------+ -------------- +-------------+ | Client | ----------------------------> | Server | +--------+ -------------- +-------------+ ``` The server can run behind a firewall, because it is actually a special HTTP client. ## How to configure The server must be configured first so that its tripcode can be registered with the relay. Configuring a server: - Copy ptth_server or ptth_server.exe onto the server - Create ptth_server.toml in the server's working dir - Add a human-readable name and a secret API key generated by diceware method - Run the server and use Ctrl+C to close it. It will print a tripcode to the terminal. Copy that to the relay. Configuring the relay: - Copy ptth_relay onto the server (A Dockerfile is provided with no guarantees) - Create ptth_relay.toml in the relay's working dir - Add the tripcodes of all servers to the server_tripcodes table Example server config: (Won't run because the key is too weak) ``` name = "my_server" api_key = "secretpassword" relay_url = "http://127.0.0.1:4000" ``` Example relay config: ``` [server_tripcodes] my_server = "czpCob1t1T7IU9zIlYyoNRomyeN7pqKSg1R0EUPz6Pw=" some_other_server = "su2wWbTyf5xih4yiCTfAzqDlASatV+0dI+UVKFBIsEI=" ``` ## How to run The relay should run first so that the server(s) can connect to it without error. 1. Start the relay 2. Start a server 3. Use a client to access a server through the relay From the source code directory: - `cargo run --bin ptth_relay` - `cargo run --bin ptth_server` - `firefox http://127.0.0.1:4000/servers/my_server/files/` If you only have pre-built binaries: - `./ptth_relay` - `./ptth_server` - `firefox http://127.0.0.1:4000/servers/my_server/files/` "ptth_file_server" is not needed for production. It's a standalone build of the file server module, for testing. To run the relay behind Nginx, these directives improve time-to-first-byte when streaming: ``` client_max_body_size 0; proxy_http_version 1.1; proxy_request_buffering off; proxy_buffering off; ``` ## Comparison with normal HTTP Normal HTTP: ``` Client Server H1 O ---------> O | H2 O <--------- O H3 ``` 1. The client connects to the server and sends a request 2. The server accepts the connection and processes the request 3. The server responds with a response We'll call these steps "H1", "H2", and "H3" in the next section. PTTH: ``` Client Relay Server P1 O <----- O P2/H1 | O ------> O | P3 O -----> O | P4/H2 O <----- O | P5 O <------ O P6/H3 ``` We'll call these steps "P1" through "P6". 1. The server makes a "listen" request to the relay, punching out through the server's firewall. The server and relay are now in a long-polling state with each other, waiting for a client to make a request. 2. A client makes a request to the relay. (P2 == H1) 3. The relay packages the request and sends it as a response to the server, completing the server's request in P1. The client and relay are now in a long-polling state, waiting for the server to respond. 4. The server processes the request. (P4 == H2) 5. The server packages its response in another request to the relay. 6. The relay unwraps the request and forwards it to the client. (P6 == H3) Every step of the normal HTTP process is inverted for the server: - It must stay connected to the relay even when nothing is happening - A request arrives packaged in a response - A response is sent out packaged as a request There are twice as many steps, and the per-connection and per-request overhead is probably high. But once the connections are established, the only overhead is that of using a relay, which is similar to many other file transfer or remote desktop software. ## Comparison with similar software PTTH is very similar to [PageKite](https://github.com/pagekite/PyPagekite). PTTH's relay is equivalent to PageKite's front-end server, and PTTH's server is equivalent to (I think) PageKite's backend. WireGuard can also pierce firewalls, but it requires root permissions, and the client must be a WireGuard node. PTTH allows any normal HTTP client such as curl, Firefox, etc. ## Module overview ``` +------------+ +-------------+ +------------------+ | ptth_relay | | ptth_server | | ptth_file_server | +------------+ +-------------+ +------------------+ | | | | \ / \ / V V V V +------------+ +-------------+ | http_serde | | file_server | +------------+ +-------------+ ``` The top-level binaries are ptth_relay, ptth_server, and ptth_file_server. ptth_relay should run on a well-known public server, behind an HTTPS proxy such as Caddy, Nginx, or Apache. ptth_file_server is a standalone HTTP file server, similar to Python2's `-m SimpleHTTPServer` command, or Python3's `-m http.server`. ptth_server and ptth_file_server use the `file_server` module. ptth_server will connect out to a ptth_relay instance and serve files through the reverse HTTP tunnel. The `http_serde` module is shared by ptth_relay and ptth_server so that they can communicate with each other easily. ## Why are GitHub issues disabled? Because they are not part of Git. For now, either email me (if you know me personally) or make a pull request to add an item to [todo.md](todo.md). ## License PTTH is licensed under the [GNU AGPLv3](https://www.gnu.org/licenses/agpl-3.0.html) Copyright 2020 "Trish"