microsoft/vscode-react-native

Public

mirrored from https://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
smoke-actionbar-timeout-assertion

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

src/cdp-proxy/reactNativeCDPProxy.ts

227lines · modeblame

f872f4d5RedMickey6 years ago1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for details.
3
09f6024fHeniker4 years ago4import { IncomingMessage } from "http";
f872f4d5RedMickey6 years ago5import {
6Connection,
7Server,
8WebSocketTransport,
9IProtocolCommand,
10IProtocolError,
34472878RedMickey5 years ago11IProtocolSuccess,
f872f4d5RedMickey6 years ago12} from "vscode-cdp-proxy";
19df32dcRedMickey4 years ago13import { CancellationToken, EventEmitter } from "vscode";
f872f4d5RedMickey6 years ago14import { OutputChannelLogger } from "../extension/log/OutputChannelLogger";
a324603aRedMickey6 years ago15import { LogLevel } from "../extension/log/LogHelper";
d9c9ddcbRedMickey6 years ago16import { DebuggerEndpointHelper } from "./debuggerEndpointHelper";
259c018fYuri Skorokhodov5 years ago17import { BaseCDPMessageHandler } from "./CDPMessageHandlers/baseCDPMessageHandler";
f872f4d5RedMickey6 years ago18
19export class ReactNativeCDPProxy {
a324603aRedMickey6 years ago20private readonly PROXY_LOG_TAGS = {
21DEBUGGER_COMMAND: "Command Debugger To Target",
22APPLICATION_COMMAND: "Command Target To Debugger",
23DEBUGGER_REPLY: "Reply From Debugger To Target",
24APPLICATION_REPLY: "Reply From Target To Debugger",
25};
26
176f99c8ConnorQi013 months ago27private server: Server | null = null;
d9c9ddcbRedMickey6 years ago28private hostAddress: string;
29private port: number;
176f99c8ConnorQi013 months ago30private debuggerTarget: Connection | null = null;
31private applicationTarget: Connection | null = null;
d9c9ddcbRedMickey6 years ago32private logger: OutputChannelLogger;
33private logLevel: LogLevel;
34private debuggerEndpointHelper: DebuggerEndpointHelper;
176f99c8ConnorQi013 months ago35private CDPMessageHandler!: BaseCDPMessageHandler;
36private applicationTargetPort: number = 0;
984ca036RedMickey6 years ago37private browserInspectUri: string;
e23d1841RedMickey6 years ago38private cancellationToken: CancellationToken | undefined;
19df32dcRedMickey4 years ago39private applicationTargetEventEmitter: EventEmitter<unknown> = new EventEmitter();
9f8c460dEzio Li2 years ago40private errorEventEmitter: EventEmitter<Error> = new EventEmitter();
19df32dcRedMickey4 years ago41
9f8c460dEzio Li2 years ago42public readonly onError = this.errorEventEmitter.event;
19df32dcRedMickey4 years ago43public readonly onApplicationTargetConnectionClosed = this.applicationTargetEventEmitter.event;
d9c9ddcbRedMickey6 years ago44
a6562589RedMickey6 years ago45constructor(hostAddress: string, port: number, logLevel: LogLevel = LogLevel.None) {
f872f4d5RedMickey6 years ago46this.port = port;
47this.hostAddress = hostAddress;
34472878RedMickey5 years ago48this.logger = OutputChannelLogger.getChannel(
49"React Native Chrome Proxy",
09f6024fHeniker4 years ago50process.env.REACT_NATIVE_TOOLS_LAZY_LOGS !== "false",
34472878RedMickey5 years ago51false,
52true,
53);
f872f4d5RedMickey6 years ago54this.logLevel = logLevel;
984ca036RedMickey6 years ago55this.browserInspectUri = "";
d9c9ddcbRedMickey6 years ago56this.debuggerEndpointHelper = new DebuggerEndpointHelper();
f872f4d5RedMickey6 years ago57}
58
0d77292aJiglioNero4 years ago59public async initializeServer(
259c018fYuri Skorokhodov5 years ago60CDPMessageHandler: BaseCDPMessageHandler,
e23d1841RedMickey6 years ago61logLevel: LogLevel,
34472878RedMickey5 years ago62cancellationToken?: CancellationToken,
e23d1841RedMickey6 years ago63): Promise<void> {
a6562589RedMickey6 years ago64this.logLevel = logLevel;
65this.CDPMessageHandler = CDPMessageHandler;
e23d1841RedMickey6 years ago66this.cancellationToken = cancellationToken;
a6562589RedMickey6 years ago67
0d77292aJiglioNero4 years ago68this.server = await Server.create({ port: this.port, host: this.hostAddress });
69this.server.onConnection(this.onConnectionHandler.bind(this));
f872f4d5RedMickey6 years ago70}
71
984ca036RedMickey6 years ago72public async stopServer(): Promise<void> {
f872f4d5RedMickey6 years ago73if (this.server) {
74this.server.dispose();
75this.server = null;
76}
984ca036RedMickey6 years ago77
78if (this.applicationTarget) {
79await this.applicationTarget.close();
80this.applicationTarget = null;
81}
82
83this.browserInspectUri = "";
e23d1841RedMickey6 years ago84this.cancellationToken = undefined;
984ca036RedMickey6 years ago85}
86
34472878RedMickey5 years ago87public setBrowserInspectUri(browserInspectUri: string): void {
984ca036RedMickey6 years ago88this.browserInspectUri = browserInspectUri;
f872f4d5RedMickey6 years ago89}
90
d9c9ddcbRedMickey6 years ago91public setApplicationTargetPort(applicationTargetPort: number): void {
92this.applicationTargetPort = applicationTargetPort;
f872f4d5RedMickey6 years ago93}
94
34472878RedMickey5 years ago95// eslint-disable-next-line @typescript-eslint/no-unused-vars
96private async onConnectionHandler([debuggerTarget, request]: [
97Connection,
98IncomingMessage,
99]): Promise<void> {
f665013bLucy Gramley1 months ago100// Only allow connections without an Origin header (i.e., from vscode-js-debug's
101// raw WebSocket client). Browser-initiated WebSocket connections always include
102// an Origin header and should be rejected.
103if (request.headers.origin) {
c37dc1d6lucygramley1 months ago104await debuggerTarget.close();
f665013bLucy Gramley1 months ago105return;
106}
107
f872f4d5RedMickey6 years ago108this.debuggerTarget = debuggerTarget;
109
110this.debuggerTarget.pause(); // don't listen for events until the target is ready
111
984ca036RedMickey6 years ago112if (!this.browserInspectUri) {
e23d1841RedMickey6 years ago113if (this.cancellationToken) {
114this.browserInspectUri = await this.debuggerEndpointHelper.retryGetWSEndpoint(
115`http://localhost:${this.applicationTargetPort}`,
11690,
34472878RedMickey5 years ago117this.cancellationToken,
e23d1841RedMickey6 years ago118);
119} else {
34472878RedMickey5 years ago120this.browserInspectUri = await this.debuggerEndpointHelper.getWSEndpoint(
121`http://localhost:${this.applicationTargetPort}`,
122);
e23d1841RedMickey6 years ago123}
984ca036RedMickey6 years ago124}
d9c9ddcbRedMickey6 years ago125
34472878RedMickey5 years ago126this.applicationTarget = new Connection(
127await WebSocketTransport.create(this.browserInspectUri),
128);
f872f4d5RedMickey6 years ago129
130this.applicationTarget.onError(this.onApplicationTargetError.bind(this));
131this.debuggerTarget.onError(this.onDebuggerTargetError.bind(this));
132
133this.applicationTarget.onCommand(this.handleApplicationTargetCommand.bind(this));
134this.debuggerTarget.onCommand(this.handleDebuggerTargetCommand.bind(this));
135
136this.applicationTarget.onReply(this.handleApplicationTargetReply.bind(this));
137this.debuggerTarget.onReply(this.handleDebuggerTargetReply.bind(this));
138
ebbd64f1RedMickey6 years ago139this.applicationTarget.onEnd(this.onApplicationTargetClosed.bind(this));
4c757eebRedMickey6 years ago140this.debuggerTarget.onEnd(this.onDebuggerTargetClosed.bind(this));
af1b9666RedMickey6 years ago141
259c018fYuri Skorokhodov5 years ago142this.CDPMessageHandler?.setApplicationTarget(this.applicationTarget);
143this.CDPMessageHandler?.setDebuggerTarget(this.debuggerTarget);
144
f872f4d5RedMickey6 years ago145// dequeue any messages we got in the meantime
146this.debuggerTarget.unpause();
147}
148
b7451aefRedMickey6 years ago149private handleDebuggerTargetCommand(event: IProtocolCommand) {
34472878RedMickey5 years ago150this.logger.logWithCustomTag(
151this.PROXY_LOG_TAGS.DEBUGGER_COMMAND,
152JSON.stringify(event, null, 2),
153this.logLevel,
154);
b7451aefRedMickey6 years ago155const processedMessage = this.CDPMessageHandler.processDebuggerCDPMessage(event);
156
157if (processedMessage.sendBack) {
ebbd64f1RedMickey6 years ago158this.debuggerTarget?.send(processedMessage.event);
b7451aefRedMickey6 years ago159} else {
984ca036RedMickey6 years ago160this.applicationTarget?.send(processedMessage.event);
b7451aefRedMickey6 years ago161}
f872f4d5RedMickey6 years ago162}
163
b7451aefRedMickey6 years ago164private handleApplicationTargetCommand(event: IProtocolCommand) {
34472878RedMickey5 years ago165this.logger.logWithCustomTag(
166this.PROXY_LOG_TAGS.APPLICATION_COMMAND,
167JSON.stringify(event, null, 2),
168this.logLevel,
169);
b7451aefRedMickey6 years ago170const processedMessage = this.CDPMessageHandler.processApplicationCDPMessage(event);
171
172if (processedMessage.sendBack) {
984ca036RedMickey6 years ago173this.applicationTarget?.send(processedMessage.event);
b7451aefRedMickey6 years ago174} else {
ebbd64f1RedMickey6 years ago175this.debuggerTarget?.send(processedMessage.event);
b7451aefRedMickey6 years ago176}
f872f4d5RedMickey6 years ago177}
178
b7451aefRedMickey6 years ago179private handleDebuggerTargetReply(event: IProtocolError | IProtocolSuccess) {
34472878RedMickey5 years ago180this.logger.logWithCustomTag(
181this.PROXY_LOG_TAGS.DEBUGGER_REPLY,
182JSON.stringify(event, null, 2),
183this.logLevel,
184);
b7451aefRedMickey6 years ago185const processedMessage = this.CDPMessageHandler.processDebuggerCDPMessage(event);
186
187if (processedMessage.sendBack) {
ebbd64f1RedMickey6 years ago188this.debuggerTarget?.send(processedMessage.event);
b7451aefRedMickey6 years ago189} else {
984ca036RedMickey6 years ago190this.applicationTarget?.send(processedMessage.event);
b7451aefRedMickey6 years ago191}
f872f4d5RedMickey6 years ago192}
193
b7451aefRedMickey6 years ago194private handleApplicationTargetReply(event: IProtocolError | IProtocolSuccess) {
34472878RedMickey5 years ago195this.logger.logWithCustomTag(
196this.PROXY_LOG_TAGS.APPLICATION_REPLY,
197JSON.stringify(event, null, 2),
198this.logLevel,
199);
b7451aefRedMickey6 years ago200const processedMessage = this.CDPMessageHandler.processApplicationCDPMessage(event);
201
202if (processedMessage.sendBack) {
984ca036RedMickey6 years ago203this.applicationTarget?.send(processedMessage.event);
b7451aefRedMickey6 years ago204} else {
ebbd64f1RedMickey6 years ago205this.debuggerTarget?.send(processedMessage.event);
b7451aefRedMickey6 years ago206}
f872f4d5RedMickey6 years ago207}
208
209private onDebuggerTargetError(err: Error) {
a324603aRedMickey6 years ago210this.logger.error("Error on debugger transport", err);
f872f4d5RedMickey6 years ago211}
212
213private onApplicationTargetError(err: Error) {
a324603aRedMickey6 years ago214this.logger.error("Error on application transport", err);
f872f4d5RedMickey6 years ago215}
216
ebbd64f1RedMickey6 years ago217private async onApplicationTargetClosed() {
218this.applicationTarget = null;
19df32dcRedMickey4 years ago219this.applicationTargetEventEmitter.fire({});
ebbd64f1RedMickey6 years ago220}
221
4c757eebRedMickey6 years ago222private async onDebuggerTargetClosed() {
984ca036RedMickey6 years ago223this.browserInspectUri = "";
34472878RedMickey5 years ago224this.CDPMessageHandler.processDebuggerCDPMessage({ method: "close" });
ebbd64f1RedMickey6 years ago225this.debuggerTarget = null;
af1b9666RedMickey6 years ago226}
f872f4d5RedMickey6 years ago227}