diff --git a/client-ts/Microsoft.AspNetCore.SignalR.Client.TS.Tests/Formatters.spec.ts b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS.Tests/Formatters.spec.ts index dbd43c19a1..9a5dfeb4cb 100644 --- a/client-ts/Microsoft.AspNetCore.SignalR.Client.TS.Tests/Formatters.spec.ts +++ b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS.Tests/Formatters.spec.ts @@ -1,13 +1,11 @@ import { TextMessageFormat, BinaryMessageFormat } from "../Microsoft.AspNetCore.SignalR.Client.TS/Formatters" describe("Text Message Formatter", () => { - it("should return empty array on empty input", () => { - let messages = TextMessageFormat.parse(""); - expect(messages).toEqual([]); - }); ([ - ["0:;", [""]], - ["5:Hello;", ["Hello"]], + ["\u001e", [""]], + ["\u001e\u001e", ["", ""]], + ["Hello\u001e", ["Hello"]], + ["Hello,\u001eWorld!\u001e", ["Hello,", "World!"]], ] as [[string, string[]]]).forEach(([payload, expected_messages]) => { it(`should parse '${payload}' correctly`, () => { let messages = TextMessageFormat.parse(payload); @@ -16,14 +14,9 @@ describe("Text Message Formatter", () => { }); ([ - ["ABC", new Error("Invalid length: 'ABC'")], - ["1:A;12ab34:", new Error("Invalid length: '12ab34'")], - ["1:A;1:", new Error("Message is incomplete")], - ["1:A;1:AB:", new Error("Message missing trailer character")], - ["1:A;5:A", new Error("Message is incomplete")], - ["1:A;5:AB", new Error("Message is incomplete")], - ["1:A;5:ABCDE", new Error("Message is incomplete")], - ["1:A;5:ABCDEF", new Error("Message missing trailer character")], + ["", new Error("Message is incomplete.")], + ["ABC", new Error("Message is incomplete.")], + ["ABC\u001eXYZ", new Error("Message is incomplete.")], ] as [[string, Error]]).forEach(([payload, expected_error]) => { it(`should fail to parse '${payload}'`, () => { expect(() => TextMessageFormat.parse(payload)).toThrow(expected_error); diff --git a/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/Formatters.ts b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/Formatters.ts index 5a65d14d4d..c2adfbb49f 100644 --- a/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/Formatters.ts +++ b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/Formatters.ts @@ -1,68 +1,19 @@  -function splitAt(input: string, searchString: string, position: number): [string, number] { - let index = input.indexOf(searchString, position); - if (index < 0) { - return [input.substr(position), input.length]; - } - let left = input.substring(position, index); - return [left, index + searchString.length]; -} - export namespace TextMessageFormat { - const LengthRegex = /^[0-9]+$/; - function hasSpace(input: string, offset: number, length: number): boolean { - let requiredLength = offset + length; - return input.length >= requiredLength; - } - - function parseMessage(input: string, position: number): [number, string] { - var offset = position; - - // Read the length - var [lenStr, offset] = splitAt(input, ":", offset); - - // parseInt is too leniant, we need a strict check to see if the string is an int - - if (!LengthRegex.test(lenStr)) { - throw new Error(`Invalid length: '${lenStr}'`); - } - let length = Number.parseInt(lenStr); - - // Required space is: (";") + length (payload len) - if (!hasSpace(input, offset, 1 + length)) { - throw new Error("Message is incomplete"); - } - - // Read the payload - var payload = input.substr(offset, length); - offset += length; - - // Verify the final trailing character - if (input[offset] != ';') { - throw new Error("Message missing trailer character"); - } - offset += 1; - - return [offset, payload]; - } + const RecordSeparator = String.fromCharCode(0x1e); export function write(output: string): string { - return `${output.length}:${output};`; + return `${output}${RecordSeparator}`; } export function parse(input: string): string[] { - if (input.length == 0) { - return [] + if (!input.endsWith(RecordSeparator)) { + throw new Error("Message is incomplete."); } - let messages = []; - var offset = 0; - while (offset < input.length) { - let message; - [offset, message] = parseMessage(input, offset); - messages.push(message); - } + let messages = input.split(RecordSeparator); + messages.pop(); return messages; } } diff --git a/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/hubConnectionTests.js b/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/hubConnectionTests.js index 5d13aa36a8..a66ef4ea45 100644 --- a/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/hubConnectionTests.js +++ b/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/hubConnectionTests.js @@ -4,7 +4,7 @@ describe('hubConnection', () => { eachTransportAndProtocol((transportType, protocol) => { describe(`${protocol.name} over ${signalR.TransportType[transportType]} transport`, () => { it(`can invoke server method and receive result`, done => { - const message = "Hi"; + const message = "你好,世界!"; let hubConnection = new signalR.HubConnection( new signalR.HttpConnection(TESTHUBENDPOINT_URL, { transport: transportType }), protocol); hubConnection.onClosed = error => { @@ -122,7 +122,7 @@ describe('hubConnection', () => { it(`can receive server calls`, done => { let client = new signalR.HubConnection( new signalR.HttpConnection(TESTHUBENDPOINT_URL, { transport: transportType }), protocol); - const message = "Hello SignalR"; + const message = "你好 SignalR!"; let callbackPromise = new Promise((resolve, reject) => { client.on("Message", msg => {