/// <summary> /// /// </summary> /// <param name="_request"></param> private void ActionForRequest(object _request) { Messages.Request request = _request as Messages.Request; if (request.Delay > 0) { Thread.Sleep(request.Delay); } Messages.Response response = ProcessRequest(request); responseQueue.Enqueue(response); }
/// <summary> /// Write response to stdout using native message protocol, message lentgh first int32 and then data /// Firefox and Chrome use the same protocol /// @see Firefox https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Native_messaging#Exchanging_messages /// @see Chrome https://developer.chrome.com/apps/nativeMessaging#native-messaging-host-protocol /// </summary> /// <param name="response"></param> private void WriteMessage(Messages.Response response) { string data = JsonConvert.SerializeObject(response, Formatting.None); var bytes = System.Text.Encoding.UTF8.GetBytes(data); Log.Debug("Sending Message: {0}", data); using var stdout = Console.OpenStandardOutput(); stdout.WriteByte((byte)((bytes.Length >> 0) & 0xFF)); stdout.WriteByte((byte)((bytes.Length >> 8) & 0xFF)); stdout.WriteByte((byte)((bytes.Length >> 16) & 0xFF)); stdout.WriteByte((byte)((bytes.Length >> 24) & 0xFF)); stdout.Write(bytes, 0, bytes.Length); stdout.Flush(); }
/// <summary> /// Sends a message to the browser, note that the message might not be able to reach if the stdIn / stdOut /// aren't properly configured (i.e. Process needs to be started) /// </summary> /// <param name="response"></param> private void SendMessage(Messages.Response response) { if (state == EndpointState.Listening) { writeMessageMutex.WaitOne(); try { if (TestMode) { WriteDebugMessage(response); } else { WriteMessage(response); } } catch (Exception e) { Log.Information("{0} during SendMessage : {1}", e.GetType(), e.Message); } finally { writeMessageMutex.ReleaseMutex(); } } }
/// <summary> /// /// </summary> /// <param name="request"></param> /// <returns></returns> private Messages.Response ProcessRequest(Messages.Request request) { Messages.Response response = null; if (Handlers.ContainsKey(request.Name)) { Log.Debug("Route request to {0} ", request.Name); try { Handlers.TryGetValue(request.Name, out Handler handler); response = handler.Invoke(request); } catch (Exception e) { response = request.Failure(e.GetType().Name, e.Message); } } else { Log.Debug("No handler defined for {0}", request.Name); response = request.Unknown(String.Format("Unknown request {0}", request.Name)); } return(response); }
/// <summary> /// Handles a request. if that request is async, enqueues in the request queue for later treatment /// otherwise process the request immediatly /// </summary> /// <param name="request"></param> /// <returns></returns> private void HandleRequest(Messages.Request request) { if (request == null) { Log.Debug("No route : Empty Request body"); throw new BadNativeMessagingProtocol("D'oh! Invalid request format : Empty request body"); } if (request.Async) { Log.Debug("Async-Request received: {0}", request.ToString()); requestQueue.Enqueue(request); } else { Log.Debug("Sync-Request received: {0}", request.ToString()); processRequestMutex.WaitOne(); Messages.Response response = ProcessRequest(request); SendMessage(response); processRequestMutex.ReleaseMutex(); } }
/// <summary> /// Write response on stdout by serializing response using json format. /// Used to debugging purpose. /// </summary> /// <param name="data"></param> private void WriteDebugMessage(Messages.Response response) { Log.Debug("Sending debug message: {0}", response.ToString()); using var stdout = Console.OpenStandardOutput(); stdout.Write(System.Text.Encoding.UTF8.GetBytes(response.ToString())); }