-
Notifications
You must be signed in to change notification settings - Fork 376
/
Copy pathstream-feature.js
74 lines (63 loc) · 1.91 KB
/
stream-feature.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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);
}
});
}