DEV Community

Cover image for Phone to PC without the cloud: a local HTTPS server, a pinned certificate and mDNS
Jassi Singh
Jassi Singh

Posted on AI-assisted

Phone to PC without the cloud: a local HTTPS server, a pinned certificate and mDNS

You take a photo on your phone and need it on your laptop, which is right there on the desk. On a Mac with an iPhone, AirDrop does it in two taps. On Windows, or with an Android phone, the photo goes up to someone's cloud, through a chat app or into an email to yourself, and back down again: two metres, by way of a data centre.

The phone and the computer are on the same Wi-Fi. They should be able to talk to each other directly, with no account and no server in between. That's the idea behind Dropple. It runs on Mac and Windows, and works with any phone. This post is about how it works, and about the parts that were harder than I expected.

The shape of it

The desktop app is built with Tauri 2, with a Rust backend. Inside it runs an axum server on the local network: plain HTTP on one port for first contact, and HTTPS (rustls) on another.

On the phone there are two ways in:

  • Any phone's browser. You scan a QR code and the computer serves the whole phone side as a web page. Nothing gets installed, and it works on an iPhone too.
  • A native Android app, which talks to the same API and stays connected in the background.

Files stream both ways. Text sent from the phone goes straight onto the computer's clipboard. Live updates go out to every connected phone as Server-Sent Events, which turned out much simpler than WebSockets for a list that only changes on one side at a time.

phone ──HTTPS──▶ axum (Rust, inside the Tauri app)
  ▲                    │
  └──── SSE /api/events ┘   "the list changed, fetch it"
Enter fullscreen mode Exit fullscreen mode

Trust without a certificate authority

HTTPS on a home network is awkward. There's no domain name, so no public certificate.

Dropple makes its own certificate authority on first run (with rcgen) and uses it to issue a certificate for the computer's current IP address. When the address changes, it issues a new one. The authority is name-constrained to private addresses and .local, so even if it were trusted somewhere, it couldn't vouch for a real website.

A browser would need that authority installed before it trusts the connection, which is a real hurdle on a phone. The Android app gets around it by pinning instead:

  1. The QR code carries the SHA-256 fingerprint of the computer's authority.
  2. The app's trust manager accepts a connection only if the server's chain contains a certificate with exactly that fingerprint, and the server's own certificate was signed by it.

Nothing goes into the phone's trust store, there's nothing for the user to install, and a lookalike server on the same Wi-Fi gets nowhere. I've written up the trust manager itself separately.

Finding the computer again

Laptops change IP addresses. They join a different network, the router hands out a new lease, or the laptop wakes up from sleep.

The computer announces itself over mDNS as _dropple._tcp, with the start of its fingerprint in a TXT record. When the saved address stops answering, the Android app searches with Android's NSD and reconnects to the computer whose fingerprint matches. Connecting still checks the full fingerprint, so the TXT record only narrows the search; it never grants trust.

One Samsung phone turned this into a bug hunt. Its NSD results contained only an IPv6 link-local address (fe80::…%wlan0), which you can't put into an https:// URL. The app sat on "Connecting…" forever. Details in the NSD post.

Staying connected on Android, politely

Receiving files in the background means a foreground service of type connectedDevice, with an ongoing notification. Two things made that bearable:

  • Explaining before asking. Before Android shows its notification prompt, a short sheet says what the notifications are for. More people say yes, and nobody is surprised.
  • An off switch for every annoying part. Users can hide the "Connected" notification's channel, or turn the background connection off entirely.

Android also won't let an app in the background read the clipboard, so "send what I just copied" needs a trick. A Quick Settings tile opens an invisible activity, which waits until it has window focus, reads the clipboard, sends it and closes. Write-up here.

What I'd tell someone building something similar

  • Pin, don't install. If you control both ends, pin the certificate rather than asking users to trust a new authority.
  • Test discovery on more than one brand of phone. NSD results differ between them.
  • Make reconnecting visible. A spinner with no words looks like a hang; "Looking for your computer…" doesn't. Users forgive waiting when they can see what's being waited for.
  • Keep the last state. If the computer is out of reach, show the last list you had rather than an empty screen.

Sharing in Dropple is free, on Mac, Windows, any phone's browser, and Android through Google Play: https://scannertechs.com/apps/dropple/

Happy to answer questions about any of this in the comments.

Top comments (0)