60 lines
2.2 KiB
TypeScript
60 lines
2.2 KiB
TypeScript
// Copyright (c) .NET Foundation. All rights reserved.
|
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
|
|
import { IHubProtocol, HubMessage, ProtocolType } from "./IHubProtocol"
|
|
|
|
export class Base64EncodedHubProtocol implements IHubProtocol {
|
|
private wrappedProtocol: IHubProtocol;
|
|
|
|
constructor(protocol: IHubProtocol) {
|
|
this.wrappedProtocol = protocol;
|
|
this.name = this.wrappedProtocol.name;
|
|
this.type = ProtocolType.Text;
|
|
}
|
|
|
|
readonly name: string;
|
|
readonly type: ProtocolType;
|
|
|
|
parseMessages(input: any): HubMessage[] {
|
|
// The format of the message is `size:message;`
|
|
let pos = input.indexOf(":");
|
|
if (pos == -1 || input[input.length - 1] != ';') {
|
|
throw new Error("Invalid payload.");
|
|
}
|
|
|
|
let lenStr = input.substring(0, pos);
|
|
if (!/^[0-9]+$/.test(lenStr)) {
|
|
throw new Error(`Invalid length: '${lenStr}'`);
|
|
}
|
|
|
|
let messageSize = parseInt(lenStr, 10);
|
|
// 2 accounts for ':' after message size and trailing ';'
|
|
if (messageSize != input.length - pos - 2) {
|
|
throw new Error("Invalid message size.");
|
|
}
|
|
|
|
let encodedMessage = input.substring(pos + 1, input.length - 1);
|
|
|
|
// atob/btoa are browsers APIs but they can be polyfilled. If this becomes problematic we can use
|
|
// base64-js module
|
|
let s = atob(encodedMessage);
|
|
let payload = new Uint8Array(s.length);
|
|
for (let i = 0; i < payload.length; i++) {
|
|
payload[i] = s.charCodeAt(i);
|
|
}
|
|
return this.wrappedProtocol.parseMessages(payload.buffer);
|
|
}
|
|
|
|
writeMessage(message: HubMessage): any {
|
|
let payload = new Uint8Array(this.wrappedProtocol.writeMessage(message));
|
|
let s = "";
|
|
for (let i = 0; i < payload.byteLength; i++) {
|
|
s += String.fromCharCode(payload[i]);
|
|
}
|
|
// atob/btoa are browsers APIs but they can be polyfilled. If this becomes problematic we can use
|
|
// base64-js module
|
|
let encodedMessage = btoa(s);
|
|
|
|
return `${encodedMessage.length.toString()}:${encodedMessage};`;
|
|
}
|
|
} |