UNPKG

3.05 kBPlain TextView Raw
1// Copyright (c) .NET Foundation. All rights reserved.
2// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3
4import { TextMessageFormat } from "./TextMessageFormat";
5import { isArrayBuffer } from "./Utils";
6
7/** @private */
8export interface HandshakeRequestMessage {
9 readonly protocol: string;
10 readonly version: number;
11}
12
13/** @private */
14export interface HandshakeResponseMessage {
15 readonly error: string;
16 readonly minorVersion: number;
17}
18
19/** @private */
20export class HandshakeProtocol {
21 // Handshake request is always JSON
22 public writeHandshakeRequest(handshakeRequest: HandshakeRequestMessage): string {
23 return TextMessageFormat.write(JSON.stringify(handshakeRequest));
24 }
25
26 public parseHandshakeResponse(data: any): [any, HandshakeResponseMessage] {
27 let responseMessage: HandshakeResponseMessage;
28 let messageData: string;
29 let remainingData: any;
30
31 if (isArrayBuffer(data) || (typeof Buffer !== "undefined" && data instanceof Buffer)) {
32 // Format is binary but still need to read JSON text from handshake response
33 const binaryData = new Uint8Array(data);
34 const separatorIndex = binaryData.indexOf(TextMessageFormat.RecordSeparatorCode);
35 if (separatorIndex === -1) {
36 throw new Error("Message is incomplete.");
37 }
38
39 // content before separator is handshake response
40 // optional content after is additional messages
41 const responseLength = separatorIndex + 1;
42 messageData = String.fromCharCode.apply(null, binaryData.slice(0, responseLength));
43 remainingData = (binaryData.byteLength > responseLength) ? binaryData.slice(responseLength).buffer : null;
44 } else {
45 const textData: string = data;
46 const separatorIndex = textData.indexOf(TextMessageFormat.RecordSeparator);
47 if (separatorIndex === -1) {
48 throw new Error("Message is incomplete.");
49 }
50
51 // content before separator is handshake response
52 // optional content after is additional messages
53 const responseLength = separatorIndex + 1;
54 messageData = textData.substring(0, responseLength);
55 remainingData = (textData.length > responseLength) ? textData.substring(responseLength) : null;
56 }
57
58 // At this point we should have just the single handshake message
59 const messages = TextMessageFormat.parse(messageData);
60 const response = JSON.parse(messages[0]);
61 if (response.type) {
62 throw new Error("Expected a handshake response from the server.");
63 }
64 responseMessage = response;
65
66 // multiple messages could have arrived with handshake
67 // return additional data to be parsed as usual, or null if all parsed
68 return [remainingData, responseMessage];
69 }
70}