fix(serve): bind before showing addresses and opening the browser
`trunk serve --open` prints the listening URLs and opens the browser even when the server cannot bind. With the port already taken it opens a tab, then logs `Address already in use`.
`axum_server::bind*()` binds lazily inside `.serve()`, so the failure only surfaces once the spawned task is polled, long after `run()` has called `open::that`.
This binds a `std::net::TcpListener` per address in `spawn_server` before `show_listening`, and passes the listeners to `run_server`, which now uses `from_tcp` / `from_tcp_rustls` instead of `bind` / `bind_rustls`. A bind error propagates out of `spawn_server`, so the existing `?` in `run()` already prevents the browser from opening; no new condition was needed there.
axum-server 0.8 has no `from_tcp_openssl`, so the native-tls path builds the equivalent from `from_tcp` plus `OpenSSLAcceptor`, the same way `from_tcp_rustls` does internally. All three paths bind eagerly; none is left on the lazy path.
Binding up front would make a single unavailable address fatal, which would be a regression: the address list is auto-populated with every loopback interface when none is configured, so a default `trunk serve` would fail on a host where one loopback family is occupied. So a failed bind warns and the server carries on with the rest, erroring only if nothing binds at all. `show_listening` now receives the addresses actually bound, taken from `local_addr()`, which also makes `--port 0` print the resolved port instead of `0`.
Fixes #946
## Verification
- `cargo build`, `cargo clippy --all-targets --all-features -- -D warnings`, `cargo fmt --check` all pass
- Feature paths compile: default (rustls), `--no-default-features`, `rustls-aws-lc`, and `native-tls,vendored`
- Only address occupied: warns, then `failed to bind to any of the requested addresses`, prints no URLs, opens no browser
- `[::1]` occupied and `127.0.0.1` free: warns about `[::1]`, prints only the `127.0.0.1` URL, keeps serving (`curl` returns 200)
- `--port 0`: prints the resolved ephemeral port
#988 took the same approach and stalled on the belief that native-tls had no listener-based constructor. That is correct for `from_tcp_openssl`, but the acceptor can be attached to `from_tcp` directly, which closes that gap.
合并状态:未合并 1 条评论