# Enabling `wss://` for the WebSocket signaling server

The PHP/Ratchet signaling server (`ws-server.php`) listens on **plain `ws://` port 8081** with no TLS.
This terminates TLS for it at Apache (which already holds the `crivello.dyndns.org` certificate on :443)
and reverse-proxies an encrypted `wss://` URL down to the local plaintext listener.

After this is live and verified, flip the single client constant `AgentConfig.signalingURLString`
(in `Viewer/Eye/Eye/RTCVideoShare/AgentConfig.swift`) from `ws://crivello.dyndns.org:8081/` to
`wss://crivello.dyndns.org/ws` and remove the `crivello.dyndns.org` ATS exception from `Info.plist`
in the next app build. **Keep `ws://:8081` reachable** until all clients have updated.

## 1. Enable the proxy modules (once)

```bash
sudo a2enmod proxy proxy_http proxy_wstunnel rewrite
sudo systemctl restart apache2
```

## 2. Add the proxy to the :443 vhost

Edit the existing TLS vhost (e.g. `/etc/apache2/sites-available/your-ssl-site.conf`), inside the
`<VirtualHost *:443>` block that already serves `crivello.dyndns.org`:

```apache
    # WebSocket signaling: wss://crivello.dyndns.org/ws  ->  ws://127.0.0.1:8081/
    # (Upgrade/Connection negotiation handled by mod_proxy_wstunnel.)
    ProxyPreserveHost On
    ProxyRequests Off

    RewriteEngine On
    RewriteCond %{HTTP:Upgrade} =websocket [NC]
    RewriteRule ^/ws/?(.*)$ "ws://127.0.0.1:8081/$1" [P,L]

    ProxyPass        /ws  ws://127.0.0.1:8081/
    ProxyPassReverse /ws  ws://127.0.0.1:8081/
```

Then:

```bash
sudo apache2ctl configtest && sudo systemctl reload apache2
```

## 3. Keep the plaintext listener loopback-only (recommended)

So the only public path to signaling is the TLS-terminated `wss://`, bind the Ratchet server to
`127.0.0.1` (it currently binds all interfaces). In `ws-server.php` the `IoServer::factory(..., $port)`
call can be changed to `IoServer::factory(..., $port, '127.0.0.1')`. **Do this only AFTER all clients
use `wss://`**, since current apps connect directly to `ws://<host>:8081`. Until then leave it public.

## 4. Verify before flipping the client

```bash
# Expect HTTP/1.1 101 Switching Protocols
curl -i -N \
  -H "Connection: Upgrade" -H "Upgrade: websocket" \
  -H "Sec-WebSocket-Version: 13" -H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" \
  https://crivello.dyndns.org/ws
```

Or use a `wss://crivello.dyndns.org/ws` client (e.g. `websocat`) and send a `{"type":"hello",...}` frame.

## Rollout order
1. Apply steps 1–2, verify step 4 returns `101`.
2. Ship the app build with `signalingURLString = "wss://crivello.dyndns.org/ws"` and the ATS exception removed.
3. Once all clients are updated, apply step 3 (loopback bind) and drop the public `:8081` exposure.
