Skip to content

Code-quality review: correctness fixes, ErrRequestOverloaded, removeElementsLocked, file split#80

Merged
linkdata merged 2 commits into
mainfrom
code-quality-review
Jun 18, 2026
Merged

Code-quality review: correctness fixes, ErrRequestOverloaded, removeElementsLocked, file split#80
linkdata merged 2 commits into
mainfrom
code-quality-review

Conversation

@linkdata

Copy link
Copy Markdown
Owner

Code changes from a quality review of the core jaws package. Documentation-only
improvements are split into a separate stacked PR (code-quality-review-docs,
based on this branch) so this PR stays focused on behavior and structure.

The review found no high/critical issues; these are the low-severity items worth
fixing, each with a test, plus one mechanical refactor.

Fixes (commit 1)

  • handleBroadcast string-id framing: reject an HTML-id broadcast target containing
    a tab or newline before it is written verbatim into a wire frame (Jid<0), where it
    would corrupt framing. Satisfies wire.WsMsg.Append's documented no-tab/newline
    precondition; rejects (not escapes) since a valid HTML id has no ASCII whitespace.
  • /jaws/.tail/ client binding: bind the one-shot tail drain to the client IP
    with the same loopback-aware equalIP check the WebSocket claim path uses, so a
    leaked key cannot drain (and thereby deny) another client's tail.
  • ErrRequestOverloaded: new exported sentinel; the broadcast- and event-channel
    backpressure cancellation causes now wrap it, so callers can classify the teardown
    via context.Cause + errors.Is instead of string-matching.
  • removeElementsLocked: extract the byte-for-byte duplicated tagMap-cleanup loop
    shared by handleRemove and deleteElementLocked.
  • GenerateHeadHTML: deduplicate extra resources against the built-in CSS path as
    well as the JS path (previously only the JS path was guarded).
  • Regression test that errors.Is(err, ErrEventHandlerPanic) stays panic-safe when a
    handler panics with a non-comparable value.

Refactor (commit 2)

  • Pure code-motion: move the Jaws-side session helpers + session middleware into
    session.go, and the broadcast/dirt/redirect/alert + SetInner..JsCall helpers into
    a new broadcast.go. jaws.go shrinks 1395 → 936 lines. No behavior change.

Verification

go build, go vet, staticcheck, golangci-lint all clean; go test -race . and
go test -tags debug -race . both pass.

Note: one reviewed finding (a theoretical errors.Is panic via the custom Is
methods) was investigated and not changed — the panic is unreachable through the
public API (unexported sentinel types; the exported sentinels carry nil interface
fields) and the proposed fix would not address the actual stdlib comparison site. A
regression test documents the reachable safe behavior instead.

linkdata added 2 commits June 18, 2026 07:21
Behavioral and structural fixes from the core-package quality review; each
comes with a test. No public API removals.

- handleBroadcast: reject an HTML-id broadcast target containing a tab or
  newline before it is written verbatim into a wire frame (Jid<0), where it
  would corrupt framing. A valid HTML id never contains ASCII whitespace, so
  reject via reportMisuse rather than escape, satisfying wire.WsMsg.Append's
  documented no-tab/newline precondition.
- /jaws/.tail/<key>: bind the one-shot tail drain to the client IP with the
  same loopback-aware equalIP check the WebSocket claim path uses, so a leaked
  key cannot drain (and thereby deny) another client's tail. A mismatch is
  treated as not found.
- Add the exported ErrRequestOverloaded sentinel and wrap the broadcast- and
  event-channel backpressure cancellation causes with it, so callers can match
  the teardown reason via context.Cause + errors.Is instead of string-matching.
- Extract removeElementsLocked, shared by handleRemove and deleteElementLocked,
  removing a byte-for-byte duplicated tagMap-cleanup loop.
- GenerateHeadHTML: deduplicate extra resources against the built-in CSS path
  as well as the JS path, so re-listing a built-in is a no-op for both.
- Add a regression test that errors.Is(err, ErrEventHandlerPanic) stays
  panic-safe when the handler panicked with a non-comparable value.
Pure code-motion, no behavior change: build, go vet, staticcheck,
golangci-lint and the full -race / -tags debug -race suites are unchanged.

- Move the Jaws-side session helpers (SessionCount, Sessions, getSessionLocked,
  getCookieSessionsIDs, GetSession, NewSession, newSession, deleteSession) and
  the session middleware (sessioner, Jaws.Session) into session.go, which
  already owns the Session methods.
- Move the broadcast/dirt/redirect/alert machinery and the SetInner..JsCall
  convenience wrappers into a new broadcast.go.

jaws.go shrinks from 1395 to 936 lines and now holds the instance lifecycle,
request pool, Serve loop, client-IP helpers and HTTP routing.
@linkdata linkdata merged commit 9ef8c00 into main Jun 18, 2026
6 checks passed
@linkdata linkdata deleted the code-quality-review branch June 18, 2026 05:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant