This project implements a minimal secure-FTP-style protocol (“SFTPQ”) on top of QUIC using Python and aioquic.
It provides a simple command-line client and server, with support for login, directory listing, file upload/download (with compression + SHA-256 integrity), and clean shutdown.
You should have received a zip archive named ftp.zip containing all source files. Unzip it and enter the ftp directory:
unzip ftp.zip
cd ftppython3 -m venv venv
source venv/bin/activate # on WSLpip install --upgrade pip
pip install aioquic
pip install -r requirements.txtmkdir certs
cd certsGenerate a 2048-bit RSA private key:
openssl genrsa -out quic_private_key.pem 2048Generate a self-signed certificate (valid 1 year):
openssl req -new -x509 \
-key quic_private_key.pem \
-out quic_certificate.pem \
-days 365 \
-subj "/C=US/ST=PA/L=Philadelphia/O=Drexel University/CN=localhost"cd ..After extraction and cert generation, you should have:
ftp/
├── certs/
│ ├── quic_certificate.pem
│ └── quic_private_key.pem
├── uploads/ ← created automatically by server
├── downloads/ ← created automatically by client
├── echo.py ← main CLI entrypoint (client & server modes)
├── quic_engine.py ← QUIC setup & protocol dispatch
├── echo_quic.py ← QuicStreamEvent & EchoQuicConnection wrappers
├── echo_server.py ← server-side protocol logic
├── echo_client.py ← client-side protocol logic
├── pdu.py ← message definitions (Datagram, MSG_TYPE_…)
├── requirements.txt
└── venv/
In one terminal (with venv active), start the server:
python echo.py server \
--cert-file certs/quic_certificate.pem \
--key-file certs/quic_private_key.pem \
--listen 0.0.0.0 \
--port 4433Binds on all interfaces (0.0.0.0) port 4433 by default. Creates uploads/ if it does not exist.
or simply
python echo.py serverIn another terminal (with the same venv active), start the client:
python echo.py client \
--server localhost \
--port 4433 \
--cert-file certs/quic_certificate.pemPrompts for Username and Password at first run (username- bob, password- builder). Creates downloads/ on first successful download.
or simply
python echo.py clientAt the sftpq> prompt, use:
1. list → request and display remote files stored by the server.
2. lls or list-local → show local files in your current directory.
3. upload → compress (gzip), hash (SHA-256), base64-encode, then send file.
4. download → request, receive, verify, decompress, and save file to downloads/.
5. exit → terminate session and close connection.
- Start server (see above).
- Connect client (see above).
- Interact:
sftpq> list
Remote files: []
sftpq> upload example.txt
📤 Upload complete
sftpq> list
Remote files: ['example.txt']
sftpq> lls
Local files: ['example.txt', 'echo.py', ...]
sftpq> download example.txt
📥 Downloaded → downloads/example.txt
sftpq> exit
👋 Goodbye!
- Confirm that uploads/example.txt on the server and downloads/example.txt on the client are identical.
- uploads/ and downloads/ are auto-created; no manual setup needed.
- File transfers use GZIP compression + SHA-256 checksums for integrity.
- If you encounter “Bad gzip data” or “SHA256 mismatch,” ensure you’re using the same certificate on both sides and that no proxy is modifying packets.
- Change ports or file paths by supplying the corresponding flags (--port, --listen, --cert-file, --key-file) to echo.py.
This project is licensed under the MIT License. See the LICENSE file for details.