refactor(handler/sni): extract helpers, add SnifferBuilder, comprehensive tests

- Extract newRecorderObject, checkRateLimit, sniffingDial, and
  handleSniffedProtocol from the Handle method into dedicated files
  (sniffing.go, util.go) to reduce Handle from ~100 to ~65 lines.
- Introduce SnifferBuilder: populated once during Init, reused via
  Build() per connection. Avoids reconstructing a 9-field sniffing.Sniffer
  literal on every inbound connection.
- Hoist router nil check from the lazy dial closure into Handle so
  misconfigured handlers fail immediately instead of silently dropping
  unrecognised traffic with no error.
- Add nil-addr guard in checkRateLimit (missing from the old inline
  version — would panic if the remote address were somehow nil).
- Add comprehensive unit tests (44 tests across 5 test files) covering
  handler creation, Init, metadata parsing (defaults, custom, MITM,
  error paths), protocol dispatch (HTTP, TLS, unknown, empty), rate
  limiting, recorder objects, dial plumbing, and SnifferBuilder.
- Add package-level godoc explaining the handler scope, limitations
  vs tcp/forward, and the connection processing flow.
- Fix metadata comment: s/SnifferBuilder/sniffing.Sniffer/.
This commit is contained in:
ginuerzh
2026-06-25 14:51:13 +08:00
parent 8fd5200bf1
commit b01f5d065f
9 changed files with 1329 additions and 90 deletions
+1 -1
View File
@@ -16,7 +16,7 @@ type metadata struct {
// readTimeout controls two behaviors:
// 1. A read deadline set on the client connection before sniffing the
// TLS ClientHello / HTTP request (see handler.go Handle).
// 2. Passed to SnifferBuilder as the timeout for reading upstream
// 2. Passed to [sniffing.Sniffer] as the timeout for reading upstream
// response headers during HTTP/TLS sniffing.
// 0 or negative defaults to 15s.
readTimeout time.Duration