seekquarry / atto
Single-file, pure-PHP servers and routing engines: HTTP/1.1+2, gopher, SMTP/IMAP, DNS, FTP, SSH/SFTP, STUN/TURN.
Requires
- php: >=8.0.0
- ext-openssl: *
- ext-pcre: *
- ext-sodium: *
Suggests
- ext-ffi: Required for the optional HTTP/3 listener (loads libquiche via FFI).
- ext-mbstring: Charset conversion for MIME-encoded mail headers in MailSite (non-UTF-8/US-ASCII parts).
- ext-posix: Privilege drop after binding privileged ports in WebSite and GopherSite.
- ext-sockets: Tunes UDP buffer sizes on the HTTP/3 listener; optional even when FFI is present.
README
Atto is a collection of single-file, low-dependency, pure-PHP servers and
routing engines. Each server is one file you drop into a project, configure
with a few chained setters, and start with a listen() call. No Composer
modules required. No build step.
What's in the box:
-
WebSite -- HTTP/1.1, HTTP/2, and HTTP/3 web server and router. Doubles as a micro-framework under Apache, nginx, or lighttpd, or runs standalone. All protocols are pure PHP implementations, the largest, HTTP/3 is in an optional side file as its performance mainly just matches HTTP/2 in our benchmarking. A sibling H3QuicheListener wraps libquiche through PHP-FFI for side-by-side comparison. In our testing, this is slower than the pure implementation because of the FFI overhead.
-
GopherSite -- a gopher protocol server, shaped just like WebSite.
-
MailSite -- SMTP and IMAP in one process. STARTTLS, authenticated submission, mailbox storage, the lot.
-
DnsSite -- authoritative DNS server. Reads zone files, answers UDP and TCP queries, supports DoT (DNS over TLS).
-
FtpSite -- FTP server with explicit and implicit FTPS. Speaks the command set FileZilla and curl expect, including MLSD listings, passive and active data connections, and a path-traversal guard.
-
SshSite -- SSH-2 server (RFC 4250-4254) with the SFTP subsystem. Curve25519 KEX, Ed25519 host keys, AES-128-CTR + HMAC-SHA-256. Password and publickey auth (OpenSSH-format authorized_keys). All crypto comes from PHP's bundled ext-sodium / ext-openssl / ext-hash.
-
TurnSite -- STUN/TURN server (RFC 8489 / RFC 8656) for WebRTC and SIP relays. Long-term credentials, allocations, channels.
A few things every Atto server has in common: request-event-driven (one
PHP process, async I/O); the $site->get('/', ...) routing API carries
through where it makes sense; familiar superglobals like $_GET, $_POST,
$_SESSION, $_FILES are populated for the protocols where that idiom
fits. Sessions live in RAM, timers fire on a schedule, and file I/O goes
through caching fileGetContents / filePutContents helpers.
Hello, World
<?php require 'atto_server_path/src/WebSite.php'; // adjust to your path use seekquarry\atto\WebSite; $site = new WebSite(); $site->get('/', function () { ?> <!DOCTYPE html> <html> <head><title>Hello World - Atto Server</title></head> <body> <h1>Hello World!</h1> <div>My first atto server route!</div> </body> </html> <?php }); if ($site->isCli()) { /* From the command line: php index.php */ $site->listen(8080); } else { /* Behind Apache/nginx/lighttpd via .htaccess + this index.php */ $site->process(); }
Run php index.php, point a browser at http://localhost:8080/, done.
The other servers follow the same shape: swap WebSite for FtpSite or
SshSite or whichever, configure with chained setters, call listen().
Installation
Atto runs on PHP 8+. HTTPS works on any PHP build with ext-openssl; SshSite additionally needs ext-sodium.
Get the code:
git clone https://github.com/seekquarry/atto.git
Then drop one require line into your project:
require 'atto_server_path/src/WebSite.php'; // or whichever Site class use seekquarry\atto\WebSite;
Composer works too:
composer require seekquarry/atto
Then require "vendor/autoload.php" and the Atto Site classes autoload.
Examples
The examples/ folder has a numbered tour: 01-18 are WebSite features
(routing, forms, sessions, WebSockets, streaming, HTTP/3, benchmarks),
and 19 onward are full-protocol demos:
- 19 GopherSite Demo -- a working gopher hole.
- 20 MailSite Demo -- SMTP + IMAP, with
swaksandopenssl s_clientsmoke tests. - 21 Anonymous WebMail -- a webmail front-end on top of MailSite.
- 22 DNS Demo -- click-through DNS scenarios, a query box, and a browser-style zone-file editor.
- 23 FTP Demo -- click-through FTP scenarios, a raw command box, and a live FTP-driven file browser.
- 24 SSH Demo -- click-through SSH/SFTP scenarios with on-wire transcripts, a raw exec command box, and a multi-user file browser.
- 25 TURN Demo -- click-through STUN/TURN scenarios with full STUN message decode and a raw STUN/TURN method explorer.
To run any example:
php index.php 19 # or 20, 21, 22, 23, 24, 25, ...
Each demo's index.php carries a header docblock describing its config,
demo credentials, and a "How to connect" pointer for real-world clients
(curl, FileZilla, ssh, swaks, etc.). Demos 22-25 also spawn a companion
web UI at http://localhost:8080/ so you can poke at the server from
your browser without leaving PHP.
Going Further
The demo webui.php files are full worked examples of using an Atto Site
class as a library: client classes, transcripts, error handling, all in
one file. Copy a Site class into your own project, write your own routes,
and you're off.
Atto's whole pitch is single-file, no friction. Skim the source of any Site class -- they're documented top to bottom -- and write the server your project actually needs.