mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Merge pull request #19218 from Napalys/js/upgrade_websocket
JS: Refactor `WebSocket` to use `API` graphs
This commit is contained in:
5
javascript/ql/lib/change-notes/2025-04-07-websocket.md
Normal file
5
javascript/ql/lib/change-notes/2025-04-07-websocket.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Improved detection of `WebSocket` and `SockJS` usage.
|
||||
* Added data received from `WebSocket` clients as a remote flow source.
|
||||
@@ -47,6 +47,20 @@ private predicate areLibrariesCompatible(
|
||||
(client = LibraryNames::ws() or client = LibraryNames::websocket())
|
||||
}
|
||||
|
||||
/** Treats `WebSocket` as an entry point for API graphs. */
|
||||
private class WebSocketEntryPoint extends API::EntryPoint {
|
||||
WebSocketEntryPoint() { this = "global.WebSocket" }
|
||||
|
||||
override DataFlow::SourceNode getASource() { result = DataFlow::globalVarRef("WebSocket") }
|
||||
}
|
||||
|
||||
/** Treats `SockJS` as an entry point for API graphs. */
|
||||
private class SockJSEntryPoint extends API::EntryPoint {
|
||||
SockJSEntryPoint() { this = "global.SockJS" }
|
||||
|
||||
override DataFlow::SourceNode getASource() { result = DataFlow::globalVarRef("SockJS") }
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides classes that model WebSockets clients.
|
||||
*/
|
||||
@@ -56,7 +70,7 @@ module ClientWebSocket {
|
||||
/**
|
||||
* A class that can be used to instantiate a WebSocket instance.
|
||||
*/
|
||||
class SocketClass extends DataFlow::SourceNode {
|
||||
deprecated class SocketClass extends DataFlow::SourceNode {
|
||||
LibraryName library; // the name of the WebSocket library. Can be one of the libraries defined in `LibraryNames`.
|
||||
|
||||
SocketClass() {
|
||||
@@ -78,13 +92,38 @@ module ClientWebSocket {
|
||||
LibraryName getLibrary() { result = library }
|
||||
}
|
||||
|
||||
/**
|
||||
* A class that can be used to instantiate a WebSocket instance.
|
||||
*/
|
||||
class WebSocketClass extends API::Node {
|
||||
LibraryName library; // the name of the WebSocket library. Can be one of the libraries defined in `LibraryNames`.
|
||||
|
||||
WebSocketClass() {
|
||||
this = any(WebSocketEntryPoint e).getANode() and library = websocket()
|
||||
or
|
||||
this = API::moduleImport("ws") and library = ws()
|
||||
or
|
||||
// the sockjs-client library:https://www.npmjs.com/package/sockjs-client
|
||||
library = sockjs() and
|
||||
(
|
||||
this = API::moduleImport("sockjs-client") or
|
||||
this = any(SockJSEntryPoint e).getANode()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the WebSocket library name.
|
||||
*/
|
||||
LibraryName getLibrary() { result = library }
|
||||
}
|
||||
|
||||
/**
|
||||
* A client WebSocket instance.
|
||||
*/
|
||||
class ClientSocket extends EventEmitter::Range, DataFlow::NewNode, ClientRequest::Range {
|
||||
SocketClass socketClass;
|
||||
class ClientSocket extends EventEmitter::Range, API::NewNode, ClientRequest::Range {
|
||||
WebSocketClass socketClass;
|
||||
|
||||
ClientSocket() { this = socketClass.getAnInstantiation() }
|
||||
ClientSocket() { this = socketClass.getAnInvocation() }
|
||||
|
||||
/**
|
||||
* Gets the WebSocket library name.
|
||||
@@ -115,10 +154,10 @@ module ClientWebSocket {
|
||||
/**
|
||||
* A message sent from a WebSocket client.
|
||||
*/
|
||||
class SendNode extends EventDispatch::Range, DataFlow::CallNode {
|
||||
class SendNode extends EventDispatch::Range, API::CallNode {
|
||||
override ClientSocket emitter;
|
||||
|
||||
SendNode() { this = emitter.getAMemberCall("send") }
|
||||
SendNode() { this = emitter.getReturn().getMember("send").getACall() }
|
||||
|
||||
override string getChannel() { result = channelName() }
|
||||
|
||||
@@ -145,8 +184,8 @@ module ClientWebSocket {
|
||||
private DataFlow::FunctionNode getAMessageHandler(
|
||||
ClientWebSocket::ClientSocket emitter, string methodName
|
||||
) {
|
||||
exists(DataFlow::CallNode call |
|
||||
call = emitter.getAMemberCall(methodName) and
|
||||
exists(API::CallNode call |
|
||||
call = emitter.getReturn().getMember(methodName).getACall() and
|
||||
call.getArgument(0).mayHaveStringValue("message") and
|
||||
result = call.getCallback(1)
|
||||
)
|
||||
@@ -161,7 +200,13 @@ module ClientWebSocket {
|
||||
WebSocketReceiveNode() {
|
||||
this = getAMessageHandler(emitter, "addEventListener")
|
||||
or
|
||||
this = emitter.getAPropertyWrite("onmessage").getRhs()
|
||||
this = emitter.getReturn().getMember("onmessage").getAValueReachingSink()
|
||||
or
|
||||
exists(DataFlow::MethodCallNode bindCall |
|
||||
bindCall = emitter.getReturn().getMember("onmessage").getAValueReachingSink() and
|
||||
bindCall.getMethodName() = "bind" and
|
||||
this = bindCall.getReceiver().getAFunctionValue()
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getReceivedItem(int i) {
|
||||
@@ -192,7 +237,7 @@ module ServerWebSocket {
|
||||
/**
|
||||
* Gets a server created by a library named `library`.
|
||||
*/
|
||||
DataFlow::SourceNode getAServer(LibraryName library) {
|
||||
deprecated DataFlow::SourceNode getAServer(LibraryName library) {
|
||||
library = ws() and
|
||||
result = DataFlow::moduleImport("ws").getAConstructorInvocation("Server")
|
||||
or
|
||||
@@ -200,11 +245,22 @@ module ServerWebSocket {
|
||||
result = DataFlow::moduleImport("sockjs").getAMemberCall("createServer")
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a server created by a library named `library`.
|
||||
*/
|
||||
API::InvokeNode getAServerInvocation(LibraryName library) {
|
||||
library = ws() and
|
||||
result = API::moduleImport("ws").getMember("Server").getAnInvocation()
|
||||
or
|
||||
library = sockjs() and
|
||||
result = API::moduleImport("sockjs").getMember("createServer").getAnInvocation()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a `socket.on("connection", (msg, req) => {})` call.
|
||||
*/
|
||||
private DataFlow::CallNode getAConnectionCall(LibraryName library) {
|
||||
result = getAServer(library).getAMemberCall(EventEmitter::on()) and
|
||||
result = getAServerInvocation(library).getReturn().getMember(EventEmitter::on()).getACall() and
|
||||
result.getArgument(0).mayHaveStringValue("connection")
|
||||
}
|
||||
|
||||
@@ -324,15 +380,18 @@ module ServerWebSocket {
|
||||
result = this.getCallback(1).getParameter(0)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow node representing data received from a client, viewed as remote user input.
|
||||
*/
|
||||
private class ReceivedItemAsRemoteFlow extends RemoteFlowSource {
|
||||
ReceivedItemAsRemoteFlow() { this = any(ReceiveNode rercv).getReceivedItem(_) }
|
||||
|
||||
override string getSourceType() { result = "WebSocket client data" }
|
||||
|
||||
override predicate isUserControlledObject() { any() }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow node representing data received from a client or server, viewed as remote user input.
|
||||
*/
|
||||
private class ReceivedItemAsRemoteFlow extends RemoteFlowSource {
|
||||
ReceivedItemAsRemoteFlow() {
|
||||
this = any(ClientWebSocket::ReceiveNode rercv).getReceivedItem(_) or
|
||||
this = any(ServerWebSocket::ReceiveNode rercv).getReceivedItem(_)
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "WebSocket transmitted data" }
|
||||
|
||||
override predicate isUserControlledObject() { any() }
|
||||
}
|
||||
|
||||
10
javascript/ql/src/Security/trest/test.ql
Normal file
10
javascript/ql/src/Security/trest/test.ql
Normal file
@@ -0,0 +1,10 @@
|
||||
import javascript
|
||||
|
||||
API::NewNode getAWebSocketInstance() { result instanceof ClientWebSocket::ClientSocket }
|
||||
|
||||
from DataFlow::Node handler
|
||||
where
|
||||
handler = getAWebSocketInstance().getReturn().getMember("onmessage").asSource()
|
||||
or
|
||||
handler = getAWebSocketInstance().getAPropertyWrite("onmessage").getRhs()
|
||||
select handler, "This is a WebSocket onmessage handler."
|
||||
@@ -0,0 +1,74 @@
|
||||
import { MyWebSocket, MySockJS, myWebSocketInstance, mySockJSInstance } from './browser.js';
|
||||
|
||||
(function () {
|
||||
const socket = new MyWebSocket('ws://localhost:9080'); // $ clientSocket
|
||||
|
||||
socket.addEventListener('open', function (event) {
|
||||
socket.send('Hi from browser!'); // $ clientSend
|
||||
});
|
||||
|
||||
socket.addEventListener('message', function (event) {
|
||||
console.log('Message from server ', event.data); // $ remoteFlow
|
||||
}); // $ clientReceive
|
||||
|
||||
socket.onmessage = function (event) {
|
||||
console.log("Message from server 2", event.data); // $ remoteFlow
|
||||
}; // $ clientReceive
|
||||
})();
|
||||
|
||||
|
||||
(function () {
|
||||
var sock = new MySockJS('http://0.0.0.0:9999/echo'); // $ clientSocket
|
||||
sock.onopen = function () {
|
||||
sock.send('test'); // $ clientSend
|
||||
};
|
||||
|
||||
sock.onmessage = function (e) {
|
||||
console.log('message', e.data); // $ remoteFlow
|
||||
sock.close();
|
||||
}; // $ clientReceive
|
||||
|
||||
sock.addEventListener('message', function (event) {
|
||||
console.log('Using addEventListener ', event.data); // $ remoteFlow
|
||||
}); // $ clientReceive
|
||||
})();
|
||||
|
||||
|
||||
(function () {
|
||||
myWebSocketInstance.addEventListener('open', function (event) {
|
||||
myWebSocketInstance.send('Hi from browser!'); // $ clientSend
|
||||
});
|
||||
|
||||
myWebSocketInstance.addEventListener('message', function (event) {
|
||||
console.log('Message from server ', event.data); // $ remoteFlow
|
||||
}); // $ clientReceive
|
||||
|
||||
myWebSocketInstance.onmessage = function (event) {
|
||||
console.log("Message from server 2", event.data); // $ remoteFlow
|
||||
}; // $ clientReceive
|
||||
})();
|
||||
|
||||
|
||||
(function () {
|
||||
mySockJSInstance.onopen = function () {
|
||||
mySockJSInstance.send('test'); // $ clientSend
|
||||
};
|
||||
|
||||
mySockJSInstance.onmessage = function (e) {
|
||||
console.log('message', e.data); // $ remoteFlow
|
||||
mySockJSInstance.close();
|
||||
}; // $ clientReceive
|
||||
|
||||
mySockJSInstance.addEventListener('message', function (event) {
|
||||
console.log('Using addEventListener ', event.data); // $ remoteFlow
|
||||
}); // $ clientReceive
|
||||
})();
|
||||
|
||||
|
||||
const recv_message = function (e) {
|
||||
console.log('Received message:', e.data); // $ remoteFlow
|
||||
}; // $ clientReceive
|
||||
|
||||
(function () {
|
||||
myWebSocketInstance.onmessage = recv_message.bind(this);
|
||||
})();
|
||||
@@ -1,32 +1,37 @@
|
||||
(function () {
|
||||
const socket = new WebSocket('ws://localhost:8080');
|
||||
const socket = new WebSocket('ws://localhost:8080'); // $clientSocket
|
||||
|
||||
socket.addEventListener('open', function (event) {
|
||||
socket.send('Hi from browser!');
|
||||
socket.send('Hi from browser!'); // $clientSend
|
||||
});
|
||||
|
||||
socket.addEventListener('message', function (event) {
|
||||
console.log('Message from server ', event.data);
|
||||
});
|
||||
console.log('Message from server ', event.data); // $ remoteFlow
|
||||
}); // $clientReceive
|
||||
|
||||
socket.onmessage = function (event) {
|
||||
console.log("Message from server 2", event.data)
|
||||
};
|
||||
console.log("Message from server 2", event.data); // $ remoteFlow
|
||||
}; // $clientReceive
|
||||
})();
|
||||
|
||||
|
||||
(function () {
|
||||
var sock = new SockJS('http://0.0.0.0:9999/echo');
|
||||
var sock = new SockJS('http://0.0.0.0:9999/echo'); // $clientSocket
|
||||
sock.onopen = function () {
|
||||
sock.send('test');
|
||||
sock.send('test'); // $clientSend
|
||||
};
|
||||
|
||||
sock.onmessage = function (e) {
|
||||
console.log('message', e.data);
|
||||
console.log('message', e.data); // $ remoteFlow
|
||||
sock.close();
|
||||
};
|
||||
}; // $clientReceive
|
||||
|
||||
sock.addEventListener('message', function (event) {
|
||||
console.log('Using addEventListener ', event.data);
|
||||
});
|
||||
})
|
||||
console.log('Using addEventListener ', event.data); // $ remoteFlow
|
||||
}); // $clientReceive
|
||||
})();
|
||||
|
||||
export const MyWebSocket = WebSocket;
|
||||
export const MySockJS = SockJS;
|
||||
export const myWebSocketInstance = new WebSocket('ws://localhost:8080'); // $ clientSocket
|
||||
export const mySockJSInstance = new SockJS('http://0.0.0.0:9999/echo'); // $ clientSocket
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
const { MyWebSocketWS, myWebSocketWSInstance } = require('./client.js');
|
||||
|
||||
(function () {
|
||||
const ws = new MyWebSocketWS('ws://example.org'); // $ clientSocket
|
||||
|
||||
ws.on('open', function open() {
|
||||
ws.send('Hi from client!'); // $ clientSend
|
||||
});
|
||||
|
||||
ws.on('message', function incoming(data) { // $ remoteFlow
|
||||
console.log(data);
|
||||
}); // $ clientReceive
|
||||
})();
|
||||
|
||||
(function () {
|
||||
myWebSocketWSInstance.on('open', function open() {
|
||||
myWebSocketWSInstance.send('Hi from client!'); // $ clientSend
|
||||
});
|
||||
|
||||
myWebSocketWSInstance.on('message', function incoming(data) { // $ remoteFlow
|
||||
console.log(data);
|
||||
}); // $ clientReceive
|
||||
})();
|
||||
@@ -1,13 +1,16 @@
|
||||
(function () {
|
||||
const WebSocket = require('ws');
|
||||
const WebSocket = require('ws');
|
||||
|
||||
const ws = new WebSocket('ws://example.org');
|
||||
(function () {
|
||||
const ws = new WebSocket('ws://example.org'); // $clientSocket
|
||||
|
||||
ws.on('open', function open() {
|
||||
ws.send('Hi from client!');
|
||||
ws.send('Hi from client!'); // $clientSend
|
||||
});
|
||||
|
||||
ws.on('message', function incoming(data) {
|
||||
ws.on('message', function incoming(data) { // $ remoteFlow
|
||||
console.log(data);
|
||||
});
|
||||
})();
|
||||
}); // $clientReceive
|
||||
})();
|
||||
|
||||
module.exports.MyWebSocketWS = require('ws');
|
||||
module.exports.myWebSocketWSInstance = new WebSocket('ws://example.org'); // $ clientSocket
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
const { MyWebSocketServer, myWebSocketServerInstance } = require('./server.js');
|
||||
|
||||
(function () {
|
||||
const wss = new MyWebSocketServer({ port: 8080 });
|
||||
|
||||
wss.on('connection', function connection(ws) { // $ serverSocket
|
||||
ws.on('message', function incoming(message) { // $ remoteFlow
|
||||
console.log('received: %s', message);
|
||||
}); // $ serverReceive
|
||||
|
||||
ws.send('Hi from server!'); // $ serverSend
|
||||
});
|
||||
})();
|
||||
|
||||
(function () {
|
||||
myWebSocketServerInstance.on('connection', function connection(ws) { // $ serverSocket
|
||||
ws.on('message', function incoming(message) { // $ remoteFlow
|
||||
console.log('received: %s', message);
|
||||
}); // $ serverReceive
|
||||
|
||||
ws.send('Hi from server!'); // $ serverSend
|
||||
});
|
||||
})();
|
||||
@@ -1,13 +1,16 @@
|
||||
(function () {
|
||||
const WebSocket = require('ws');
|
||||
const WebSocket = require('ws');
|
||||
|
||||
(function () {
|
||||
const wss = new WebSocket.Server({ port: 8080 });
|
||||
|
||||
wss.on('connection', function connection(ws) {
|
||||
ws.on('message', function incoming(message) {
|
||||
wss.on('connection', function connection(ws) { // $serverSocket
|
||||
ws.on('message', function incoming(message) { // $remoteFlow
|
||||
console.log('received: %s', message);
|
||||
});
|
||||
}); // $serverReceive
|
||||
|
||||
ws.send('Hi from server!');
|
||||
ws.send('Hi from server!'); // $serverSend
|
||||
});
|
||||
})();
|
||||
})();
|
||||
|
||||
module.exports.MyWebSocketServer = require('ws').Server;
|
||||
module.exports.myWebSocketServerInstance = new WebSocket.Server({ port: 8080 });
|
||||
|
||||
@@ -5,11 +5,11 @@ const sockjs = require('sockjs');
|
||||
const app = express();
|
||||
const server = http.createServer(app);
|
||||
const sockjs_echo = sockjs.createServer({});
|
||||
sockjs_echo.on('connection', function (conn) {
|
||||
conn.on('data', function (message) {
|
||||
sockjs_echo.on('connection', function (conn) { // $serverSocket
|
||||
conn.on('data', function (message) { // $remoteFlow
|
||||
var data = JSON.parse(message);
|
||||
conn.write(JSON.stringify(eval(data.test)));
|
||||
});
|
||||
conn.write(JSON.stringify(eval(data.test))); // $serverSend
|
||||
}); // $serverReceive
|
||||
});
|
||||
|
||||
sockjs_echo.installHandlers(server, { prefix: '/echo' });
|
||||
|
||||
@@ -1,35 +1,139 @@
|
||||
clientSocket
|
||||
| browser.js:2:17:2:52 | new Web ... :8080') |
|
||||
| browser.js:19:13:19:50 | new Soc ... /echo') |
|
||||
| client.js:4:13:4:45 | new Web ... e.org') |
|
||||
clientReceive
|
||||
| browser-custom.js:10:37:12:2 | functio ... Flow\\n\\t} |
|
||||
| browser-custom.js:14:21:16:2 | functio ... Flow\\n\\t} |
|
||||
| browser-custom.js:26:19:29:2 | functio ... e();\\n\\t} |
|
||||
| browser-custom.js:31:35:33:2 | functio ... Flow\\n\\t} |
|
||||
| browser-custom.js:42:53:44:5 | functio ... w\\n } |
|
||||
| browser-custom.js:46:37:48:5 | functio ... w\\n } |
|
||||
| browser-custom.js:57:34:60:5 | functio ... ;\\n } |
|
||||
| browser-custom.js:62:50:64:5 | functio ... w\\n } |
|
||||
| browser-custom.js:68:22:70:1 | functio ... eFlow\\n} |
|
||||
| browser.js:8:37:10:2 | functio ... Flow\\n\\t} |
|
||||
| browser.js:12:21:14:2 | functio ... Flow\\n\\t} |
|
||||
| browser.js:24:19:27:2 | functio ... e();\\n\\t} |
|
||||
| browser.js:29:35:31:2 | functio ... Flow\\n\\t} |
|
||||
| client-custom.js:10:19:12:2 | functio ... ta);\\n\\t} |
|
||||
| client-custom.js:20:38:22:2 | functio ... ta);\\n\\t} |
|
||||
| client.js:10:19:12:2 | functio ... ta);\\n\\t} |
|
||||
clientSend
|
||||
| browser-custom.js:7:3:7:33 | socket. ... wser!') |
|
||||
| browser-custom.js:23:3:23:19 | sock.send('test') |
|
||||
| browser-custom.js:39:9:39:52 | myWebSo ... wser!') |
|
||||
| browser-custom.js:54:9:54:37 | mySockJ ... 'test') |
|
||||
| browser.js:5:3:5:33 | socket. ... wser!') |
|
||||
| browser.js:21:3:21:19 | sock.send('test') |
|
||||
| client-custom.js:7:3:7:28 | ws.send ... ient!') |
|
||||
| client-custom.js:17:3:17:47 | myWebSo ... ient!') |
|
||||
| client.js:7:3:7:28 | ws.send ... ient!') |
|
||||
clientReceive
|
||||
| browser.js:8:37:10:2 | functio ... ta);\\n\\t} |
|
||||
| browser.js:12:21:14:2 | functio ... ata)\\n\\t} |
|
||||
| browser.js:24:19:27:2 | functio ... e();\\n\\t} |
|
||||
| browser.js:29:35:31:2 | functio ... ta);\\n\\t} |
|
||||
| client.js:10:19:12:2 | functio ... ta);\\n\\t} |
|
||||
serverSocket
|
||||
| server.js:6:43:6:44 | ws |
|
||||
| sockjs.js:8:40:8:43 | conn |
|
||||
serverSend
|
||||
| server.js:11:3:11:28 | ws.send ... rver!') |
|
||||
| sockjs.js:11:9:11:51 | conn.wr ... test))) |
|
||||
serverReceive
|
||||
| server.js:7:3:9:4 | ws.on(' ... );\\n\\t\\t}) |
|
||||
| sockjs.js:9:5:12:6 | conn.on ... \\n }) |
|
||||
clientSocket
|
||||
| browser-custom.js:4:17:4:54 | new MyW ... :9080') |
|
||||
| browser-custom.js:21:13:21:52 | new MyS ... /echo') |
|
||||
| browser.js:2:17:2:52 | new Web ... :8080') |
|
||||
| browser.js:19:13:19:50 | new Soc ... /echo') |
|
||||
| browser.js:36:36:36:71 | new Web ... :8080') |
|
||||
| browser.js:37:33:37:70 | new Soc ... /echo') |
|
||||
| client-custom.js:4:13:4:49 | new MyW ... e.org') |
|
||||
| client.js:4:13:4:45 | new Web ... e.org') |
|
||||
| client.js:16:40:16:72 | new Web ... e.org') |
|
||||
flowSteps
|
||||
| browser-custom.js:1:10:1:20 | MyWebSocket | browser-custom.js:1:10:1:20 | MyWebSocket |
|
||||
| browser-custom.js:1:23:1:30 | MySockJS | browser-custom.js:1:23:1:30 | MySockJS |
|
||||
| browser-custom.js:1:33:1:51 | myWebSocketInstance | browser-custom.js:1:33:1:51 | myWebSocketInstance |
|
||||
| browser-custom.js:1:54:1:69 | mySockJSInstance | browser-custom.js:1:54:1:69 | mySockJSInstance |
|
||||
| browser-custom.js:7:15:7:32 | 'Hi from browser!' | server-custom.js:7:38:7:44 | message |
|
||||
| browser-custom.js:7:15:7:32 | 'Hi from browser!' | server-custom.js:17:38:17:44 | message |
|
||||
| browser-custom.js:7:15:7:32 | 'Hi from browser!' | server.js:7:38:7:44 | message |
|
||||
| browser-custom.js:23:13:23:18 | 'test' | sockjs.js:9:31:9:37 | message |
|
||||
| browser-custom.js:39:34:39:51 | 'Hi from browser!' | server-custom.js:7:38:7:44 | message |
|
||||
| browser-custom.js:39:34:39:51 | 'Hi from browser!' | server-custom.js:17:38:17:44 | message |
|
||||
| browser-custom.js:39:34:39:51 | 'Hi from browser!' | server.js:7:38:7:44 | message |
|
||||
| browser-custom.js:54:31:54:36 | 'test' | sockjs.js:9:31:9:37 | message |
|
||||
| browser.js:5:15:5:32 | 'Hi from browser!' | server-custom.js:7:38:7:44 | message |
|
||||
| browser.js:5:15:5:32 | 'Hi from browser!' | server-custom.js:17:38:17:44 | message |
|
||||
| browser.js:5:15:5:32 | 'Hi from browser!' | server.js:7:38:7:44 | message |
|
||||
| browser.js:21:13:21:18 | 'test' | sockjs.js:9:31:9:37 | message |
|
||||
| client-custom.js:7:11:7:27 | 'Hi from client!' | server-custom.js:7:38:7:44 | message |
|
||||
| client-custom.js:7:11:7:27 | 'Hi from client!' | server-custom.js:17:38:17:44 | message |
|
||||
| client-custom.js:7:11:7:27 | 'Hi from client!' | server.js:7:38:7:44 | message |
|
||||
| client-custom.js:17:30:17:46 | 'Hi from client!' | server-custom.js:7:38:7:44 | message |
|
||||
| client-custom.js:17:30:17:46 | 'Hi from client!' | server-custom.js:17:38:17:44 | message |
|
||||
| client-custom.js:17:30:17:46 | 'Hi from client!' | server.js:7:38:7:44 | message |
|
||||
| client.js:7:11:7:27 | 'Hi from client!' | server-custom.js:7:38:7:44 | message |
|
||||
| client.js:7:11:7:27 | 'Hi from client!' | server-custom.js:17:38:17:44 | message |
|
||||
| client.js:7:11:7:27 | 'Hi from client!' | server.js:7:38:7:44 | message |
|
||||
| client.js:15:32:15:44 | require('ws') | client-custom.js:1:9:1:21 | MyWebSocketWS |
|
||||
| client.js:16:40:16:72 | new Web ... e.org') | client-custom.js:1:24:1:44 | myWebSo ... nstance |
|
||||
| server-custom.js:11:11:11:27 | 'Hi from server!' | browser-custom.js:11:39:11:48 | event.data |
|
||||
| server-custom.js:11:11:11:27 | 'Hi from server!' | browser-custom.js:15:40:15:49 | event.data |
|
||||
| server-custom.js:11:11:11:27 | 'Hi from server!' | browser-custom.js:43:45:43:54 | event.data |
|
||||
| server-custom.js:11:11:11:27 | 'Hi from server!' | browser-custom.js:47:46:47:55 | event.data |
|
||||
| server-custom.js:11:11:11:27 | 'Hi from server!' | browser-custom.js:69:38:69:43 | e.data |
|
||||
| server-custom.js:11:11:11:27 | 'Hi from server!' | browser.js:9:39:9:48 | event.data |
|
||||
| server-custom.js:11:11:11:27 | 'Hi from server!' | browser.js:13:40:13:49 | event.data |
|
||||
| server-custom.js:11:11:11:27 | 'Hi from server!' | client-custom.js:10:37:10:40 | data |
|
||||
| server-custom.js:11:11:11:27 | 'Hi from server!' | client-custom.js:20:56:20:59 | data |
|
||||
| server-custom.js:11:11:11:27 | 'Hi from server!' | client.js:10:37:10:40 | data |
|
||||
| server-custom.js:21:11:21:27 | 'Hi from server!' | browser-custom.js:11:39:11:48 | event.data |
|
||||
| server-custom.js:21:11:21:27 | 'Hi from server!' | browser-custom.js:15:40:15:49 | event.data |
|
||||
| server-custom.js:21:11:21:27 | 'Hi from server!' | browser-custom.js:43:45:43:54 | event.data |
|
||||
| server-custom.js:21:11:21:27 | 'Hi from server!' | browser-custom.js:47:46:47:55 | event.data |
|
||||
| server-custom.js:21:11:21:27 | 'Hi from server!' | browser-custom.js:69:38:69:43 | e.data |
|
||||
| server-custom.js:21:11:21:27 | 'Hi from server!' | browser.js:9:39:9:48 | event.data |
|
||||
| server-custom.js:21:11:21:27 | 'Hi from server!' | browser.js:13:40:13:49 | event.data |
|
||||
| server-custom.js:21:11:21:27 | 'Hi from server!' | client-custom.js:10:37:10:40 | data |
|
||||
| server-custom.js:21:11:21:27 | 'Hi from server!' | client-custom.js:20:56:20:59 | data |
|
||||
| server-custom.js:21:11:21:27 | 'Hi from server!' | client.js:10:37:10:40 | data |
|
||||
| server.js:11:11:11:27 | 'Hi from server!' | browser-custom.js:11:39:11:48 | event.data |
|
||||
| server.js:11:11:11:27 | 'Hi from server!' | browser-custom.js:15:40:15:49 | event.data |
|
||||
| server.js:11:11:11:27 | 'Hi from server!' | browser-custom.js:43:45:43:54 | event.data |
|
||||
| server.js:11:11:11:27 | 'Hi from server!' | browser-custom.js:47:46:47:55 | event.data |
|
||||
| server.js:11:11:11:27 | 'Hi from server!' | browser-custom.js:69:38:69:43 | e.data |
|
||||
| server.js:11:11:11:27 | 'Hi from server!' | browser.js:9:39:9:48 | event.data |
|
||||
| server.js:11:11:11:27 | 'Hi from server!' | browser.js:13:40:13:49 | event.data |
|
||||
| server.js:11:11:11:27 | 'Hi from server!' | client-custom.js:10:37:10:40 | data |
|
||||
| server.js:11:11:11:27 | 'Hi from server!' | client-custom.js:20:56:20:59 | data |
|
||||
| server.js:11:11:11:27 | 'Hi from server!' | client.js:10:37:10:40 | data |
|
||||
| server.js:15:36:15:55 | require('ws').Server | server-custom.js:1:9:1:25 | MyWebSocketServer |
|
||||
| server.js:16:44:16:79 | new Web ... 8080 }) | server-custom.js:1:28:1:52 | myWebSo ... nstance |
|
||||
| sockjs.js:11:20:11:50 | JSON.st ... .test)) | browser-custom.js:27:26:27:31 | e.data |
|
||||
| sockjs.js:11:20:11:50 | JSON.st ... .test)) | browser-custom.js:32:42:32:51 | event.data |
|
||||
| sockjs.js:11:20:11:50 | JSON.st ... .test)) | browser-custom.js:58:32:58:37 | e.data |
|
||||
| sockjs.js:11:20:11:50 | JSON.st ... .test)) | browser-custom.js:63:48:63:57 | event.data |
|
||||
| sockjs.js:11:20:11:50 | JSON.st ... .test)) | browser.js:25:26:25:31 | e.data |
|
||||
| sockjs.js:11:20:11:50 | JSON.st ... .test)) | browser.js:30:42:30:51 | event.data |
|
||||
remoteFlow
|
||||
| browser-custom.js:11:39:11:48 | event.data |
|
||||
| browser-custom.js:15:40:15:49 | event.data |
|
||||
| browser-custom.js:27:26:27:31 | e.data |
|
||||
| browser-custom.js:32:42:32:51 | event.data |
|
||||
| browser-custom.js:43:45:43:54 | event.data |
|
||||
| browser-custom.js:47:46:47:55 | event.data |
|
||||
| browser-custom.js:58:32:58:37 | e.data |
|
||||
| browser-custom.js:63:48:63:57 | event.data |
|
||||
| browser-custom.js:69:38:69:43 | e.data |
|
||||
| browser.js:9:39:9:48 | event.data |
|
||||
| browser.js:13:40:13:49 | event.data |
|
||||
| browser.js:25:26:25:31 | e.data |
|
||||
| browser.js:30:42:30:51 | event.data |
|
||||
| client-custom.js:10:37:10:40 | data |
|
||||
| client-custom.js:20:56:20:59 | data |
|
||||
| client.js:10:37:10:40 | data |
|
||||
| server-custom.js:7:38:7:44 | message |
|
||||
| server-custom.js:17:38:17:44 | message |
|
||||
| server.js:7:38:7:44 | message |
|
||||
| sockjs.js:9:31:9:37 | message |
|
||||
serverReceive
|
||||
| server-custom.js:7:3:9:4 | ws.on(' ... );\\n\\t\\t}) |
|
||||
| server-custom.js:17:3:19:4 | ws.on(' ... );\\n\\t\\t}) |
|
||||
| server.js:7:3:9:4 | ws.on(' ... );\\n\\t\\t}) |
|
||||
| sockjs.js:9:5:12:6 | conn.on ... \\n }) |
|
||||
serverSend
|
||||
| server-custom.js:11:3:11:28 | ws.send ... rver!') |
|
||||
| server-custom.js:21:3:21:28 | ws.send ... rver!') |
|
||||
| server.js:11:3:11:28 | ws.send ... rver!') |
|
||||
| sockjs.js:11:9:11:51 | conn.wr ... test))) |
|
||||
serverSocket
|
||||
| server-custom.js:6:43:6:44 | ws |
|
||||
| server-custom.js:16:65:16:66 | ws |
|
||||
| server.js:6:43:6:44 | ws |
|
||||
| sockjs.js:8:40:8:43 | conn |
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
query: test.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
Reference in New Issue
Block a user