Skip to content

fix: serialize AutoSession creation with Session.Close - #260

Merged
linkdata merged 3 commits into
mainfrom
fix/249-autosession-close-race
Aug 7, 2026
Merged

fix: serialize AutoSession creation with Session.Close#260
linkdata merged 3 commits into
mainfrom
fix/249-autosession-close-race

Conversation

@linkdata

@linkdata linkdata commented Aug 7, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes #249.

  • Creates and associates an AutoSession with its initiating Request before publishing it in the session registry.
  • Commits a session cookie only while the exact Session remains registered and live, after calling the reentrant ResponseWriter.Header outside all core locks.
  • Shares that cookie commit with NewSession and SessionMiddleware so manual creation cannot emit a stale live cookie after a close winner.
  • Documents association, nil handling, concurrent-close behavior, and replacement-random-reader panic behavior.

Concurrency model

AutoSession creation follows the established Jaws -> Request -> Session lock order. Both sides of the Request/Session association are established before registry insertion, so Sessions never exposes a half-associated AutoSession.

Cookie publication calls ResponseWriter.Header with no internal lock held, then holds Jaws and Session read locks through the concrete response/request header mutations. If cookie publication wins, a later Close sees and detaches the associated Request and queues one reload. If Close wins, no live response or request cookie is installed.

Creation remains in the 101 Switching Protocols hook, preserving the accepted-handshake-only behavior from #139.

Tests

  • TestWS_AutoSessionCloseAtPublication uses a real WebSocket and an unwrap-capable, reentrant ResponseWriter to close the Session at publication. It verifies detachment, empty Session membership, registry removal, no live cookie, and exactly one pre-subscription reload.
  • TestSessionMiddleware_CloseDuringResponseHeader covers the same cookie winner semantics for middleware-created Sessions.
  • TestSession_AddCookieRejectsUnavailableSession independently pins the exact-registry and liveness guards.
  • Nil request/writer tests preserve the documented NewSession behavior, and an injected-reader regression proves session allocation releases the Jaws lock on panic.
  • Existing successful, existing-session, rejected-origin, and malformed-handshake AutoSession tests remain green.

Verification

  • go generate ./...
  • gofmt -l .
  • go vet ./...
  • staticcheck ./...
  • golangci-lint run
  • gosec ./...
  • JAWS_REQUIRE_NODE=1 go test -race ./...
  • JAWS_REQUIRE_NODE=1 go test ./...
  • go build ./...

Associate an AutoSession with its Request before publishing it, and commit session cookies only while the exact Session remains registered and live. Share the cookie commit with manual and middleware-created Sessions so reentrant response writers cannot emit stale live cookies.

Add deterministic WebSocket and middleware regressions for close-during-publication behavior.
Exercise the deadline half of the live-session cookie guard and document why it is distinct from Close serialization.

Apply the related review cleanups and remove obsolete recoverable CSPRNG failure claims.
Restore the scoped deferred unlock around session allocation so an error from a replacement random reader cannot wedge Jaws.

Pin the nil-request contract and both halves of the live-session publication guard.
@linkdata
linkdata merged commit ceffec6 into main Aug 7, 2026
7 checks passed
@linkdata
linkdata deleted the fix/249-autosession-close-race branch August 7, 2026 20:07
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.

AutoSession can attach a Session after concurrent Session.Close returns

1 participant