-
Notifications
You must be signed in to change notification settings - Fork 376
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
stream-management: Split bind2, sasl2 and stream features (#1063)
- Loading branch information
Showing
7 changed files
with
168 additions
and
141 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { NS, makeEnableElement } from "./index.js"; | ||
|
||
export function setupBind2({ bind2, sm, failed, enabled }) { | ||
bind2.use( | ||
NS, | ||
// https://xmpp.org/extensions/xep-0198.html#inline-examples | ||
(_element) => { | ||
return makeEnableElement({ sm }); | ||
}, | ||
async (element) => { | ||
if (element.is("enabled")) { | ||
enabled(element.attrs); | ||
} else if (element.is("failed")) { | ||
// const error = StreamError.fromElement(element) | ||
failed(); | ||
} | ||
}, | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { NS, makeResumeElement } from "./index.js"; | ||
|
||
export function setupSasl2({ sasl2, sm, failed, resumed }) { | ||
sasl2.use( | ||
NS, | ||
(element) => { | ||
if (!element.is("sm")) return; | ||
if (sm.id) return makeResumeElement({ sm }); | ||
}, | ||
(element) => { | ||
if (element.is("resumed")) { | ||
resumed(element); | ||
} else if (element.is(failed)) { | ||
// const error = StreamError.fromElement(element) | ||
failed(); | ||
} | ||
}, | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import XMPPError from "@xmpp/error"; | ||
import { procedure } from "@xmpp/events"; | ||
|
||
import { NS, makeEnableElement, makeResumeElement } from "./index.js"; | ||
|
||
export function setupStreamFeature({ | ||
streamFeatures, | ||
sm, | ||
entity, | ||
resumed, | ||
failed, | ||
enabled, | ||
}) { | ||
// https://xmpp.org/extensions/xep-0198.html#enable | ||
// For client-to-server connections, the client MUST NOT attempt to enable stream management until after it has completed Resource Binding unless it is resuming a previous session | ||
streamFeatures.use("sm", NS, async (context, next) => { | ||
// Resuming | ||
if (sm.id) { | ||
try { | ||
const element = await resume(entity, sm); | ||
await resumed(element); | ||
return; | ||
// If resumption fails, continue with session establishment | ||
} catch { | ||
failed(); | ||
} | ||
} | ||
|
||
// Enabling | ||
|
||
// Resource binding first | ||
await next(); | ||
|
||
const promiseEnable = enable(entity, sm); | ||
|
||
if (sm.outbound_q.length > 0) { | ||
throw new Error( | ||
"Stream Management assertion failure, queue should be empty after enable", | ||
); | ||
} | ||
|
||
// > The counter for an entity's own sent stanzas is set to zero and started after sending either <enable/> or <enabled/>. | ||
sm.outbound = 0; | ||
|
||
try { | ||
const response = await promiseEnable; | ||
enabled(response.attrs); | ||
} catch { | ||
sm.enabled = false; | ||
} | ||
|
||
sm.inbound = 0; | ||
}); | ||
} | ||
|
||
export function enable(entity, sm) { | ||
return procedure(entity, makeEnableElement({ sm }), (element, done) => { | ||
if (element.is("enabled", NS)) { | ||
return done(element); | ||
} else if (element.is("failed", NS)) { | ||
throw XMPPError.fromElement(element); | ||
} | ||
}); | ||
} | ||
|
||
export async function resume(entity, sm) { | ||
return procedure(entity, makeResumeElement({ sm }), (element, done) => { | ||
if (element.is("resumed", NS)) { | ||
return done(element); | ||
} else if (element.is("failed", NS)) { | ||
throw XMPPError.fromElement(element); | ||
} | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { mockClient } from "@xmpp/test"; | ||
|
||
import { tick } from "@xmpp/events"; | ||
|
||
test("emits ack when the server ackownledge stanzas", async () => { | ||
const { entity } = mockClient(); | ||
|
||
entity.streamManagement.enabled = true; | ||
|
||
expect(entity.streamManagement.outbound).toBe(0); | ||
expect(entity.streamManagement.outbound_q).toBeEmpty(); | ||
// expect(entity.streamManagement.enabled).toBe(true); | ||
|
||
await entity.send(<message id="a" />); | ||
|
||
expect(entity.streamManagement.outbound).toBe(0); | ||
expect(entity.streamManagement.outbound_q).toHaveLength(1); | ||
|
||
let acks = 0; | ||
entity.streamManagement.on("ack", (stanza) => { | ||
expect(stanza.attrs.id).toBe("a"); | ||
acks++; | ||
}); | ||
|
||
entity.mockInput(<a xmlns="urn:xmpp:sm:3" h="1" />); | ||
await tick(); | ||
|
||
expect(acks).toBe(1); | ||
expect(entity.streamManagement.outbound).toBe(1); | ||
expect(entity.streamManagement.outbound_q).toHaveLength(0); | ||
}); | ||
|
||
test("sends an <a/> element before closing", async () => { | ||
const { entity, streamManagement } = mockClient(); | ||
streamManagement.enabled = true; | ||
streamManagement.inbound = 42; | ||
entity.status = "online"; | ||
|
||
const promise_disconnect = entity.disconnect(); | ||
|
||
expect(await entity.catchOutgoing()).toEqual( | ||
<a xmlns="urn:xmpp:sm:3" h={streamManagement.inbound} />, | ||
); | ||
|
||
await promise_disconnect; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,6 +26,7 @@ modules_enabled = { | |
"sasl2_bind2"; | ||
"sasl2_sm"; | ||
"sasl2_fast"; | ||
"csi_simple"; | ||
}; | ||
|
||
modules_disabled = { | ||
|