@norskvideo/moq-net 0.1.8 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/announce.d.ts +7 -0
- package/announce.d.ts.map +1 -0
- package/announce.js +8 -0
- package/announce.js.map +1 -0
- package/announced.d.ts +49 -91
- package/announced.d.ts.map +1 -1
- package/announced.js +21 -156
- package/announced.js.map +1 -1
- package/bandwidth.d.ts +163 -0
- package/bandwidth.d.ts.map +1 -0
- package/bandwidth.js +304 -0
- package/bandwidth.js.map +1 -0
- package/bandwidth_api.d.ts +7 -0
- package/bandwidth_api.d.ts.map +1 -0
- package/bandwidth_api.js +8 -0
- package/bandwidth_api.js.map +1 -0
- package/broadcast.d.ts +44 -35
- package/broadcast.d.ts.map +1 -1
- package/broadcast.js +104 -60
- package/broadcast.js.map +1 -1
- package/connection/accept.d.ts +16 -1
- package/connection/accept.d.ts.map +1 -1
- package/connection/accept.js +52 -28
- package/connection/accept.js.map +1 -1
- package/connection/browser.d.ts.map +1 -1
- package/connection/browser.js +9 -7
- package/connection/browser.js.map +1 -1
- package/connection/connect.d.ts +30 -6
- package/connection/connect.d.ts.map +1 -1
- package/connection/connect.js +110 -54
- package/connection/connect.js.map +1 -1
- package/connection/established.d.ts +17 -21
- package/connection/established.d.ts.map +1 -1
- package/connection/established.js.map +1 -1
- package/connection/forward.d.ts +2 -0
- package/connection/forward.d.ts.map +1 -0
- package/connection/forward.js +173 -0
- package/connection/forward.js.map +1 -0
- package/connection/handshake.d.ts +1 -0
- package/connection/handshake.d.ts.map +1 -1
- package/connection/handshake.js +5 -2
- package/connection/handshake.js.map +1 -1
- package/connection/index.d.ts +5 -5
- package/connection/index.d.ts.map +1 -1
- package/connection/index.js +4 -5
- package/connection/index.js.map +1 -1
- package/connection/pool.d.ts +186 -0
- package/connection/pool.d.ts.map +1 -0
- package/connection/pool.js +361 -0
- package/connection/pool.js.map +1 -0
- package/connection/reload.d.ts +14 -93
- package/connection/reload.d.ts.map +1 -1
- package/connection/reload.js +217 -81
- package/connection/reload.js.map +1 -1
- package/connection/stats.d.ts +3 -26
- package/connection/stats.d.ts.map +1 -1
- package/connection/stats.js.map +1 -1
- package/connection/transport.d.ts +0 -7
- package/connection/transport.d.ts.map +1 -1
- package/consume.d.ts +1 -43
- package/consume.d.ts.map +1 -1
- package/consume.js +1 -1
- package/consume.js.map +1 -1
- package/error.d.ts +180 -29
- package/error.d.ts.map +1 -1
- package/error.js +331 -16
- package/error.js.map +1 -1
- package/errors.d.ts +7 -0
- package/errors.d.ts.map +1 -0
- package/errors.js +8 -0
- package/errors.js.map +1 -0
- package/group.d.ts +9 -43
- package/group.d.ts.map +1 -1
- package/group.js +284 -69
- package/group.js.map +1 -1
- package/hop.d.ts +115 -0
- package/hop.d.ts.map +1 -0
- package/hop.js +119 -0
- package/hop.js.map +1 -0
- package/ietf/adapter.d.ts +5 -1
- package/ietf/adapter.d.ts.map +1 -1
- package/ietf/adapter.js +105 -60
- package/ietf/adapter.js.map +1 -1
- package/ietf/aliases.d.ts +1 -78
- package/ietf/aliases.d.ts.map +1 -1
- package/ietf/cluster.d.ts +9 -123
- package/ietf/cluster.d.ts.map +1 -1
- package/ietf/cluster.js +84 -44
- package/ietf/cluster.js.map +1 -1
- package/ietf/connection.d.ts +6 -72
- package/ietf/connection.d.ts.map +1 -1
- package/ietf/connection.js +62 -56
- package/ietf/connection.js.map +1 -1
- package/ietf/error.d.ts +11 -0
- package/ietf/error.d.ts.map +1 -0
- package/ietf/error.js +193 -0
- package/ietf/error.js.map +1 -0
- package/ietf/fetch.d.ts +7 -20
- package/ietf/fetch.d.ts.map +1 -1
- package/ietf/fetch.js +52 -22
- package/ietf/fetch.js.map +1 -1
- package/ietf/filter.d.ts +2 -0
- package/ietf/filter.d.ts.map +1 -1
- package/ietf/filter.js +10 -1
- package/ietf/filter.js.map +1 -1
- package/ietf/goaway.d.ts.map +1 -1
- package/ietf/goaway.js +22 -5
- package/ietf/goaway.js.map +1 -1
- package/ietf/hidden.d.ts +2 -0
- package/ietf/hidden.d.ts.map +1 -0
- package/ietf/hidden.js +30 -0
- package/ietf/hidden.js.map +1 -0
- package/ietf/index.d.ts +2 -0
- package/ietf/index.d.ts.map +1 -1
- package/ietf/index.js +2 -0
- package/ietf/index.js.map +1 -1
- package/ietf/object.d.ts +15 -8
- package/ietf/object.d.ts.map +1 -1
- package/ietf/object.js +51 -36
- package/ietf/object.js.map +1 -1
- package/ietf/parameters.d.ts +14 -2
- package/ietf/parameters.d.ts.map +1 -1
- package/ietf/parameters.js +97 -29
- package/ietf/parameters.js.map +1 -1
- package/ietf/properties.d.ts +1 -0
- package/ietf/properties.d.ts.map +1 -1
- package/ietf/properties.js +14 -0
- package/ietf/properties.js.map +1 -1
- package/ietf/publish.d.ts +19 -2
- package/ietf/publish.d.ts.map +1 -1
- package/ietf/publish.js +40 -6
- package/ietf/publish.js.map +1 -1
- package/ietf/publish_namespace.d.ts +25 -0
- package/ietf/publish_namespace.d.ts.map +1 -1
- package/ietf/publish_namespace.js +63 -0
- package/ietf/publish_namespace.js.map +1 -1
- package/ietf/publisher.d.ts +1 -82
- package/ietf/publisher.d.ts.map +1 -1
- package/ietf/publisher.js +483 -235
- package/ietf/publisher.js.map +1 -1
- package/ietf/solicit.d.ts +1 -40
- package/ietf/solicit.d.ts.map +1 -1
- package/ietf/subscribe.d.ts +8 -6
- package/ietf/subscribe.d.ts.map +1 -1
- package/ietf/subscribe.js +33 -27
- package/ietf/subscribe.js.map +1 -1
- package/ietf/subscribe_namespace.d.ts +8 -2
- package/ietf/subscribe_namespace.d.ts.map +1 -1
- package/ietf/subscribe_namespace.js +18 -8
- package/ietf/subscribe_namespace.js.map +1 -1
- package/ietf/subscriber.d.ts +1 -65
- package/ietf/subscriber.d.ts.map +1 -1
- package/ietf/subscriber.js +337 -123
- package/ietf/subscriber.js.map +1 -1
- package/ietf/token.d.ts +2 -0
- package/ietf/token.d.ts.map +1 -0
- package/ietf/token.js +99 -0
- package/ietf/token.js.map +1 -0
- package/ietf/track.d.ts +4 -0
- package/ietf/track.d.ts.map +1 -1
- package/ietf/track.js +6 -20
- package/ietf/track.js.map +1 -1
- package/ietf/version.d.ts +12 -1
- package/ietf/version.d.ts.map +1 -1
- package/ietf/version.js +13 -0
- package/ietf/version.js.map +1 -1
- package/index.d.ts +12 -7
- package/index.d.ts.map +1 -1
- package/index.js +10 -5
- package/index.js.map +1 -1
- package/internal.d.ts +115 -1
- package/internal.d.ts.map +1 -1
- package/internal.js +108 -0
- package/internal.js.map +1 -1
- package/lite/announce.d.ts +60 -10
- package/lite/announce.d.ts.map +1 -1
- package/lite/announce.js +176 -31
- package/lite/announce.js.map +1 -1
- package/lite/connection.d.ts +9 -59
- package/lite/connection.d.ts.map +1 -1
- package/lite/connection.js +34 -35
- package/lite/connection.js.map +1 -1
- package/lite/datagram.d.ts +3 -2
- package/lite/datagram.d.ts.map +1 -1
- package/lite/datagram.js +7 -8
- package/lite/datagram.js.map +1 -1
- package/lite/fetch.d.ts +15 -1
- package/lite/fetch.d.ts.map +1 -1
- package/lite/fetch.js +39 -7
- package/lite/fetch.js.map +1 -1
- package/lite/goaway.d.ts.map +1 -1
- package/lite/goaway.js +7 -1
- package/lite/goaway.js.map +1 -1
- package/lite/group.d.ts +30 -12
- package/lite/group.d.ts.map +1 -1
- package/lite/group.js +68 -26
- package/lite/group.js.map +1 -1
- package/lite/message.d.ts +2 -2
- package/lite/message.d.ts.map +1 -1
- package/lite/message.js +14 -5
- package/lite/message.js.map +1 -1
- package/lite/priority.d.ts +1 -61
- package/lite/priority.d.ts.map +1 -1
- package/lite/priority.js +4 -5
- package/lite/priority.js.map +1 -1
- package/lite/publisher.d.ts +1 -69
- package/lite/publisher.d.ts.map +1 -1
- package/lite/publisher.js +630 -262
- package/lite/publisher.js.map +1 -1
- package/lite/setup.d.ts +8 -8
- package/lite/setup.d.ts.map +1 -1
- package/lite/setup.js +33 -30
- package/lite/setup.js.map +1 -1
- package/lite/subscribe.d.ts +71 -17
- package/lite/subscribe.d.ts.map +1 -1
- package/lite/subscribe.js +205 -53
- package/lite/subscribe.js.map +1 -1
- package/lite/subscriber.d.ts +15 -56
- package/lite/subscriber.d.ts.map +1 -1
- package/lite/subscriber.js +451 -247
- package/lite/subscriber.js.map +1 -1
- package/lite/track.d.ts +4 -10
- package/lite/track.d.ts.map +1 -1
- package/lite/track.js +34 -29
- package/lite/track.js.map +1 -1
- package/lite/version.d.ts +42 -6
- package/lite/version.d.ts.map +1 -1
- package/lite/version.js +126 -10
- package/lite/version.js.map +1 -1
- package/origin.d.ts +256 -29
- package/origin.d.ts.map +1 -1
- package/origin.js +1427 -37
- package/origin.js.map +1 -1
- package/package.json +8 -3
- package/path.d.ts +25 -7
- package/path.d.ts.map +1 -1
- package/path.js +5 -3
- package/path.js.map +1 -1
- package/stream.d.ts +73 -14
- package/stream.d.ts.map +1 -1
- package/stream.js +372 -141
- package/stream.js.map +1 -1
- package/tail.d.ts +18 -0
- package/tail.d.ts.map +1 -0
- package/tail.js +167 -0
- package/tail.js.map +1 -0
- package/time.d.ts +15 -2
- package/time.d.ts.map +1 -1
- package/time.js +28 -9
- package/time.js.map +1 -1
- package/track.d.ts +211 -83
- package/track.d.ts.map +1 -1
- package/track.js +816 -205
- package/track.js.map +1 -1
- package/util/abort.d.ts +2 -0
- package/util/abort.d.ts.map +1 -0
- package/util/abort.js +20 -0
- package/util/abort.js.map +1 -0
- package/util/log.d.ts +5 -0
- package/util/log.d.ts.map +1 -0
- package/util/log.js +17 -0
- package/util/log.js.map +1 -0
- package/util/u64.d.ts +39 -0
- package/util/u64.d.ts.map +1 -0
- package/util/u64.js +83 -0
- package/util/u64.js.map +1 -0
- package/util/varint.d.ts +29 -0
- package/util/varint.d.ts.map +1 -0
- package/util/varint.js +198 -0
- package/util/varint.js.map +1 -0
- package/varint.d.ts +10 -6
- package/varint.d.ts.map +1 -1
- package/varint.js +40 -237
- package/varint.js.map +1 -1
- package/wire.d.ts +80 -0
- package/wire.d.ts.map +1 -0
- package/wire.js +32 -0
- package/wire.js.map +1 -0
- package/zod.d.ts +1 -1
- package/zod.d.ts.map +1 -1
- package/zod.js.map +1 -1
- package/mock.d.ts +0 -66
- package/mock.d.ts.map +0 -1
- package/mock.js +0 -243
- package/mock.js.map +0 -1
package/connection/accept.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accept.js","sourceRoot":"","sources":["../../src/connection/accept.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Ietf from \"../ietf/index.ts\";\nimport * as Lite from \"../lite/index.ts\";\nimport { Stream } from \"../stream.ts\";\nimport type { Established } from \"./established.ts\";\nimport { exchangeSetup } from \"./handshake.ts\";\n\n/** Options for {@link accept}. */\nexport interface AcceptProps {\n\t/** Version to select during SETUP negotiation (for non-ALPN paths). */\n\tversion?: number;\n\n\t/**\n\t * Whether this server supports broadcast discovery; see {@link Established.discovery}.\n\t * Defaults to true.\n\t */\n\tdiscovery?: boolean;\n}\n\n/**\n * Server-side handshake: accepts a transport and performs the server half of the SETUP exchange.\n *\n * @param transport - The WebTransport session to accept\n * @param url - The URL of the connection\n * @param props - Optional configuration\n * @returns A promise that resolves to a Connection instance\n */\nexport async function accept(transport: WebTransport, url: URL, props?: AcceptProps): Promise<Established> {\n\t// @ts-expect-error - TODO: add protocol to WebTransport\n\tconst protocol: string | undefined = transport.protocol;\n\n\tconst discovery = props?.discovery ?? true;\n\n\tif (protocol === Ietf.ALPN.DRAFT_20) {\n\t\treturn acceptAlpn(transport, url, Ietf.Version.DRAFT_20, discovery);\n\t}\n\tif (protocol === Ietf.ALPN.DRAFT_19) {\n\t\treturn acceptAlpn(transport, url, Ietf.Version.DRAFT_19, discovery);\n\t} else if (protocol === Ietf.ALPN.DRAFT_18) {\n\t\treturn acceptAlpn(transport, url, Ietf.Version.DRAFT_18, discovery);\n\t} else if (protocol === Ietf.ALPN.DRAFT_17) {\n\t\treturn acceptAlpn(transport, url, Ietf.Version.DRAFT_17, discovery);\n\t} else if (protocol === Ietf.ALPN.DRAFT_16) {\n\t\treturn acceptSetup(transport, url, Ietf.Version.DRAFT_16, discovery);\n\t} else if (protocol === Ietf.ALPN.DRAFT_15) {\n\t\treturn acceptSetup(transport, url, Ietf.Version.DRAFT_15, discovery);\n\t} else if (protocol === Lite.ALPN_06_WIP) {\n\t\treturn new Lite.Connection({ url, quic: transport, version: Lite.Version.DRAFT_06, discovery });\n\t} else if (protocol === Lite.ALPN_05) {\n\t\treturn new Lite.Connection({ url, quic: transport, version: Lite.Version.DRAFT_05, discovery });\n\t} else if (protocol === Lite.ALPN_04) {\n\t\treturn new Lite.Connection({ url, quic: transport, version: Lite.Version.DRAFT_04, discovery });\n\t} else if (protocol === Lite.ALPN_03) {\n\t\treturn new Lite.Connection({ url, quic: transport, version: Lite.Version.DRAFT_03, discovery });\n\t} else if (protocol === Lite.ALPN || protocol === \"\" || protocol === undefined) {\n\t\treturn acceptNegotiated(transport, url, props);\n\t} else {\n\t\tthrow new Error(`unsupported WebTransport protocol: ${protocol}`);\n\t}\n}\n\n/**\n * Draft-17+ accept: ALPN already pinned the version. SETUP is exchanged over\n * a pair of uni streams using stream type 0x2F00.\n */\nasync function acceptAlpn(\n\ttransport: WebTransport,\n\turl: URL,\n\tversion: Ietf.IetfVersion,\n\tdiscovery: boolean,\n): Promise<Established> {\n\tconst { control, solicit, cluster } = await exchangeSetup(transport, version, \"moq-lite-js\");\n\n\treturn new Ietf.Connection({\n\t\tdiscovery,\n\t\tclient: false,\n\t\turl,\n\t\tquic: transport,\n\t\tcontrol,\n\t\tsolicit,\n\t\tcluster,\n\t\t// v17+ uses NativeSession which manages its own request IDs; maxRequestId is unused.\n\t\tmaxRequestId: 0n,\n\t\tversion,\n\t});\n}\n\n/**\n * Legacy accept (draft-15/16): ALPN pinned the version, but the SETUP message\n * is still exchanged over a bidi stream wrapped in the moq-lite compat envelope.\n */\nasync function acceptSetup(\n\ttransport: WebTransport,\n\turl: URL,\n\tversion: Ietf.IetfVersion,\n\tdiscovery: boolean,\n): Promise<Established> {\n\t// Accept bidi, read ClientSetup, write ServerSetup\n\tconst stream = await Stream.accept(transport);\n\tif (!stream) throw new Error(\"no incoming bidi stream for SETUP\");\n\n\tconst clientCompat = await stream.reader.u53();\n\tif (clientCompat !== Lite.StreamId.ClientCompat) {\n\t\tthrow new Error(`unexpected client message type: 0x${clientCompat.toString(16)}`);\n\t}\n\n\tconst client = await Ietf.ClientSetup.decode(stream.reader, version);\n\n\tawait stream.writer.u53(Lite.StreamId.ServerCompat);\n\n\tconst encoder = new TextEncoder();\n\tconst params = new Ietf.SetupOptions();\n\tparams.setVarint(Ietf.SetupOption.MaxRequestId, 42069n);\n\tparams.setBytes(Ietf.SetupOption.Implementation, encoder.encode(\"moq-lite-js\"));\n\tIetf.solicitIntoSetup(params);\n\n\tconst server = new Ietf.ServerSetup({ version, parameters: params });\n\tawait server.encode(stream.writer, version);\n\n\tconst maxRequestId = 42069n;\n\n\treturn new Ietf.Connection({\n\t\tdiscovery,\n\t\tclient: false,\n\t\turl,\n\t\tquic: transport,\n\t\tcontrol: stream,\n\t\tmaxRequestId,\n\t\tversion,\n\t\tsolicit: Ietf.solicitFromSetup(client.parameters),\n\t});\n}\n\nasync function acceptNegotiated(transport: WebTransport, url: URL, props?: AcceptProps): Promise<Established> {\n\tconst discovery = props?.discovery ?? true;\n\tconst setupVersion = Ietf.Version.DRAFT_14;\n\n\tconst stream = await Stream.accept(transport);\n\tif (!stream) throw new Error(\"no incoming bidi stream for SETUP\");\n\n\tconst clientCompat = await stream.reader.u53();\n\tif (clientCompat !== Lite.StreamId.ClientCompat) {\n\t\tthrow new Error(`unexpected client message type: 0x${clientCompat.toString(16)}`);\n\t}\n\n\tconst client = await Ietf.ClientSetup.decode(stream.reader, setupVersion);\n\n\t// Pick the requested version, or first matching version from client's list\n\tconst allVersions = [...Object.values(Lite.Version), ...Object.values(Ietf.Version)] as number[];\n\tlet selectedVersion: number;\n\tif (props?.version !== undefined) {\n\t\tselectedVersion = props.version;\n\t} else {\n\t\tconst match = client.versions.find((v) => allVersions.includes(v));\n\t\tif (match === undefined) {\n\t\t\tthrow new Error(\n\t\t\t\t`no common version found; client offered: ${client.versions.map((v) => v.toString(16)).join(\", \")}`,\n\t\t\t);\n\t\t}\n\t\tselectedVersion = match;\n\t}\n\n\tawait stream.writer.u53(Lite.StreamId.ServerCompat);\n\n\tconst encoder = new TextEncoder();\n\tconst params = new Ietf.SetupOptions();\n\tparams.setVarint(Ietf.SetupOption.MaxRequestId, 42069n);\n\tparams.setBytes(Ietf.SetupOption.Implementation, encoder.encode(\"moq-lite-js\"));\n\tIetf.solicitIntoSetup(params);\n\n\tconst server = new Ietf.ServerSetup({ version: selectedVersion, parameters: params });\n\tawait server.encode(stream.writer, setupVersion);\n\n\tif (Object.values(Lite.Version).includes(selectedVersion as Lite.Version)) {\n\t\treturn new Lite.Connection({\n\t\t\turl,\n\t\t\tquic: transport,\n\t\t\tversion: selectedVersion as Lite.Version,\n\t\t\tsession: stream,\n\t\t\tdiscovery,\n\t\t});\n\t} else if (Object.values(Ietf.Version).includes(selectedVersion as Ietf.Version)) {\n\t\tconst maxRequestId = client.parameters.getVarint(Ietf.SetupOption.MaxRequestId) ?? 0n;\n\t\treturn new Ietf.Connection({\n\t\t\tdiscovery,\n\t\t\tclient: false,\n\t\t\turl,\n\t\t\tquic: transport,\n\t\t\tcontrol: stream,\n\t\t\tmaxRequestId,\n\t\t\tversion: selectedVersion as Ietf.IetfVersion,\n\t\t\tsolicit: Ietf.solicitFromSetup(client.parameters),\n\t\t});\n\t} else {\n\t\tthrow new Error(`unsupported version: ${selectedVersion.toString(16)}`);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"accept.js","sourceRoot":"","sources":["../../src/connection/accept.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Ietf from \"../ietf/index.ts\";\nimport * as Lite from \"../lite/index.ts\";\nimport type { Consumer as OriginConsumer, Producer as OriginProducer } from \"../origin.ts\";\nimport { Stream } from \"../stream.ts\";\nimport type { Established } from \"./established.ts\";\nimport { forwardAnnounced } from \"./forward.ts\";\nimport { exchangeSetup } from \"./handshake.ts\";\n\n/** Options for {@link accept}. */\nexport interface AcceptProps {\n\t/** The accepted transport. */\n\ttransport: WebTransport;\n\t/** The request URL associated with the transport. */\n\turl: URL;\n\n\t/** Version to select during SETUP negotiation (for non-ALPN paths). */\n\tversion?: number;\n\n\t/**\n\t * Whether this server supports broadcast discovery; see {@link Established.discovery}.\n\t * Defaults to true.\n\t */\n\tdiscovery?: boolean;\n\n\t/**\n\t * The origin whose broadcasts the session announces and serves to the peer. Omit to\n\t * publish nothing. Borrowed, not owned: closing the session leaves its broadcasts alone.\n\t */\n\tpublish?: OriginConsumer;\n\n\t/**\n\t * The origin the session feeds with the peer's announced broadcasts. Omit to discover\n\t * nothing. The entries retract when the session dies; see the `consume` connect option.\n\t */\n\tconsume?: OriginProducer;\n}\n\n/** The per-session wiring shared by every negotiated protocol path. */\ntype SessionProps = {\n\tdiscovery: boolean;\n\tpublish?: OriginConsumer;\n};\n\n/**\n * Server-side handshake: accepts a transport and performs the server half of the SETUP exchange.\n *\n * @param transport - The WebTransport session to accept\n * @param url - The URL of the connection\n * @param props - Optional configuration\n * @returns A promise that resolves to a Connection instance\n */\nexport async function accept({ transport, url, ...props }: AcceptProps): Promise<Established> {\n\tconst connection = await acceptInner(transport, url, props);\n\tif (props.consume) forwardAnnounced(connection, props.consume);\n\treturn connection;\n}\n\nasync function acceptInner(\n\ttransport: WebTransport,\n\turl: URL,\n\tprops: Omit<AcceptProps, \"transport\" | \"url\">,\n): Promise<Established> {\n\t// The DOM lib has no `protocol` property yet. It is \"\" when none was negotiated, and\n\t// undefined in a browser that predates subprotocols (Firefox before 155).\n\tconst protocol = (transport as { protocol?: string }).protocol;\n\n\tconst wiring: SessionProps = {\n\t\tdiscovery: props.discovery ?? true,\n\t\tpublish: props.publish,\n\t};\n\n\tif (protocol === Ietf.ALPN.DRAFT_22) {\n\t\treturn acceptAlpn(transport, url, Ietf.Version.DRAFT_22, wiring);\n\t}\n\tif (protocol === Ietf.ALPN.DRAFT_21) {\n\t\treturn acceptAlpn(transport, url, Ietf.Version.DRAFT_21, wiring);\n\t}\n\tif (protocol === Ietf.ALPN.DRAFT_20) {\n\t\treturn acceptAlpn(transport, url, Ietf.Version.DRAFT_20, wiring);\n\t}\n\tif (protocol === Ietf.ALPN.DRAFT_19) {\n\t\treturn acceptAlpn(transport, url, Ietf.Version.DRAFT_19, wiring);\n\t} else if (protocol === Ietf.ALPN.DRAFT_18) {\n\t\treturn acceptAlpn(transport, url, Ietf.Version.DRAFT_18, wiring);\n\t} else if (protocol === Ietf.ALPN.DRAFT_17) {\n\t\treturn acceptAlpn(transport, url, Ietf.Version.DRAFT_17, wiring);\n\t} else if (protocol === Ietf.ALPN.DRAFT_16) {\n\t\treturn acceptSetup(transport, url, Ietf.Version.DRAFT_16, wiring);\n\t} else if (protocol === Ietf.ALPN.DRAFT_15) {\n\t\treturn acceptSetup(transport, url, Ietf.Version.DRAFT_15, wiring);\n\t} else if (protocol === Lite.ALPN_07_WIP) {\n\t\treturn new Lite.Connection({ url, quic: transport, version: Lite.Version.DRAFT_07, ...wiring });\n\t} else if (protocol === Lite.ALPN_06) {\n\t\treturn new Lite.Connection({ url, quic: transport, version: Lite.Version.DRAFT_06, ...wiring });\n\t} else if (protocol === Lite.ALPN_05) {\n\t\treturn new Lite.Connection({ url, quic: transport, version: Lite.Version.DRAFT_05, ...wiring });\n\t} else if (protocol === Lite.ALPN_04) {\n\t\treturn new Lite.Connection({ url, quic: transport, version: Lite.Version.DRAFT_04, ...wiring });\n\t} else if (protocol === Lite.ALPN_03) {\n\t\treturn new Lite.Connection({ url, quic: transport, version: Lite.Version.DRAFT_03, ...wiring });\n\t} else if (protocol === Lite.ALPN || protocol === \"\" || protocol === undefined) {\n\t\treturn acceptNegotiated(transport, url, wiring, props.version);\n\t} else {\n\t\tthrow new Error(`unsupported WebTransport protocol: ${protocol}`);\n\t}\n}\n\n/**\n * Draft-17+ accept: ALPN already pinned the version. SETUP is exchanged over\n * a pair of uni streams using stream type 0x2F00.\n */\nasync function acceptAlpn(\n\ttransport: WebTransport,\n\turl: URL,\n\tversion: Ietf.IetfVersion,\n\twiring: SessionProps,\n): Promise<Established> {\n\tconst { control, solicit, hidden, cluster } = await exchangeSetup(transport, version, \"moq-lite-js\");\n\n\treturn new Ietf.Connection({\n\t\t...wiring,\n\t\tclient: false,\n\t\turl,\n\t\tquic: transport,\n\t\tcontrol,\n\t\tsolicit,\n\t\thidden,\n\t\tcluster,\n\t\t// v17+ uses NativeSession which manages its own request IDs; maxRequestId is unused.\n\t\tmaxRequestId: 0n,\n\t\tversion,\n\t});\n}\n\n/**\n * Legacy accept (draft-15/16): ALPN pinned the version, but the SETUP message\n * is still exchanged over a bidi stream wrapped in the moq-lite compat envelope.\n */\nasync function acceptSetup(\n\ttransport: WebTransport,\n\turl: URL,\n\tversion: Ietf.IetfVersion,\n\twiring: SessionProps,\n): Promise<Established> {\n\t// Accept bidi, read ClientSetup, write ServerSetup\n\tconst stream = await Stream.accept(transport, version);\n\tif (!stream) throw new Error(\"no incoming bidi stream for SETUP\");\n\n\tconst clientCompat = await stream.reader.u53();\n\tif (clientCompat !== Lite.StreamId.ClientCompat) {\n\t\tthrow new Error(`unexpected client message type: 0x${clientCompat.toString(16)}`);\n\t}\n\n\tconst client = await Ietf.ClientSetup.decode(stream.reader, version);\n\n\tawait stream.writer.u53(Lite.StreamId.ServerCompat);\n\n\tconst encoder = new TextEncoder();\n\tconst params = new Ietf.SetupOptions();\n\tparams.setVarint(Ietf.SetupOption.MaxRequestId, 42069n);\n\tparams.setBytes(Ietf.SetupOption.Implementation, encoder.encode(\"moq-lite-js\"));\n\tIetf.solicitIntoSetup(params);\n\tIetf.hiddenIntoSetup(params);\n\n\tconst server = new Ietf.ServerSetup({ version, parameters: params });\n\tawait server.encode(stream.writer, version);\n\n\tconst maxRequestId = 42069n;\n\n\treturn new Ietf.Connection({\n\t\t...wiring,\n\t\tclient: false,\n\t\turl,\n\t\tquic: transport,\n\t\tcontrol: stream,\n\t\tmaxRequestId,\n\t\tversion,\n\t\tsolicit: Ietf.solicitFromSetup(client.parameters),\n\t\thidden: Ietf.hiddenFromSetup(client.parameters),\n\t});\n}\n\nasync function acceptNegotiated(\n\ttransport: WebTransport,\n\turl: URL,\n\twiring: SessionProps,\n\tversion?: number,\n): Promise<Established> {\n\tconst setupVersion = Ietf.Version.DRAFT_14;\n\n\tconst stream = await Stream.accept(transport, setupVersion);\n\tif (!stream) throw new Error(\"no incoming bidi stream for SETUP\");\n\n\tconst clientCompat = await stream.reader.u53();\n\tif (clientCompat !== Lite.StreamId.ClientCompat) {\n\t\tthrow new Error(`unexpected client message type: 0x${clientCompat.toString(16)}`);\n\t}\n\n\tconst client = await Ietf.ClientSetup.decode(stream.reader, setupVersion);\n\n\t// Pick the requested version, or first matching version from client's list\n\tconst allVersions = [...Object.values(Lite.Version), ...Object.values(Ietf.Version)] as number[];\n\tlet selectedVersion: number;\n\tif (version !== undefined) {\n\t\tselectedVersion = version;\n\t} else {\n\t\tconst match = client.versions.find((v) => allVersions.includes(v));\n\t\tif (match === undefined) {\n\t\t\tthrow new Error(\n\t\t\t\t`no common version found; client offered: ${client.versions.map((v) => v.toString(16)).join(\", \")}`,\n\t\t\t);\n\t\t}\n\t\tselectedVersion = match;\n\t}\n\n\tawait stream.writer.u53(Lite.StreamId.ServerCompat);\n\n\tconst encoder = new TextEncoder();\n\tconst params = new Ietf.SetupOptions();\n\tparams.setVarint(Ietf.SetupOption.MaxRequestId, 42069n);\n\tparams.setBytes(Ietf.SetupOption.Implementation, encoder.encode(\"moq-lite-js\"));\n\tIetf.solicitIntoSetup(params);\n\tIetf.hiddenIntoSetup(params);\n\n\tconst server = new Ietf.ServerSetup({ version: selectedVersion, parameters: params });\n\tawait server.encode(stream.writer, setupVersion);\n\n\tif (Object.values(Lite.Version).includes(selectedVersion as Lite.Version)) {\n\t\treturn new Lite.Connection({\n\t\t\turl,\n\t\t\tquic: transport,\n\t\t\tversion: selectedVersion as Lite.Version,\n\t\t\tsession: stream,\n\t\t\t...wiring,\n\t\t});\n\t} else if (Object.values(Ietf.Version).includes(selectedVersion as Ietf.Version)) {\n\t\tconst maxRequestId = client.parameters.getVarint(Ietf.SetupOption.MaxRequestId) ?? 0n;\n\t\treturn new Ietf.Connection({\n\t\t\t...wiring,\n\t\t\tclient: false,\n\t\t\turl,\n\t\t\tquic: transport,\n\t\t\tcontrol: stream,\n\t\t\tmaxRequestId,\n\t\t\tversion: selectedVersion as Ietf.IetfVersion,\n\t\t\tsolicit: Ietf.solicitFromSetup(client.parameters),\n\t\t\thidden: Ietf.hiddenFromSetup(client.parameters),\n\t\t});\n\t} else {\n\t\tthrow new Error(`unsupported version: ${selectedVersion.toString(16)}`);\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/connection/browser.ts"],"names":[],"mappings":"AAEA,qFAAqF;AACrF,wBAAgB,gCAAgC,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/connection/browser.ts"],"names":[],"mappings":"AAEA,qFAAqF;AACrF,wBAAgB,gCAAgC,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAsB3E;AAED,kEAAkE;AAClE,wBAAgB,uBAAuB,IAAI,OAAO,CAIjD"}
|
package/connection/browser.js
CHANGED
|
@@ -3,19 +3,21 @@ import Bowser from "bowser";
|
|
|
3
3
|
/** Returns whether a browser user agent has a usable WebTransport implementation. */
|
|
4
4
|
export function isWebTransportUserAgentSupported(userAgent) {
|
|
5
5
|
const browser = Bowser.getParser(userAgent);
|
|
6
|
+
// Every WebKit engine stalls long sessions: the flow-control window never
|
|
7
|
+
// refills (https://bugs.webkit.org/show_bug.cgi?id=319818), and incoming
|
|
8
|
+
// unidirectional streams stop for good after roughly 7,600 of them or 16 MiB
|
|
9
|
+
// on one session (moq-dev/moq#2388); one stream per group reaches that in
|
|
10
|
+
// about two minutes. Chrome, Firefox and Edge on iOS are WebKit under the
|
|
11
|
+
// hood, and iPadOS Safari reports macOS, so gate on the engine and the OS.
|
|
12
|
+
if (browser.getEngine().name === "WebKit" || browser.getOS().name === "iOS")
|
|
13
|
+
return false;
|
|
6
14
|
const supported = browser.satisfies({
|
|
7
15
|
// Fixed with 153.0.0, Firefox only allows two concurrent remote-initiated streams:
|
|
8
16
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=2046262
|
|
9
17
|
firefox: ">=153.0",
|
|
10
|
-
// Safari's flow-control window never refills, which permanently stalls sessions:
|
|
11
|
-
// https://bugs.webkit.org/show_bug.cgi?id=319818
|
|
12
|
-
// It also stops delivering incoming unidirectional streams for good after
|
|
13
|
-
// roughly 7,600 of them or 16 MiB on one session, whichever comes first
|
|
14
|
-
// (moq-dev/moq#2388); one stream per group reaches that in about two minutes.
|
|
15
|
-
safari: "<0",
|
|
16
18
|
});
|
|
17
19
|
if (supported === undefined) {
|
|
18
|
-
//By default, other browsers are considered to support WebTransport.
|
|
20
|
+
// By default, other browsers are considered to support WebTransport.
|
|
19
21
|
return true;
|
|
20
22
|
}
|
|
21
23
|
return supported;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/connection/browser.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,qFAAqF;AACrF,MAAM,UAAU,gCAAgC,CAAC,SAAiB;IACjE,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/connection/browser.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,qFAAqF;AACrF,MAAM,UAAU,gCAAgC,CAAC,SAAiB;IACjE,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAE5C,0EAA0E;IAC1E,yEAAyE;IACzE,6EAA6E;IAC7E,0EAA0E;IAC1E,0EAA0E;IAC1E,2EAA2E;IAC3E,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,IAAI,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IAE1F,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,mFAAmF;QACnF,uDAAuD;QACvD,OAAO,EAAE,SAAS;KAClB,CAAC,CAAC;IAEH,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC7B,qEAAqE;QACrE,OAAO,IAAI,CAAC;IACb,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,uBAAuB;IACtC,IAAI,OAAO,UAAU,CAAC,YAAY,KAAK,WAAW;QAAE,OAAO,KAAK,CAAC;IACjE,IAAI,OAAO,SAAS,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IAClD,OAAO,gCAAgC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;AAC9D,CAAC","sourcesContent":["import Bowser from \"bowser\";\n\n/** Returns whether a browser user agent has a usable WebTransport implementation. */\nexport function isWebTransportUserAgentSupported(userAgent: string): boolean {\n\tconst browser = Bowser.getParser(userAgent);\n\n\t// Every WebKit engine stalls long sessions: the flow-control window never\n\t// refills (https://bugs.webkit.org/show_bug.cgi?id=319818), and incoming\n\t// unidirectional streams stop for good after roughly 7,600 of them or 16 MiB\n\t// on one session (moq-dev/moq#2388); one stream per group reaches that in\n\t// about two minutes. Chrome, Firefox and Edge on iOS are WebKit under the\n\t// hood, and iPadOS Safari reports macOS, so gate on the engine and the OS.\n\tif (browser.getEngine().name === \"WebKit\" || browser.getOS().name === \"iOS\") return false;\n\n\tconst supported = browser.satisfies({\n\t\t// Fixed with 153.0.0, Firefox only allows two concurrent remote-initiated streams:\n\t\t// https://bugzilla.mozilla.org/show_bug.cgi?id=2046262\n\t\tfirefox: \">=153.0\",\n\t});\n\n\tif (supported === undefined) {\n\t\t// By default, other browsers are considered to support WebTransport.\n\t\treturn true;\n\t}\n\treturn supported;\n}\n\n/** Returns whether this runtime can connect with WebTransport. */\nexport function isWebTransportSupported(): boolean {\n\tif (typeof globalThis.WebTransport === \"undefined\") return false;\n\tif (typeof navigator === \"undefined\") return true;\n\treturn isWebTransportUserAgentSupported(navigator.userAgent);\n}\n"]}
|
package/connection/connect.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import type { Consumer as OriginConsumer, Producer as OriginProducer } from "../origin";
|
|
2
|
+
import * as Time from "../time";
|
|
1
3
|
import type { Established } from "./established";
|
|
2
4
|
/** Tuning for the WebSocket fallback used when WebTransport is unavailable or loses the connect race. */
|
|
3
|
-
export interface
|
|
5
|
+
export interface WebSocketProps {
|
|
4
6
|
/** Enable the WebSocket fallback. Defaults to `true`. */
|
|
5
7
|
enabled?: boolean;
|
|
6
8
|
/** Use a different URL than WebTransport. By default, `https` maps to `wss` and `http` to `ws`. */
|
|
@@ -9,7 +11,7 @@ export interface WebSocketOptions {
|
|
|
9
11
|
* The delay in milliseconds before attempting the WebSocket fallback (default: 500).
|
|
10
12
|
* If WebSocket won the previous race for a given URL, this is 0.
|
|
11
13
|
*/
|
|
12
|
-
delay?:
|
|
14
|
+
delay?: Time.Milli;
|
|
13
15
|
}
|
|
14
16
|
/**
|
|
15
17
|
* A server certificate hash used to pin a self-signed server, one entry of
|
|
@@ -38,10 +40,12 @@ export interface WebTransportProps extends Omit<WebTransportOptions, "serverCert
|
|
|
38
40
|
}
|
|
39
41
|
/** Options for {@link connect}. */
|
|
40
42
|
export interface ConnectProps {
|
|
43
|
+
/** The relay URL. */
|
|
44
|
+
url: URL;
|
|
41
45
|
/** WebTransport options. */
|
|
42
46
|
webtransport?: WebTransportProps;
|
|
43
47
|
/** WebSocket (fallback) options. */
|
|
44
|
-
websocket?:
|
|
48
|
+
websocket?: WebSocketProps;
|
|
45
49
|
/**
|
|
46
50
|
* Use a pre-existing WebTransport session instead of connecting; skips the
|
|
47
51
|
* WebTransport/WebSocket race. The publisher acquires the session's datagram
|
|
@@ -52,9 +56,29 @@ export interface ConnectProps {
|
|
|
52
56
|
transport?: WebTransport;
|
|
53
57
|
/**
|
|
54
58
|
* Whether the relay supports broadcast discovery; see {@link Established.discovery}.
|
|
55
|
-
* Defaults to true
|
|
59
|
+
* Defaults to true.
|
|
56
60
|
*/
|
|
57
61
|
discovery?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* The origin whose broadcasts the session announces and serves to the peer. Omit to
|
|
64
|
+
* publish nothing.
|
|
65
|
+
*
|
|
66
|
+
* The origin is borrowed, not owned: closing the session leaves its broadcasts alone,
|
|
67
|
+
* and the same origin can back several sessions (or successive reconnects), each
|
|
68
|
+
* announcing the table for as long as it lasts.
|
|
69
|
+
*/
|
|
70
|
+
publish?: OriginConsumer;
|
|
71
|
+
/**
|
|
72
|
+
* The origin the session feeds with the peer's announced broadcasts. Omit to discover
|
|
73
|
+
* nothing.
|
|
74
|
+
*
|
|
75
|
+
* Everything the peer announces appears in the origin's table for the session's
|
|
76
|
+
* lifetime, consumable by path; the entries retract when the session dies. Pass the
|
|
77
|
+
* producer behind {@link ConnectProps.publish} to route both directions through one
|
|
78
|
+
* origin: a locally published path is then served back to local consumers directly, and
|
|
79
|
+
* the session still never announces the peer's own broadcasts back to it.
|
|
80
|
+
*/
|
|
81
|
+
consume?: OriginProducer;
|
|
58
82
|
/**
|
|
59
83
|
* Aborts the connection attempt with the signal's reason. An already-aborted
|
|
60
84
|
* signal rejects before anything opens, and aborting after the connection is
|
|
@@ -67,9 +91,9 @@ export interface ConnectProps {
|
|
|
67
91
|
*
|
|
68
92
|
* @param url - The URL of the server to connect to
|
|
69
93
|
* @param props - Connection options
|
|
70
|
-
* @returns A promise that resolves to
|
|
94
|
+
* @returns A promise that resolves to an established session
|
|
71
95
|
*/
|
|
72
|
-
export declare function connect(url
|
|
96
|
+
export declare function connect({ url, ...props }: ConnectProps): Promise<Established>;
|
|
73
97
|
/**
|
|
74
98
|
* Compute the SHA-256 hash of a certificate, the value `serverCertificateHashes`
|
|
75
99
|
* pins. Accepts a PEM string or raw DER bytes. Matches the hex fingerprints a moq
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/connection/connect.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/connection/connect.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,IAAI,cAAc,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,cAAc,CAAC;AAE3F,OAAO,KAAK,IAAI,MAAM,YAAY,CAAC;AAInC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAWpD,yGAAyG;AACzG,MAAM,WAAW,cAAc;IAC9B,yDAAyD;IACzD,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,mGAAmG;IACnG,GAAG,CAAC,EAAE,GAAG,CAAC;IAEV;;;OAGG;IACH,KAAK,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC/B,4EAA4E;IAC5E,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,uDAAuD;IACvD,KAAK,EAAE,YAAY,GAAG,MAAM,CAAC;CAC7B;AAED,2GAA2G;AAC3G,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,mBAAmB,EAAE,yBAAyB,CAAC;IAC9F;;;OAGG;IACH,uBAAuB,CAAC,EAAE,eAAe,EAAE,CAAC;IAE5C;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,GAAG,YAAY,CAAC;CAC1C;AAED,mCAAmC;AACnC,MAAM,WAAW,YAAY;IAC5B,qBAAqB;IACrB,GAAG,EAAE,GAAG,CAAC;IAET,4BAA4B;IAC5B,YAAY,CAAC,EAAE,iBAAiB,CAAC;IAEjC,oCAAoC;IACpC,SAAS,CAAC,EAAE,cAAc,CAAC;IAE3B;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,YAAY,CAAC;IAEzB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IAEzB;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IAEzB;;;;OAIG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB;AAcD;;;;;;GAMG;AACH,wBAAsB,OAAO,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAwBnF;AA4OD;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAInG"}
|
package/connection/connect.js
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
/* @ts-self-types="./connect.d.ts" */
|
|
2
2
|
import Session from "@moq/qmux";
|
|
3
|
+
import { error, fromClose } from "../error.js";
|
|
3
4
|
import * as Ietf from "../ietf/index.js";
|
|
4
5
|
import * as Lite from "../lite/index.js";
|
|
5
6
|
import { Stream } from "../stream.js";
|
|
7
|
+
import * as Time from "../time.js";
|
|
6
8
|
import * as Hex from "../util/hex.js";
|
|
9
|
+
import { dev, redact } from "../util/log.js";
|
|
7
10
|
import { isWebTransportSupported } from "./browser.js";
|
|
11
|
+
import { forwardAnnounced } from "./forward.js";
|
|
8
12
|
import { exchangeSetup } from "./handshake.js";
|
|
9
13
|
// Default head start for WebTransport before attempting the WebSocket fallback.
|
|
10
|
-
const DEFAULT_WEBSOCKET_DELAY_MS = 500;
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
|
|
14
|
-
const NO_DISCOVERY_HOSTS = ["mediaoverquic.com"];
|
|
15
|
-
/** Whether the relay at `url` is expected to support broadcast discovery. */
|
|
16
|
-
function defaultDiscovery(url) {
|
|
17
|
-
return !NO_DISCOVERY_HOSTS.some((host) => url.hostname.endsWith(host));
|
|
18
|
-
}
|
|
14
|
+
const DEFAULT_WEBSOCKET_DELAY_MS = Time.Milli(500);
|
|
15
|
+
// RESET_STREAM and CONNECTION_CLOSE are separate transport notifications. Give the latter
|
|
16
|
+
// time to surface its authoritative code without letting a reset-only peer stall SETUP forever.
|
|
17
|
+
const SETUP_CLOSE_GRACE_MS = 100;
|
|
19
18
|
// Save if WebSocket won the last race, so we won't give QUIC a head start next time.
|
|
20
19
|
const websocketWon = new Set();
|
|
21
20
|
/** The default connect signal: never aborts. */
|
|
@@ -25,10 +24,10 @@ const NEVER_ABORTED = new AbortController().signal;
|
|
|
25
24
|
*
|
|
26
25
|
* @param url - The URL of the server to connect to
|
|
27
26
|
* @param props - Connection options
|
|
28
|
-
* @returns A promise that resolves to
|
|
27
|
+
* @returns A promise that resolves to an established session
|
|
29
28
|
*/
|
|
30
|
-
export async function connect(url, props) {
|
|
31
|
-
const signal = props
|
|
29
|
+
export async function connect({ url, ...props }) {
|
|
30
|
+
const signal = props.signal ?? NEVER_ABORTED;
|
|
32
31
|
signal.throwIfAborted();
|
|
33
32
|
// Resolves on abort so every in-flight transport tears itself down.
|
|
34
33
|
const { promise: abort, resolve } = Promise.withResolvers();
|
|
@@ -38,8 +37,11 @@ export async function connect(url, props) {
|
|
|
38
37
|
try {
|
|
39
38
|
// A `pending` rejection propagates unless the abort beat it to the finish line.
|
|
40
39
|
const connection = await Promise.race([pending, abort.then(() => undefined)]);
|
|
41
|
-
if (connection && !signal.aborted)
|
|
40
|
+
if (connection && !signal.aborted) {
|
|
41
|
+
if (props.consume)
|
|
42
|
+
forwardAnnounced(connection, props.consume);
|
|
42
43
|
return connection;
|
|
44
|
+
}
|
|
43
45
|
// Close a connection that settles after the abort.
|
|
44
46
|
pending.then((conn) => conn.close()).catch(() => { });
|
|
45
47
|
throw signal.reason;
|
|
@@ -49,21 +51,24 @@ export async function connect(url, props) {
|
|
|
49
51
|
}
|
|
50
52
|
}
|
|
51
53
|
async function connectInner(url, props, abort) {
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
+
const wiring = {
|
|
55
|
+
discovery: props.discovery ?? true,
|
|
56
|
+
publish: props.publish,
|
|
57
|
+
};
|
|
58
|
+
if (props.transport) {
|
|
54
59
|
const transport = props.transport;
|
|
55
60
|
void abort.then(() => transport.close());
|
|
56
|
-
return connectTransport(url, transport,
|
|
61
|
+
return connectTransport(url, transport, wiring);
|
|
57
62
|
}
|
|
58
63
|
// Stop transports after one connects or the caller aborts.
|
|
59
64
|
const { promise: raced, resolve: done } = Promise.withResolvers();
|
|
60
65
|
const cancel = Promise.race([raced, abort]);
|
|
61
|
-
const webtransport = isWebTransportSupported() ? connectWebTransport(url, cancel, props
|
|
66
|
+
const webtransport = isWebTransportSupported() ? connectWebTransport(url, cancel, props.webtransport) : undefined;
|
|
62
67
|
// Give QUIC a head start to connect before trying WebSocket, unless WebSocket has won in the past.
|
|
63
68
|
// NOTE that QUIC should be faster because it involves 1/2 fewer RTTs.
|
|
64
|
-
const headstart = !webtransport || websocketWon.has(url.toString()) ? 0 : (props
|
|
65
|
-
const websocket = props
|
|
66
|
-
? connectWebSocket(props
|
|
69
|
+
const headstart = !webtransport || websocketWon.has(url.toString()) ? 0 : (props.websocket?.delay ?? DEFAULT_WEBSOCKET_DELAY_MS);
|
|
70
|
+
const websocket = props.websocket?.enabled !== false
|
|
71
|
+
? connectWebSocket(props.websocket?.url ?? url, headstart, cancel)
|
|
67
72
|
: undefined;
|
|
68
73
|
if (!websocket && !webtransport) {
|
|
69
74
|
throw new Error("no transport available; WebTransport not supported and WebSocket is disabled");
|
|
@@ -83,33 +88,68 @@ async function connectInner(url, props, abort) {
|
|
|
83
88
|
void abort.then(() => session.close());
|
|
84
89
|
// Save if WebSocket won the last race, so we won't give QUIC a head start next time.
|
|
85
90
|
if (session instanceof Session) {
|
|
86
|
-
|
|
91
|
+
// Still a warning, not a debug line: losing the race means we fell back off QUIC.
|
|
92
|
+
if (dev())
|
|
93
|
+
console.warn(redact(url), "connected via WebSocket");
|
|
87
94
|
websocketWon.add(url.toString());
|
|
88
95
|
}
|
|
89
|
-
else {
|
|
90
|
-
console.debug(url
|
|
96
|
+
else if (dev()) {
|
|
97
|
+
console.debug(redact(url), "connected via WebTransport");
|
|
91
98
|
}
|
|
92
99
|
// The remaining setup is identical whether the transport was raced or supplied.
|
|
93
|
-
return await connectTransport(url, session,
|
|
100
|
+
return await connectTransport(url, session, wiring);
|
|
94
101
|
}
|
|
95
|
-
async function connectTransport(url, session,
|
|
96
|
-
|
|
97
|
-
|
|
102
|
+
async function connectTransport(url, session, wiring) {
|
|
103
|
+
const closed = session.closed.then(fromClose, error);
|
|
104
|
+
const terminal = closed.then((cause) => {
|
|
105
|
+
throw cause ?? new Error("session closed during SETUP");
|
|
106
|
+
});
|
|
107
|
+
try {
|
|
108
|
+
return await Promise.race([terminal, negotiate(url, session, wiring)]);
|
|
109
|
+
}
|
|
110
|
+
catch (cause) {
|
|
111
|
+
// A session shutdown can reject its SETUP stream before `closed` publishes the
|
|
112
|
+
// peer's close code. Wait briefly without closing locally, since a local clean close
|
|
113
|
+
// could overwrite that code. A reset-only peer is cleaned up after the grace period.
|
|
114
|
+
const pending = Symbol("session close pending");
|
|
115
|
+
const final = await Promise.race([
|
|
116
|
+
closed,
|
|
117
|
+
new Promise((resolve) => setTimeout(() => resolve(pending), SETUP_CLOSE_GRACE_MS)),
|
|
118
|
+
]);
|
|
119
|
+
if (final !== pending) {
|
|
120
|
+
if (final)
|
|
121
|
+
throw final;
|
|
122
|
+
throw cause;
|
|
123
|
+
}
|
|
124
|
+
session.close();
|
|
125
|
+
throw cause;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Negotiate the MoQ protocol over an established transport. The caller races this against
|
|
129
|
+
// the session closing so a close code is not lost behind a failed or stalled SETUP stream.
|
|
130
|
+
async function negotiate(url, session, wiring) {
|
|
131
|
+
// The DOM lib has no `protocol` property yet. It is "" when none was negotiated, and
|
|
132
|
+
// undefined in a browser that predates subprotocols (Firefox before 155).
|
|
98
133
|
const protocol = session.protocol || undefined;
|
|
99
|
-
|
|
134
|
+
if (dev())
|
|
135
|
+
console.debug(redact(url), "negotiated ALPN:", protocol ?? "(none)");
|
|
100
136
|
// Choose setup encoding based on negotiated WebTransport protocol (if any).
|
|
101
137
|
let setupVersion;
|
|
102
|
-
const modernVersion = protocol === Ietf.ALPN.
|
|
103
|
-
? Ietf.Version.
|
|
104
|
-
: protocol === Ietf.ALPN.
|
|
105
|
-
? Ietf.Version.
|
|
106
|
-
: protocol === Ietf.ALPN.
|
|
107
|
-
? Ietf.Version.
|
|
108
|
-
: protocol === Ietf.ALPN.
|
|
109
|
-
? Ietf.Version.
|
|
110
|
-
:
|
|
138
|
+
const modernVersion = protocol === Ietf.ALPN.DRAFT_22
|
|
139
|
+
? Ietf.Version.DRAFT_22
|
|
140
|
+
: protocol === Ietf.ALPN.DRAFT_21
|
|
141
|
+
? Ietf.Version.DRAFT_21
|
|
142
|
+
: protocol === Ietf.ALPN.DRAFT_20
|
|
143
|
+
? Ietf.Version.DRAFT_20
|
|
144
|
+
: protocol === Ietf.ALPN.DRAFT_19
|
|
145
|
+
? Ietf.Version.DRAFT_19
|
|
146
|
+
: protocol === Ietf.ALPN.DRAFT_18
|
|
147
|
+
? Ietf.Version.DRAFT_18
|
|
148
|
+
: protocol === Ietf.ALPN.DRAFT_17
|
|
149
|
+
? Ietf.Version.DRAFT_17
|
|
150
|
+
: undefined;
|
|
111
151
|
if (modernVersion !== undefined) {
|
|
112
|
-
return await handshakeAlpn(url, session, modernVersion,
|
|
152
|
+
return await handshakeAlpn(url, session, modernVersion, wiring);
|
|
113
153
|
}
|
|
114
154
|
else if (protocol === Ietf.ALPN.DRAFT_16) {
|
|
115
155
|
setupVersion = Ietf.Version.DRAFT_16;
|
|
@@ -117,17 +157,20 @@ async function connectTransport(url, session, discovery) {
|
|
|
117
157
|
else if (protocol === Ietf.ALPN.DRAFT_15) {
|
|
118
158
|
setupVersion = Ietf.Version.DRAFT_15;
|
|
119
159
|
}
|
|
120
|
-
else if (protocol === Lite.
|
|
121
|
-
return new Lite.Connection({ url, quic: session, version: Lite.Version.
|
|
160
|
+
else if (protocol === Lite.ALPN_07_WIP) {
|
|
161
|
+
return new Lite.Connection({ url, quic: session, version: Lite.Version.DRAFT_07, ...wiring });
|
|
162
|
+
}
|
|
163
|
+
else if (protocol === Lite.ALPN_06) {
|
|
164
|
+
return new Lite.Connection({ url, quic: session, version: Lite.Version.DRAFT_06, ...wiring });
|
|
122
165
|
}
|
|
123
166
|
else if (protocol === Lite.ALPN_05) {
|
|
124
|
-
return new Lite.Connection({ url, quic: session, version: Lite.Version.DRAFT_05,
|
|
167
|
+
return new Lite.Connection({ url, quic: session, version: Lite.Version.DRAFT_05, ...wiring });
|
|
125
168
|
}
|
|
126
169
|
else if (protocol === Lite.ALPN_04) {
|
|
127
|
-
return new Lite.Connection({ url, quic: session, version: Lite.Version.DRAFT_04,
|
|
170
|
+
return new Lite.Connection({ url, quic: session, version: Lite.Version.DRAFT_04, ...wiring });
|
|
128
171
|
}
|
|
129
172
|
else if (protocol === Lite.ALPN_03) {
|
|
130
|
-
return new Lite.Connection({ url, quic: session, version: Lite.Version.DRAFT_03,
|
|
173
|
+
return new Lite.Connection({ url, quic: session, version: Lite.Version.DRAFT_03, ...wiring });
|
|
131
174
|
}
|
|
132
175
|
else if (protocol === Lite.ALPN || protocol === "" || protocol === undefined) {
|
|
133
176
|
setupVersion = Ietf.Version.DRAFT_14;
|
|
@@ -135,13 +178,14 @@ async function connectTransport(url, session, discovery) {
|
|
|
135
178
|
else {
|
|
136
179
|
throw new Error(`unsupported WebTransport protocol: ${protocol}`);
|
|
137
180
|
}
|
|
138
|
-
const stream = await Stream.open(session);
|
|
181
|
+
const stream = await Stream.open(session, { version: setupVersion });
|
|
139
182
|
await stream.writer.u53(Lite.StreamId.ClientCompat);
|
|
140
183
|
const encoder = new TextEncoder();
|
|
141
184
|
const params = new Ietf.SetupOptions();
|
|
142
185
|
params.setVarint(Ietf.SetupOption.MaxRequestId, 42069n);
|
|
143
186
|
params.setBytes(Ietf.SetupOption.Implementation, encoder.encode("moq-lite-js"));
|
|
144
187
|
Ietf.solicitIntoSetup(params);
|
|
188
|
+
Ietf.hiddenIntoSetup(params);
|
|
145
189
|
const client = new Ietf.ClientSetup({
|
|
146
190
|
versions: setupVersion === Ietf.Version.DRAFT_16
|
|
147
191
|
? [Ietf.Version.DRAFT_16]
|
|
@@ -162,13 +206,13 @@ async function connectTransport(url, session, discovery) {
|
|
|
162
206
|
quic: session,
|
|
163
207
|
version: server.version,
|
|
164
208
|
session: stream,
|
|
165
|
-
|
|
209
|
+
...wiring,
|
|
166
210
|
});
|
|
167
211
|
}
|
|
168
212
|
else if (Object.values(Ietf.Version).includes(server.version)) {
|
|
169
213
|
const maxRequestId = server.parameters.getVarint(Ietf.SetupOption.MaxRequestId) ?? 0n;
|
|
170
214
|
return new Ietf.Connection({
|
|
171
|
-
|
|
215
|
+
...wiring,
|
|
172
216
|
client: true,
|
|
173
217
|
url,
|
|
174
218
|
quic: session,
|
|
@@ -176,6 +220,7 @@ async function connectTransport(url, session, discovery) {
|
|
|
176
220
|
maxRequestId,
|
|
177
221
|
version: server.version,
|
|
178
222
|
solicit: Ietf.solicitFromSetup(server.parameters),
|
|
223
|
+
hidden: Ietf.hiddenFromSetup(server.parameters),
|
|
179
224
|
});
|
|
180
225
|
}
|
|
181
226
|
else {
|
|
@@ -186,15 +231,16 @@ async function connectTransport(url, session, discovery) {
|
|
|
186
231
|
* Draft-17+ client handshake. ALPN already pinned the version; SETUP is
|
|
187
232
|
* exchanged over a pair of uni streams using stream type 0x2F00.
|
|
188
233
|
*/
|
|
189
|
-
async function handshakeAlpn(url, session, version,
|
|
190
|
-
const { control, solicit, cluster } = await exchangeSetup(session, version, "moq-lite-js");
|
|
234
|
+
async function handshakeAlpn(url, session, version, wiring) {
|
|
235
|
+
const { control, solicit, hidden, cluster } = await exchangeSetup(session, version, "moq-lite-js");
|
|
191
236
|
return new Ietf.Connection({
|
|
192
|
-
|
|
237
|
+
...wiring,
|
|
193
238
|
client: true,
|
|
194
239
|
url,
|
|
195
240
|
quic: session,
|
|
196
241
|
control,
|
|
197
242
|
solicit,
|
|
243
|
+
hidden,
|
|
198
244
|
cluster,
|
|
199
245
|
// v17+ uses NativeSession which manages its own request IDs; maxRequestId is unused.
|
|
200
246
|
maxRequestId: 0n,
|
|
@@ -244,12 +290,15 @@ async function connectWebTransport(url, cancel, options) {
|
|
|
244
290
|
allowPooling: false,
|
|
245
291
|
congestionControl: "low-latency",
|
|
246
292
|
protocols: [
|
|
247
|
-
// Lite.
|
|
248
|
-
// not advertised by default (
|
|
293
|
+
// Lite.ALPN_07_WIP is intentionally omitted: lite-07 is work-in-progress and
|
|
294
|
+
// not advertised by default (negotiate still accepts it if a server selects it).
|
|
295
|
+
Lite.ALPN_06,
|
|
249
296
|
Lite.ALPN_05,
|
|
250
297
|
Lite.ALPN_04,
|
|
251
298
|
Lite.ALPN_03,
|
|
252
299
|
Lite.ALPN,
|
|
300
|
+
Ietf.ALPN.DRAFT_22,
|
|
301
|
+
Ietf.ALPN.DRAFT_21,
|
|
253
302
|
Ietf.ALPN.DRAFT_20,
|
|
254
303
|
Ietf.ALPN.DRAFT_19,
|
|
255
304
|
Ietf.ALPN.DRAFT_18,
|
|
@@ -267,11 +316,14 @@ async function connectWebTransport(url, cancel, options) {
|
|
|
267
316
|
if (url.protocol === "http:") {
|
|
268
317
|
const fingerprintUrl = new URL(url);
|
|
269
318
|
fingerprintUrl.pathname = "/certificate.sha256";
|
|
319
|
+
// The certificate endpoint is unauthenticated, so don't hand it the token.
|
|
270
320
|
fingerprintUrl.search = "";
|
|
271
321
|
// Dev-only path: http:// can't be a real WebTransport origin, so we fetch the
|
|
272
322
|
// self-signed cert's hash over plain HTTP and pin it. Production uses https://
|
|
273
323
|
// and never reaches here. Keep this at debug so it doesn't read as a problem.
|
|
274
|
-
|
|
324
|
+
if (dev()) {
|
|
325
|
+
console.debug(redact(fingerprintUrl), "performing an insecure fingerprint fetch; use https:// in production");
|
|
326
|
+
}
|
|
275
327
|
// Fetch the fingerprint from the server.
|
|
276
328
|
// TODO cancel the request if the effect is cancelled.
|
|
277
329
|
const fingerprint = await Promise.race([fetch(fingerprintUrl), cancel]);
|
|
@@ -305,18 +357,22 @@ async function connectWebSocket(url, delay, cancel) {
|
|
|
305
357
|
const active = await Promise.race([cancel, timer.then(() => true)]);
|
|
306
358
|
if (!active)
|
|
307
359
|
return undefined;
|
|
308
|
-
//
|
|
360
|
+
// moq-transport-18 and newer are pinned to qmux-01. Every other ALPN we
|
|
309
361
|
// support is currently negotiated as `qmux-00.{alpn}` on the wire, but we
|
|
310
362
|
// don't want to lock that in: set the value to `null` so the polyfill
|
|
311
363
|
// advertises every QMux draft it knows about and the server picks one.
|
|
312
364
|
// Insertion order is the negotiation preference on the wire.
|
|
313
365
|
const versions = {
|
|
314
|
-
// Lite.
|
|
366
|
+
// Lite.ALPN_07_WIP omitted on purpose: lite-07 is work-in-progress, not advertised by default.
|
|
367
|
+
[Lite.ALPN_06]: null,
|
|
315
368
|
[Lite.ALPN_05]: null,
|
|
316
369
|
[Lite.ALPN_04]: null,
|
|
317
370
|
[Lite.ALPN_03]: null,
|
|
318
371
|
[Lite.ALPN]: null,
|
|
372
|
+
[Ietf.ALPN.DRAFT_22]: "qmux-01",
|
|
373
|
+
[Ietf.ALPN.DRAFT_21]: "qmux-01",
|
|
319
374
|
[Ietf.ALPN.DRAFT_20]: "qmux-01",
|
|
375
|
+
[Ietf.ALPN.DRAFT_19]: "qmux-01",
|
|
320
376
|
[Ietf.ALPN.DRAFT_18]: "qmux-01",
|
|
321
377
|
[Ietf.ALPN.DRAFT_17]: null,
|
|
322
378
|
[Ietf.ALPN.DRAFT_16]: null,
|