-
-
Notifications
You must be signed in to change notification settings - Fork 249
feat(net): carry path patterns in moq-lite AUTH_OK grants #4277
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d4820fc
3e7ec43
7ce9e24
5f94754
4554773
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -43,23 +43,21 @@ export class AuthMessage { | |
| } | ||
| } | ||
|
|
||
| // The wire carries prefixes, the ANNOUNCE_REQUEST encoding, so only a union of subtrees is | ||
| // representable. Anything else is refused rather than widened to its head. | ||
| async function encodePrefixes(w: Writer, patterns: Path.Patterns) { | ||
| const prefixes = patterns.toArray().map((pattern) => { | ||
| const prefix = pattern.asPrefix(); | ||
| if (prefix === undefined) throw new Unsupported(`grant not representable as prefixes: ${pattern}`); | ||
| return prefix; | ||
| }); | ||
| await w.u53(prefixes.length); | ||
| for (const prefix of prefixes) await w.string(prefix); | ||
| // Each pattern travels as its canonical text. | ||
| async function encodePatterns(w: Writer, patterns: Path.Patterns) { | ||
| await w.u53(patterns.size); | ||
| for (const pattern of patterns) await w.string(pattern.text); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a JavaScript issuer accepts a JSON pattern containing an unpaired UTF-16 surrogate, AGENTS.md reference: AGENTS.md:L17-L18 Useful? React with 馃憤聽/ 馃憥.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Disagree for this PR. (Written by Claude Opus 5.5) |
||
| } | ||
|
|
||
| async function decodePrefixes(r: Reader): Promise<Path.Patterns> { | ||
| async function decodePatterns(r: Reader): Promise<Path.Patterns> { | ||
| const count = await r.u53(); | ||
| const patterns = new Path.Patterns(); | ||
| for (let i = 0; i < count; i++) { | ||
| patterns.insert(Path.Pattern.subtree(await r.string())); | ||
| const text = await r.string(); | ||
| const pattern = Path.Pattern.parse(text); | ||
| // Only the canonical spelling is valid, so each pattern has one encoding. | ||
| if (pattern.text !== text) throw new Error(`non-canonical pattern: ${text}`); | ||
| patterns.insert(pattern); | ||
| } | ||
| return patterns; | ||
| } | ||
|
|
@@ -78,17 +76,17 @@ export class AuthOk { | |
| } | ||
|
|
||
| async #encode(w: Writer) { | ||
| await encodePrefixes(w, this.publish); | ||
| await encodePrefixes(w, this.subscribe); | ||
| await encodePatterns(w, this.publish); | ||
| await encodePatterns(w, this.subscribe); | ||
| // 0 means never, so a lapsed grant rounds up to the smallest real expiry. | ||
| const expires = | ||
| this.expires === undefined ? 0 : Math.min(Math.max(Math.ceil(this.expires), 1), Number.MAX_SAFE_INTEGER); | ||
| await w.u53(expires); | ||
| } | ||
|
|
||
| static async #decode(r: Reader): Promise<AuthOk> { | ||
| const publish = await decodePrefixes(r); | ||
| const subscribe = await decodePrefixes(r); | ||
| const publish = await decodePatterns(r); | ||
| const subscribe = await decodePatterns(r); | ||
| const expires = await r.u53(); | ||
| return new AuthOk(publish, subscribe, expires === 0 ? undefined : expires); | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When an acceptor sends an invalid or non-canonical pattern such as
/roomor*/**, Rust'sPresentTokenabsorbs the resulting decode error as a token termination, while JavaScript's auth loop catches it and likewise leaves the session open. The newly specifiedPROTOCOL_VIOLATIONexists only in the session error space, so both implementations need to propagate this decode failure into a session close rather than merely dropping the offending token.AGENTS.md reference: drafts/AGENTS.md:L1-L1
Useful? React with 馃憤聽/ 馃憥.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not changing this here. Every malformed AUTH reply already ends just that token and leaves the session up in both languages, including an out-of-range
Expires, which predates this PR. Closing the session on a malformed Auth Stream reply is a behavior change for the whole stream, not just patterns. It should be decided and tested on its own, so it is proposed as a follow-up quest.(Written by Claude Opus 5.5)