Awesome
<!-- / | ___ (___ ___| | )| )| ) |__/ | / |__/ | --> <p align="center"> <img src="./img/logo.png"> <br> <a href="https://github.com/xvxx/phd/releases"> <img src="https://img.shields.io/github/v/release/xvxx/phd?include_prereleases"> </a> <a href="https://crates.io/crates/phd"> <img src="https://img.shields.io/crates/v/phd"> </a> <a href="https://github.com/xvxx/phd/actions?query=workflow%3Abuild"> <img src="https://github.com/xvxx/phd/workflows/build/badge.svg"> </a> </p>phd
is a small, easy-to-use gopher server.
Point it at a directory and it'll serve up all the text files,
sub-directories, and binary files over Gopher. Any .gph
files will
be served up as gophermaps and executable .gph
files will be
run as a program with their output served to the client, like the
glorious cgi-bin days of yore!
~ special files ~
header.gph
: If it exists in a directory, its content will be shown above the directory's content. Put ASCII art in it.footer.gph
: Same, but will be shown below a directory's content.index.gph
: Completely replaces a directory's content with what's in this file.??.gph
: Visitinggopher://yoursite/1/dog/
will try to renderdog.gph
from disk. Visiting/1/dog.gph
will render the raw content of the .gph file..reverse
: If this exists, the directory contents will be listed in reverse alphanumeric order. Useful for phloggin', if you date your posts.
Any line in a .gph
file that doesn't contain tabs (\t
) will get an
i
automatically prefixed, turning it into a Gopher information item.
For your convenience, phd supports geomyidae syntax for creating links:
This is an info line.
[1|This is a link|/help|server|port]
[h|URL Link|URL:https://noogle.com]
server
and port
will get translated into the server and port of
the actively running server, eg localhost
and 7070
.
Any line containing a tab character (\t
) will be sent as-is to the
client, meaning you can write and serve up raw Gophermap files too.
~ dynamic content ~
Any .gph
file that is marked executable with be run as if it
were a standalone program and its output will be sent to the client.
It will be passed three arguments: the query string (if any), the
server's hostname, and the current port. Do with them what you will.
For example:
$ cat echo.gph
#!/bin/sh
echo "Hi, world! You said:" $1
echo "1Visit Gopherpedia / gopherpedia.com 70"
Then:
$ gopher-client gopher://localhost/1/echo?something
[INFO] Hi, world! You said: something
[LINK] Visit Gopherpedia
Or more seriously:
$ cat figlet.gph
#!/bin/sh
figlet $1
then:
$ gopher-client gopher://localhost/1/figlet?hi gopher
[INFO] _ _ _
[INFO] | |__ (_) __ _ ___ _ __ | |__ ___ _ __
[INFO] | '_ \| | / _` |/ _ \| '_ \| '_ \ / _ \ '__|
[INFO] | | | | | | (_| | (_) | |_) | | | | __/ |
[INFO] |_| |_|_| \__, |\___/| .__/|_| |_|\___|_|
[INFO] |___/ |_|
~ ruby on rails ~
sh
is fun, but for serious work you need a serious scripting
language like Ruby or PHP or Node.JS:
$ cat sizes.gph
#!/usr/bin/env ruby
def filesize(file)
(size=File.size file) > (k=1024) ? "#{size/k}K" : "#{size}B"
end
puts "~ file sizes ~"
spaces = 20
Dir[__dir__ + "/*"].each do |entry|
name = File.basename entry
puts "#{name}#{' ' * (spaces - name.length)}#{filesize entry}"
end
Now you can finally share the file sizes of a directory with the world of Gopher!
$ phetch -r 0.0.0.0:7070/1/sizes
i~ file sizes ~ (null) 127.0.0.1 7070
iCargo.toml 731B (null) 127.0.0.1 7070
iLICENSE 1K (null) 127.0.0.1 7070
iMakefile 724B (null) 127.0.0.1 7070
itarget 288B (null) 127.0.0.1 7070
iphd 248K (null) 127.0.0.1 7070
iCargo.lock 2K (null) 127.0.0.1 7070
iREADME.md 4K (null) 127.0.0.1 7070
img 96B (null) 127.0.0.1 7070
isizes.gph 276B (null) 127.0.0.1 7070
isrc 224B (null) 127.0.0.1 7070
~ usage ~
Usage:
phd [options] <root directory>
Options:
-r, --render SELECTOR Render and print SELECTOR to stdout only.
-h, --host HOST Hostname for links. [Default: {host}]
-p, --port PORT Port for links. [Default: {port}]
-b, --bind ADDRESS Socket address to bind to. [Default: {bind}]
--no-color Don't show colors in log messages.
Other flags:
-h, --help Print this screen.
-v, --version Print phd version.
Examples:
phd ./path/to/site # Serve directory over port 7070.
phd -p 70 docs # Serve 'docs' directory on port 70
phd -h gopher.com # Serve current directory over port 7070
# using hostname 'gopher.com'
phd -r / ./site # Render local gopher site to stdout.
~ installation ~
On macOS you can install with Homebrew:
brew install xvxx/code/phd
Binaries for Linux, Mac, and Raspberry Pi are available at gopher://phkt.io/1/releases/phd and https://github.com/xvxx/phd/releases:
Just unzip/untar the phd
program into your $PATH
and get going!
If you have cargo, you can install the crate directly:
cargo install phd --locked
~ development ~
cargo run -- ./path/to/gopher/site
~ resources ~
- gopher://bitreich.org/1/scm/geomyidae/files.gph
- https://github.com/gophernicus/gophernicus/blob/master/README.Gophermap
- https://gopher.zone/posts/how-to-gophermap/
- rfc 1436
~ todo ~
- systemd config, or something
- TLS support
- user input sanitization tests
~ status ~
phd is no longer under active development, but the latest version works great.