A lightweight private file sharing stack: a Flask server plus a single-file C++ CLI client (think minimal Google Drive over the terminal).
Built for personal use over a Cloudflare Tunnel or a direct IP, with large file uploads in chunks, per-file ownership, and simple authenticated downloads.
- Features
- Architecture
- Requirements
- Quick Start
- Usage
- Storage Layout
- Deployment Notes
- Prebuilt Binaries
- Roadmap
- Contributing
- License
- Private file exchange between users or machines
- Chunked uploads for large files with resumability potential
- Per-file ownership tracked in metadata
- Simple CLI for create, login, upload, list, and download
- Works well behind a Cloudflare Tunnel, which improves reachability
[ netserve (CLI) ] <----libcurl----> [ Flask HTTP server ]
| |
| uploads/ (on disk)
| ├─ incomplete/ (temp chunks)
| ├─ complete/ (assembled files)
| ├─ metadata.json (file metadata + ownership)
| └─ users.json (user credential hashes)
Components
server.py- Flask HTTP server that exposes all operationsnetserve.cpp- single-file C++ CLI client that uses libcurl
Server
- Python 3.8 or newer
- Flask
Client
- g++ or clang++
libcurldevelopment headers
# Ubuntu or Debian
sudo apt update
sudo apt install -y python3 python3-pip
pip3 install flask
# run the server
python3 server.py
# The server listens on http://0.0.0.0:5000 by default
# Open in your browser if desired
$BROWSER http://localhost:5000# Ubuntu or Debian
sudo apt install -y g++ libcurl4-openssl-dev build-essential
g++ netserve.cpp -o netserveThe client expects the server at
http://localhost:5000unless you specify a different URL with a flag such as--server URLor an environment variable. If your build uses a different mechanism, set the server location accordingly when you run commands.
Create a user
./netserve create <username> <password>Log in
./netserve login <username> <password>Upload a file (client splits into chunks automatically)
./netserve upload /path/to/file [username password]List files
./netserve list [username password]Download a file (saves to your Downloads directory by default)
./netserve download <filename> [username password]Notes
- After you run
netserve login <username> <password>, the client persists your session locally. You do not need to log in again unless you clear the session. - The server enforces a maximum chunk size defined by
CHUNK_SIZEinserver.pywith a default near 90 MB.
On the server host:
uploads/
├─ incomplete/ # temporary chunk folders per in-progress upload
├─ complete/ # assembled files available for download
├─ metadata.json # per-file metadata including ownership
└─ users.json # stored user credential hashes
Make sure the server process user can read and write the uploads/ directory.
Netserve is suitable for exposure through a Cloudflare Tunnel, which gives you:
- Stable public hostname that forwards to your local server port
- TLS termination by Cloudflare
- Lower friction for NAT and firewall traversal
Typical steps at a high level
- Install
cloudflaredon the server host - Authenticate
cloudflaredwith your Cloudflare account - Create a tunnel that targets
http://localhost:5000 - Map a DNS record in Cloudflare to the tunnel hostname
- Point your client to
https://your-tunnel-hostname
- Prefer HTTPS termination at the edge or a reverse proxy. If you use Cloudflare Tunnel, the edge provides TLS.
- Use strong, unique passwords. Consider rate limiting and request size limits at the proxy.
- Back up
uploads/complete,metadata.json, andusers.jsonregularly to preserve data durability and provenance. - Treat
users.jsonas sensitive. It contains password hashes, not plaintext.
If the repository contains prebuilt artifacts, availability is as follows.
| Platform | x86 | x86_64 | ARM32 | ARM64 |
|---|---|---|---|---|
| Linux | present | present | ||
| Windows | ||||
| MacOS |
If your platform is not listed, compile from source using the steps above.
Clients
- Public API surface for programmatic automation
- Additional client apps that can talk to the same server
Server
- More granular operator controls for quotas, retention, and policy
- Operational metrics for throughput, latency, and storage utilization
- Server logic lives in
server.py - CLI client lives in
netserve.cpp
Please open an issue or pull request with a clear description, expected behavior, and steps to reproduce any defects. For features, describe the user journey and any configuration changes.
Copyright (c) 2025 Seth Jones
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.