Ein lokales "WebDrop" für dein Netzwerk: jeder Rechner findet andere Rechner im selben Netzwerk automatisch und kann Dateien sowie Zwischenablage-Inhalte teilen.
Kein Sicherheits-/Verschlüsselungsmechanismus - bewusst, siehe Anforderungen. Nur für vertrauenswürdige, isolierte lokale Netzwerke gedacht.
Es gibt zwei Betriebsmodi, je nach Zielplattform:
Linux (nativer Docker-Host): docker compose up --build -d mit
network_mode: host funktioniert hier wie gedacht - der Container nutzt
direkt die echte Netzwerkschnittstelle des Rechners, UDP-Broadcast erreicht
das reale LAN.
Windows und Mac (Docker Desktop): Docker Desktop läuft intern in einer
VM mit eigenem virtuellem Netzwerk (auch bei network_mode: host).
UDP-Broadcast käme dort nie aus der VM heraus ins echte LAN, und selbst die
Web-UI wäre vom eigentlichen Host aus nicht ohne Port-Mapping erreichbar.
Auf Windows/Mac deshalb die native Binary direkt ausführen, kein Docker.
Die Binary ist eine einzelne, portable Datei (Frontend ist eingebettet) - kein Installer, keine Laufzeitumgebung nötig.
Ohne lokal installiertes Go (nutzt Docker als Build-Umgebung):
./scripts/build-all-in-docker.shMit lokal installiertem Go:
./scripts/build-all.shBeides erzeugt in ./dist/:
webdrop-linux-amd64/webdrop-linux-arm64webdrop-windows-amd64.exewebdrop-darwin-amd64(Mac Intel) /webdrop-darwin-arm64(Mac Apple Silicon)
Cross-Compiling funktioniert ohne Fallstricke, weil der komplette Code reines
Go mit Standardbibliothek ist (CGO_ENABLED=0) - keine plattformspezifischen
Abhängigkeiten.
Native Binary (Windows/Mac, empfohlen):
./webdrop-darwin-arm64 # bzw. die passende Datei für die PlattformDanach http://localhost:8080 im Browser öffnen. Persistente Daten (Node-ID,
Trust-Liste) landen automatisch in einem plattformüblichen Verzeichnis
(%AppData%\webdrop unter Windows, ~/Library/Application Support/webdrop
unter Mac, ~/.config/webdrop unter Linux).
Erste Startschwierigkeiten, die keine Bugs sind, sondern normales Betriebssystem-Verhalten:
- Windows Firewall fragt beim ersten Start, ob die App im Netzwerk kommunizieren darf - "Zulassen" bestätigen (private Netzwerke reichen).
- macOS Gatekeeper blockiert unsignierte Binaries beim Doppelklick - einmalig per Rechtsklick → Öffnen bestätigen.
Docker (nur für native Linux-Hosts):
docker compose up --build -d| Variable | Standard | Bedeutung |
|---|---|---|
HTTP_PORT |
8080 |
Port der Web-UI / API |
DISCOVERY_PORT |
41234 |
UDP-Port für Broadcast-Discovery |
BROADCAST_ADDR |
leer (= automatische Multi-Interface-Erkennung) | fester Override, z.B. 255.255.255.255:41234, falls Auto-Erkennung nicht passt |
ADVERTISE_ADDR |
leer (= pro Peer automatisch ermittelt) | fester Override, falls Auto-Erkennung nicht passt (z.B. Port-Weiterleitung/NAT) |
PEER_TIMEOUT |
6s |
Peer gilt nach dieser Zeit ohne Lebenszeichen als offline |
TRANSFER_TTL |
30m |
wie lange ein Datei-Angebot gültig bleibt |
DATA_DIR |
plattformabhängig (s.o.) | persistente Daten (ID, Trust-Liste, Uploads) |
WEB_DIR |
leer (= eingebettetes Frontend) | Override für lokale Frontend-Entwicklung ohne Neu-Kompilieren |
cmd/webdrop/main.go Verdrahtet alles, liest Konfiguration aus ENV
internal/id Persistente Node-Identität (UUID + Name)
internal/peers Peer-Registry mit Timeout-/Prune-Logik
internal/discovery UDP-Broadcast Announce/Listen
internal/trust Persistente Trust-Liste pro Peer
internal/transfer Download-Token-Verwaltung für Dateien
internal/api HTTP-API + Server-Sent-Events (SSE) für Live-Updates
internal/webui Eingebettetes Frontend (go:embed)
scripts/ Cross-Compile-Skripte für alle Zielplattformen
Jedes Package ist unabhängig testbar und über klar definierte Schnittstellen
verbunden - gedacht, um später einzelne Teile auszutauschen oder zu erweitern
(z.B. Verschlüsselung in internal/transfer, eine andere Discovery-Methode
in internal/discovery, Auth-Handling in internal/api), ohne den Rest
anfassen zu müssen.
- UDP-Broadcast statt mDNS/Bonjour: volle Kontrolle über Timing. Das Broadcast-Intervall (Standard 1,5s) und der Peer-Timeout (Standard 6s) sorgen dafür, dass ein Peer nach einem Netzwerk-Aussetzer innerhalb weniger Sekunden verschwindet bzw. wieder auftaucht - nicht nach Stunden.
- Broadcast an spezifische Subnetz-Adressen statt an die globale
255.255.255.255: Senden an die globale Broadcast-Adresse überlässt dem Betriebssystem, über welches Interface das Paket geht. Sobald mehrere Netzwerk-Interfaces gleichzeitig aktiv sind (Docker Desktop, VirtualBox, Hyper-V, WSL und VPN-Clients legen alle automatisch eigene virtuelle Adapter an), kann diese Wahl auf ein isoliertes virtuelles Netz fallen - das Senden meldet trotzdem Erfolg, das Paket erreicht aber nie andere Rechner im echten LAN. WebDrop ermittelt deshalb bei jedem Announce alle aktiven, "broadcast-fähigen" Interfaces (internal/discovery/interfaces.go) und sendet gezielt an die Subnetz-Broadcast-Adresse jedes einzelnen (z.B.192.168.0.255statt255.255.255.255) - jedes Subnetz hat dadurch eine eindeutige Route. ÜberBROADCAST_ADDRlässt sich das bei Bedarf weiterhin auf eine feste Adresse überschreiben. - Frontend per
go:embed: eine einzelne portable Binary statt Binary + Ordner + Pfad-Konfiguration - wichtig für native Ausführung auf Windows/Mac ohne Docker. - Adress-Ermittlung pro Ziel-Peer statt einer global geratenen Adresse:
Beim Datei-Versand wird die eigene, für den jeweiligen Empfänger korrekte
lokale Adresse erst im Moment des Kontakts ermittelt
(
internal/netutil.LocalAddrFor), nicht einmalig beim Start global geraten. Eine global geratene Adresse kann auf Rechnern mit mehreren aktiven Interfaces (Docker/VirtualBox/Hyper-V/WSL/VPN) für einen bestimmten Peer schlicht falsch sein - anders als beim Broadcast (siehe oben) ist das Routing zu einem konkreten, bekannten Ziel-Host aber nicht mehrdeutig, der Kernel kennt die richtige Antwort in diesem Moment immer. - Downloads per normalem HTTP-GET: kein eigenes Übertragungsprotokoll -
der sendende Knoten bietet die Datei unter einer Download-URL an, der
Zielknoten lädt sie ganz gewöhnlich herunter (inkl. Keep-Alive,
Range-Requests durch
http.ServeContent). - Server-Sent Events statt WebSocket: wir brauchen nur eine Push-Richtung (Server → Browser für Peer-Updates und eingehende Transfers). SSE braucht dafür keine externe Abhängigkeit und reconnected im Browser automatisch von selbst.
- Clipboard-Autoschreiben: Browser erlauben
navigator.clipboard.writenur zuverlässig ohne Nutzergeste, wenn der Tab fokussiert ist. Bei vertrauten Peers UND fokussiertem Tab wird automatisch geschrieben, sonst erscheint ein Hinweis mit "Übernehmen"-Button.
go test ./...~36 Unit-/Integrationstests decken die Kernlogik ab: Peer-Timeout-Verhalten, ID-/Trust-Persistenz über Neustarts, Discovery-Paket-Handling (inkl. Ende-zu-Ende-Test zwischen zwei simulierten Knoten), Transfer-Token-Handling, das eingebettete Frontend, und alle HTTP-Handler (inkl. Trust-gesteuertes Auto-Accept-Verhalten, mit echtem Mock-Peer-Server statt echtem Netzwerk).
- Keine Verschlüsselung, keine Authentifizierung (bewusst, siehe oben)
- Automatisches Clipboard-Schreiben funktioniert nur bei fokussiertem Browser-Tab (Browser-Beschränkung, keine App-Entscheidung)
- Docker Desktop (Windows/Mac) eignet sich nicht als Laufzeitumgebung für dieses Projekt - dort die native Binary nutzen (siehe oben)
- Für spätere Erweiterung vorgesehen: Protokollversion im
Discovery-Announcement (
discovery.ProtocolVersion), damit sich das Format später abwärtskompatibel weiterentwickeln lässt