public override Task <Result> SendCommand(SessionId sessionId, string method, JObject?args, CancellationToken token) { if (args == null) { args = new JObject(); } var tcs = new TaskCompletionSource <Result>(); MessageId msgId; if (args["to"]?.Value <string>() is not string to_str) { throw new Exception($"No 'to' field found in '{args}'"); } msgId = new FirefoxMessageId("", 0, to_str); pending_cmds[msgId] = tcs; logger.LogTrace($"SendCommand: to: {args}"); var msg = args.ToString(Formatting.None); var bytes = Encoding.UTF8.GetBytes(msg); Send(bytes, token); return(tcs.Task); }
protected override async Task <Result> SendCommandInternal(SessionId sessionId, string method, JObject args, CancellationToken token) { // logger.LogTrace($"SendCommandInternal: to-browser: {method}, {args}"); if (method != null && method != "") { var tcs = new TaskCompletionSource <Result>(); MessageId msgId; if (method == "evaluateJSAsync") { int id = GetNewCmdId(); msgId = new FirefoxMessageId(sessionId.sessionId, id, ""); } else { msgId = new FirefoxMessageId(sessionId.sessionId, 0, args["to"].Value <string>()); } pending_cmds.Add(msgId, tcs); await Send(browser, args, token); return(await tcs.Task); } await Send(browser, args, token); return(await Task.FromResult(Result.OkFromObject(new { }))); }
protected override Task?HandleMessage(string msg, CancellationToken token) { var res = JObject.Parse(msg); if (res["type"]?.Value <string>() == "newSource") { var method = res["type"]?.Value <string>(); return(onEvent(method, res, token)); } if (res["type"]?.Value <string>() == "target-available-form" && res["target"] is JObject target) { UpdateTarget(target); return(Task.CompletedTask); } if (res["applicationType"] != null) { return(null); } if (res["resultID"] != null) { if (res["type"]?.Value <string>() == "evaluationResult") { if (res["from"]?.Value <string>() is not string from_str) { return(null); } var messageId = new FirefoxMessageId("", 0, from_str); if (pending_cmds.Remove(messageId, out var item)) { item.SetResult(Result.FromJsonFirefox(res)); } else { logger.LogDebug($"HandleMessage: Could not find any pending cmd for {messageId}. msg: {msg}"); } } return(null); } if (res["from"] is not null) { if (res["from"]?.Value <string>() is not string from_str) { return(null); } var messageId = new FirefoxMessageId("", 0, from_str); if (pending_cmds.Remove(messageId, out var item)) { item.SetResult(Result.FromJsonFirefox(res)); return(null); } } if (res["type"] != null) { var method = res["type"]?.Value <string>(); switch (method) { case "paused": { method = "Debugger.paused"; break; } case "resource-available-form": { if (res["resources"]?[0]?["resourceType"]?.Value <string>() == "console-message" /*&& res["resources"][0]["arguments"] != null*/) { method = "Runtime.consoleAPICalled"; var args = new JArray(); // FIXME: unncessary alloc foreach (JToken?argument in res["resources"]?[0]?["message"]?["arguments"]?.Value <JArray>() ?? new JArray()) { args.Add(JObject.FromObject(new { value = argument.Value <string>() })); } res = JObject.FromObject(new { type = res["resources"]?[0]?["message"]?["level"]?.Value <string>(), args }); } break; } } return(onEvent(method, res, token)); } return(null); }
protected override Task ProcessBrowserMessage(string msg, CancellationToken token) { try { logger.LogTrace($"from-browser: {msg}"); var res = JObject.Parse(msg); if (res["error"] is not null) { logger.LogDebug($"from-browser: {res}"); } //if (method != "Debugger.scriptParsed" && method != "Runtime.consoleAPICalled") if (res["prototype"] != null || res["frames"] != null) { var msgId = new FirefoxMessageId(null, 0, res["from"].Value <string>()); // if (pending_cmds.ContainsKey(msgId)) { // HACK for now, as we don't correctly handle responses yet OnResponse(msgId, Result.FromJsonFirefox(res)); } } else if (res["resultID"] == null) { return(OnEvent(res.ToObject <SessionId>(), res, token)); } else if (res["type"] == null || res["type"].Value <string>() != "evaluationResult") { var o = JObject.FromObject(new { type = "evaluationResult", resultID = res["resultID"].Value <string>() }); var id = int.Parse(res["resultID"].Value <string>().Split('-')[1]); var msgId = new MessageId(null, id + 1); return(SendCommandInternal(msgId, "", o, token)); } else if (res["result"] is JObject && res["result"]["type"].Value <string>() == "object" && res["result"]["class"].Value <string>() == "Array") { var msgIdNew = new FirefoxMessageId(null, 0, res["result"]["actor"].Value <string>()); var id = int.Parse(res["resultID"].Value <string>().Split('-')[1]); var msgId = new FirefoxMessageId(null, id + 1, ""); var pendingTask = pending_cmds[msgId]; pending_cmds.Remove(msgId); pending_cmds.Add(msgIdNew, pendingTask); return(SendCommandInternal(msgIdNew, "", JObject.FromObject(new { type = "prototypeAndProperties", to = res["result"]["actor"].Value <string>() }), token)); } else { var id = int.Parse(res["resultID"].Value <string>().Split('-')[1]); var msgId = new FirefoxMessageId(null, id + 1, ""); if (pending_cmds.ContainsKey(msgId)) { OnResponse(msgId, Result.FromJsonFirefox(res)); } else { return(SendCommandInternal(msgId, "", res, token)); } return(null); } return(null); } catch (Exception ex) { logger.LogError(ex.ToString()); _runLoop.Fail(ex); throw; } }
protected override Task ProcessBrowserMessage(string msg, CancellationToken token) { try { logger.LogTrace($"from-browser: {msg}"); var res = JObject.Parse(msg); if (res["error"] is not null) { logger.LogDebug($"from-browser: {res}"); } //if (method != "Debugger.scriptParsed" && method != "Runtime.consoleAPICalled") if (res["prototype"] != null || res["frames"] != null) { var msgId = new FirefoxMessageId(null, 0, res["from"].Value <string>()); // if (pending_cmds.ContainsKey(msgId)) { // HACK for now, as we don't correctly handle responses yet OnResponse(msgId, Result.FromJsonFirefox(res)); } } else if (res["resultID"] == null) { return(OnEvent(res.ToObject <SessionId>(), res, token)); } else if (res["type"] == null || res["type"].Value <string>() != "evaluationResult") { var o = JObject.FromObject(new { type = "evaluationResult", resultID = res["resultID"].Value <string>() }); var id = int.Parse(res["resultID"].Value <string>().Split('-')[1]); var msgId = new MessageId(null, id + 1); return(SendCommandInternal(msgId, "", o, token)); } else if (res["result"] is JObject && res["result"]["type"].Value <string>() == "object" && res["result"]["class"].Value <string>() == "Array") { var msgIdNew = new FirefoxMessageId(null, 0, res["result"]["actor"].Value <string>()); var id = int.Parse(res["resultID"].Value <string>().Split('-')[1]); var msgId = new FirefoxMessageId(null, id + 1, ""); var pendingTask = pending_cmds[msgId]; pending_cmds.Remove(msgId); pending_cmds.Add(msgIdNew, pendingTask); return(SendCommandInternal(msgIdNew, "", JObject.FromObject(new { type = "prototypeAndProperties", to = res["result"]["actor"].Value <string>() }), token)); } else { var id = int.Parse(res["resultID"].Value <string>().Split('-')[1]); var msgId = new FirefoxMessageId(null, id + 1, ""); if (pending_cmds.ContainsKey(msgId)) { OnResponse(msgId, Result.FromJsonFirefox(res)); } else { return(SendCommandInternal(msgId, "", res, token)); } return(null); } //{"type":"evaluationResult","resultID":"1634575904746-0","hasException":false,"input":"ret = 10","result":10,"startTime":1634575904746,"timestamp":1634575904748,"from":"server1.conn21.child10/consoleActor2"} return(null); } catch (Exception ex) { // FIXME: using `side_exception` right now because the runloop doesn't // immediately look at all faulted tasks logger.LogError(ex.ToString()); side_exception.TrySetResult(ex); throw; } }