summaryrefslogtreecommitdiffstats
path: root/devtools/client/netmonitor/src/components/messages/parsers/signalr
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /devtools/client/netmonitor/src/components/messages/parsers/signalr
parentInitial commit. (diff)
downloadthunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz
thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'devtools/client/netmonitor/src/components/messages/parsers/signalr')
-rw-r--r--devtools/client/netmonitor/src/components/messages/parsers/signalr/HandshakeProtocol.js82
-rw-r--r--devtools/client/netmonitor/src/components/messages/parsers/signalr/IHubProtocol.js33
-rw-r--r--devtools/client/netmonitor/src/components/messages/parsers/signalr/JSONHubProtocol.js120
-rw-r--r--devtools/client/netmonitor/src/components/messages/parsers/signalr/TextMessageFormat.js33
-rw-r--r--devtools/client/netmonitor/src/components/messages/parsers/signalr/Utils.js25
-rw-r--r--devtools/client/netmonitor/src/components/messages/parsers/signalr/index.js13
-rw-r--r--devtools/client/netmonitor/src/components/messages/parsers/signalr/moz.build12
7 files changed, 318 insertions, 0 deletions
diff --git a/devtools/client/netmonitor/src/components/messages/parsers/signalr/HandshakeProtocol.js b/devtools/client/netmonitor/src/components/messages/parsers/signalr/HandshakeProtocol.js
new file mode 100644
index 0000000000..c1c64d6717
--- /dev/null
+++ b/devtools/client/netmonitor/src/components/messages/parsers/signalr/HandshakeProtocol.js
@@ -0,0 +1,82 @@
+/*
+ * A helper class for working with SignalR handshakes.
+ *
+ * Copyright (c) .NET Foundation. All rights reserved.
+ *
+ * This source code is licensed under the Apache License, Version 2.0,
+ * found in the LICENSE.txt file in the root directory of the library
+ * source tree.
+ *
+ * https://github.com/aspnet/AspNetCore
+ */
+
+"use strict";
+
+Object.defineProperty(exports, "__esModule", { value: true });
+const TextMessageFormat = require("resource://devtools/client/netmonitor/src/components/messages/parsers/signalr/TextMessageFormat.js");
+const Utils = require("resource://devtools/client/netmonitor/src/components/messages/parsers/signalr/Utils.js");
+/** @private */
+class HandshakeProtocol {
+ // Handshake request is always JSON
+ writeHandshakeRequest(handshakeRequest) {
+ return TextMessageFormat.TextMessageFormat.write(
+ JSON.stringify(handshakeRequest)
+ );
+ }
+ parseHandshakeResponse(data) {
+ let messageData;
+ let remainingData;
+ if (
+ Utils.isArrayBuffer(data) ||
+ // eslint-disable-next-line no-undef
+ (typeof Buffer !== "undefined" && data instanceof Buffer)
+ ) {
+ // Format is binary but still need to read JSON text from handshake response
+ const binaryData = new Uint8Array(data);
+ const separatorIndex = binaryData.indexOf(
+ TextMessageFormat.TextMessageFormat.RecordSeparatorCode
+ );
+ if (separatorIndex === -1) {
+ throw new Error("Message is incomplete.");
+ }
+ // content before separator is handshake response
+ // optional content after is additional messages
+ const responseLength = separatorIndex + 1;
+ messageData = String.fromCharCode.apply(
+ null,
+ binaryData.slice(0, responseLength)
+ );
+ remainingData =
+ binaryData.byteLength > responseLength
+ ? binaryData.slice(responseLength).buffer
+ : null;
+ } else {
+ const textData = data;
+ const separatorIndex = textData.indexOf(
+ TextMessageFormat.TextMessageFormat.RecordSeparator
+ );
+ if (separatorIndex === -1) {
+ throw new Error("Message is incomplete.");
+ }
+ // content before separator is handshake response
+ // optional content after is additional messages
+ const responseLength = separatorIndex + 1;
+ messageData = textData.substring(0, responseLength);
+ remainingData =
+ textData.length > responseLength
+ ? textData.substring(responseLength)
+ : null;
+ }
+ // At this point we should have just the single handshake message
+ const messages = TextMessageFormat.TextMessageFormat.parse(messageData);
+ const response = JSON.parse(messages[0]);
+ if (response.type) {
+ throw new Error("Expected a handshake response from the server.");
+ }
+ const responseMessage = response;
+ // multiple messages could have arrived with handshake
+ // return additional data to be parsed as usual, or null if all parsed
+ return [remainingData, responseMessage];
+ }
+}
+exports.HandshakeProtocol = HandshakeProtocol;
diff --git a/devtools/client/netmonitor/src/components/messages/parsers/signalr/IHubProtocol.js b/devtools/client/netmonitor/src/components/messages/parsers/signalr/IHubProtocol.js
new file mode 100644
index 0000000000..fec2cdbff4
--- /dev/null
+++ b/devtools/client/netmonitor/src/components/messages/parsers/signalr/IHubProtocol.js
@@ -0,0 +1,33 @@
+/*
+ * A protocol abstraction for communicating with SignalR hubs.
+ *
+ * Copyright (c) .NET Foundation. All rights reserved.
+ *
+ * This source code is licensed under the Apache License, Version 2.0,
+ * found in the LICENSE.txt file in the root directory of the library
+ * source tree.
+ *
+ * https://github.com/aspnet/AspNetCore
+ */
+
+"use strict";
+
+Object.defineProperty(exports, "__esModule", { value: true });
+/** Defines the type of a Hub Message. */
+var MessageType;
+(function (_MessageType) {
+ /** Indicates the message is an Invocation message and implements the {@link @microsoft/signalr.InvocationMessage} interface. */
+ MessageType[(MessageType.Invocation = 1)] = "Invocation";
+ /** Indicates the message is a StreamItem message and implements the {@link @microsoft/signalr.StreamItemMessage} interface. */
+ MessageType[(MessageType.StreamItem = 2)] = "StreamItem";
+ /** Indicates the message is a Completion message and implements the {@link @microsoft/signalr.CompletionMessage} interface. */
+ MessageType[(MessageType.Completion = 3)] = "Completion";
+ /** Indicates the message is a Stream Invocation message and implements the {@link @microsoft/signalr.StreamInvocationMessage} interface. */
+ MessageType[(MessageType.StreamInvocation = 4)] = "StreamInvocation";
+ /** Indicates the message is a Cancel Invocation message and implements the {@link @microsoft/signalr.CancelInvocationMessage} interface. */
+ MessageType[(MessageType.CancelInvocation = 5)] = "CancelInvocation";
+ /** Indicates the message is a Ping message and implements the {@link @microsoft/signalr.PingMessage} interface. */
+ MessageType[(MessageType.Ping = 6)] = "Ping";
+ /** Indicates the message is a Close message and implements the {@link @microsoft/signalr.CloseMessage} interface. */
+ MessageType[(MessageType.Close = 7)] = "Close";
+})((MessageType = exports.MessageType || (exports.MessageType = {})));
diff --git a/devtools/client/netmonitor/src/components/messages/parsers/signalr/JSONHubProtocol.js b/devtools/client/netmonitor/src/components/messages/parsers/signalr/JSONHubProtocol.js
new file mode 100644
index 0000000000..c3648e940f
--- /dev/null
+++ b/devtools/client/netmonitor/src/components/messages/parsers/signalr/JSONHubProtocol.js
@@ -0,0 +1,120 @@
+/*
+ * Implements the SignalR Hub Protocol.
+ *
+ * Copyright (c) .NET Foundation. All rights reserved.
+ *
+ * This source code is licensed under the Apache License, Version 2.0,
+ * found in the LICENSE.txt file in the root directory of the library
+ * source tree.
+ *
+ * https://github.com/aspnet/AspNetCore
+ */
+
+"use strict";
+
+Object.defineProperty(exports, "__esModule", { value: true });
+const IHubProtocol = require("resource://devtools/client/netmonitor/src/components/messages/parsers/signalr/IHubProtocol.js");
+const TextMessageFormat = require("resource://devtools/client/netmonitor/src/components/messages/parsers/signalr/TextMessageFormat.js");
+/** Implements the JSON Hub Protocol. */
+class JsonHubProtocol {
+ /** Creates an array of {@link @microsoft/signalr.HubMessage} objects from the specified serialized representation.
+ *
+ * @param {string} input A string containing the serialized representation.
+ */
+ parseMessages(input) {
+ // The interface does allow "ArrayBuffer" to be passed in, but this implementation does not. So let's throw a useful error.
+ if (typeof input !== "string") {
+ throw new Error(
+ "Invalid input for JSON hub protocol. Expected a string."
+ );
+ }
+ if (!input) {
+ return [];
+ }
+ // Parse the messages
+ const messages = TextMessageFormat.TextMessageFormat.parse(input);
+ const hubMessages = [];
+ for (const message of messages) {
+ const parsedMessage = JSON.parse(message);
+ if (typeof parsedMessage.type !== "number") {
+ throw new Error("Invalid payload.");
+ }
+ switch (parsedMessage.type) {
+ case IHubProtocol.MessageType.Invocation:
+ this.isInvocationMessage(parsedMessage);
+ break;
+ case IHubProtocol.MessageType.StreamItem:
+ this.isStreamItemMessage(parsedMessage);
+ break;
+ case IHubProtocol.MessageType.Completion:
+ this.isCompletionMessage(parsedMessage);
+ break;
+ case IHubProtocol.MessageType.Ping:
+ // Single value, no need to validate
+ break;
+ case IHubProtocol.MessageType.Close:
+ // All optional values, no need to validate
+ break;
+ default:
+ // Future protocol changes can add message types, new kinds of messages
+ // will show up without having to update Firefox.
+ break;
+ }
+ // Map numeric message type to their textual name if it exists
+ parsedMessage.type =
+ IHubProtocol.MessageType[parsedMessage.type] || parsedMessage.type;
+ hubMessages.push(parsedMessage);
+ }
+ return hubMessages;
+ }
+ /** Writes the specified {@link @microsoft/signalr.HubMessage} to a string and returns it.
+ *
+ * @param {HubMessage} message The message to write.
+ * @returns {string} A string containing the serialized representation of the message.
+ */
+ writeMessage(message) {
+ return TextMessageFormat.TextMessageFormat.write(JSON.stringify(message));
+ }
+ isInvocationMessage(message) {
+ this.assertNotEmptyString(
+ message.target,
+ "Invalid payload for Invocation message."
+ );
+ if (message.invocationId !== undefined) {
+ this.assertNotEmptyString(
+ message.invocationId,
+ "Invalid payload for Invocation message."
+ );
+ }
+ }
+ isStreamItemMessage(message) {
+ this.assertNotEmptyString(
+ message.invocationId,
+ "Invalid payload for StreamItem message."
+ );
+ if (message.item === undefined) {
+ throw new Error("Invalid payload for StreamItem message.");
+ }
+ }
+ isCompletionMessage(message) {
+ if (message.result && message.error) {
+ throw new Error("Invalid payload for Completion message.");
+ }
+ if (!message.result && message.error) {
+ this.assertNotEmptyString(
+ message.error,
+ "Invalid payload for Completion message."
+ );
+ }
+ this.assertNotEmptyString(
+ message.invocationId,
+ "Invalid payload for Completion message."
+ );
+ }
+ assertNotEmptyString(value, errorMessage) {
+ if (typeof value !== "string" || value === "") {
+ throw new Error(errorMessage);
+ }
+ }
+}
+exports.JsonHubProtocol = JsonHubProtocol;
diff --git a/devtools/client/netmonitor/src/components/messages/parsers/signalr/TextMessageFormat.js b/devtools/client/netmonitor/src/components/messages/parsers/signalr/TextMessageFormat.js
new file mode 100644
index 0000000000..a9ec58ee36
--- /dev/null
+++ b/devtools/client/netmonitor/src/components/messages/parsers/signalr/TextMessageFormat.js
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) .NET Foundation. All rights reserved.
+ *
+ * This source code is licensed under the Apache License, Version 2.0,
+ * found in the LICENSE.txt file in the root directory of the library
+ * source tree.
+ *
+ * https://github.com/aspnet/AspNetCore
+ */
+
+"use strict";
+
+Object.defineProperty(exports, "__esModule", { value: true });
+// Not exported from index
+/** @private */
+class TextMessageFormat {
+ static write(output) {
+ return `${output}${TextMessageFormat.RecordSeparator}`;
+ }
+ static parse(input) {
+ if (input[input.length - 1] !== TextMessageFormat.RecordSeparator) {
+ throw new Error("Message is incomplete.");
+ }
+ const messages = input.split(TextMessageFormat.RecordSeparator);
+ messages.pop();
+ return messages;
+ }
+}
+exports.TextMessageFormat = TextMessageFormat;
+TextMessageFormat.RecordSeparatorCode = 0x1e;
+TextMessageFormat.RecordSeparator = String.fromCharCode(
+ TextMessageFormat.RecordSeparatorCode
+);
diff --git a/devtools/client/netmonitor/src/components/messages/parsers/signalr/Utils.js b/devtools/client/netmonitor/src/components/messages/parsers/signalr/Utils.js
new file mode 100644
index 0000000000..77b00daf45
--- /dev/null
+++ b/devtools/client/netmonitor/src/components/messages/parsers/signalr/Utils.js
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) .NET Foundation. All rights reserved.
+ *
+ * This source code is licensed under the Apache License, Version 2.0,
+ * found in the LICENSE.txt file in the root directory of the library
+ * source tree.
+ *
+ * https://github.com/aspnet/AspNetCore
+ */
+
+"use strict";
+
+Object.defineProperty(exports, "__esModule", { value: true });
+// Also in signalr-protocol-msgpack/Utils.ts
+/** @private */
+function isArrayBuffer(val) {
+ return (
+ val &&
+ typeof ArrayBuffer !== "undefined" &&
+ (val instanceof ArrayBuffer ||
+ // Sometimes we get an ArrayBuffer that doesn't satisfy instanceof
+ (val.constructor && val.constructor.name === "ArrayBuffer"))
+ );
+}
+exports.isArrayBuffer = isArrayBuffer;
diff --git a/devtools/client/netmonitor/src/components/messages/parsers/signalr/index.js b/devtools/client/netmonitor/src/components/messages/parsers/signalr/index.js
new file mode 100644
index 0000000000..927b0a0922
--- /dev/null
+++ b/devtools/client/netmonitor/src/components/messages/parsers/signalr/index.js
@@ -0,0 +1,13 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const JsonHubProtocol = require("resource://devtools/client/netmonitor/src/components/messages/parsers/signalr/JSONHubProtocol.js");
+const HandshakeProtocol = require("resource://devtools/client/netmonitor/src/components/messages/parsers/signalr/HandshakeProtocol.js");
+
+module.exports = {
+ JsonHubProtocol: JsonHubProtocol.JsonHubProtocol,
+ HandshakeProtocol: HandshakeProtocol.HandshakeProtocol,
+};
diff --git a/devtools/client/netmonitor/src/components/messages/parsers/signalr/moz.build b/devtools/client/netmonitor/src/components/messages/parsers/signalr/moz.build
new file mode 100644
index 0000000000..48329513f2
--- /dev/null
+++ b/devtools/client/netmonitor/src/components/messages/parsers/signalr/moz.build
@@ -0,0 +1,12 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DevToolsModules(
+ "HandshakeProtocol.js",
+ "IHubProtocol.js",
+ "index.js",
+ "JSONHubProtocol.js",
+ "TextMessageFormat.js",
+ "Utils.js",
+)