I am trying to send a JSON object that contains a byte[] to a "Console Application" using a Chrome Extention by NativeMessaging.
I have no problems with some of the calls, but I get a problem when I try to send a byte array.
Behavior is following:
reader.Read(buffer, 0, buffer.Length);
I will post here a version of code that I hope it helps.
Native App.
Program.cs
public static void Main(string[] args)
{
m_Logger = LogManager.Setup().GetCurrentClassLogger();
m_Logger.Info("App Started!");
try
{
JObject command = Read();
if (command != null)
{
var ceCommand = command.ToObject<CommandModel>();
if (ceCommand == null)
{
m_Logger.Warn("Could not deserialize command from extention");
return;
}
//do other things
}
}
}
catch (Exception ex)
{
throw;
}
}
public static JObject Read()
{
try
{
m_Logger.Debug("Read started");
var stdin = Console.OpenStandardInput();
m_Logger.Debug("StDin initialized");
var length = 0;
var lengthBytes = new byte[4];
stdin.Read(lengthBytes, 0, 4);
length = BitConverter.ToInt32(lengthBytes, 0);
m_Logger.Debug($"Message length: {length}");
var buffer = new char[length];
m_Logger.Debug($"Buffer lenght: {buffer.Length}");
using (var reader = new StreamReader(stdin))
{
m_Logger.Debug("Reading from stream...");
while (reader.Peek() >= 0)
{
m_Logger.Debug("We are in reading process...please wait");
int result = reader.Read(buffer, 0, buffer.Length);
m_Logger.Debug($"Read {result} numer of chars");
}
m_Logger.Debug("Read finished");
}
var stringMessage = new string(buffer);
m_Logger.Info($"Recieved from CE {stringMessage}");
return JsonConvert.DeserializeObject<JObject>(stringMessage);
}
catch (Exception ex)
{
m_Logger.Error(ex, $"Error at reading input data");
return null;
}
}
public static void Write(JToken data)
{
var json = new JObject();
json["data"] = data;
var bytes = System.Text.Encoding.UTF8.GetBytes(json.ToString(Formatting.None));
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>
/// Copies the contents of input to output. Doesn't close either stream.
/// </summary>
public static string ByteToString(byte[] array, int count)
{
char[] chars = Encoding.UTF8.GetChars(array, 0, count);
return new string(chars);
}
I deducted that the problem is at reader.Read(buffer, 0, buffer.Length);
based on logs that look like this
2022-11-17 16:34:14.9604 INFO App Started!
2022-11-17 16:34:15.0837 DEBUG Read started
2022-11-17 16:34:15.0837 DEBUG StDin initialized
2022-11-17 16:34:15.0837 DEBUG Message length: 1862
2022-11-17 16:34:15.0837 DEBUG Buffer lenght: 1862
2022-11-17 16:34:15.0837 DEBUG Reading from stream...
2022-11-17 16:34:15.0837 DEBUG We are in reading process...please wait
2022-11-17 16:34:15.0837 DEBUG Read 1862 numer of chars
2022-11-17 16:34:44.2786 DEBUG Read finished
2022-11-17 16:34:44.2787 DEBUG Message length: 0
2022-11-17 16:34:44.2787 DEBUG Buffer lenght: 0
2022-11-17 16:34:44.2786 INFO Recieved from CE {"CommandId":2,"CommandValue":"{\"ImportCertificates\":[],\"byteArray\":\"MIIKWAIBAzCCChQGCSqGSIb3DQEHAaCCCgUEggoBMIIJ/TCCBe4GCSqGSIb3DQEHAaCCBd8EggXbMIIF1zCCBdMGCyqGSIb3DQEMCgECoIIE7jCCBOowHAYKKoZIhvcNAQwBAzAOBAjslY0EWPiyRwICB9AEggTItTgbudKRaEBCdOn1rMgGUoGjVIOxTgT/5Oo5D0gfBe/0yorvQKenVimcfDmWCXZGlsvou5Km7g3yjmK7PTZh3IUuX86bJeyECrJBZa+4ZXyrbkVV7R2GEwy99ACOkevHxBZ7H6deVKdRFDsCSC+cdLpsSGoNNi3Coowqw8i7lzXDPzph64L2Rre7cky/QJdkXKIEUGjxKYUR4cpOOmlLXfbQMR3fOChT5FrxbOnTRTAvVELtwFTh8Gxq55Et8rLgIktQ2eL8FIx43sGspukhZvm5bH05aEwVz5df0T3e3cMsZ13t4oc72phNKx9HiZmPvmi4lUdBwn6qXEJSRg+P5MWGD41StCAoZ/pDtMTPSV5DalLpDpKF6XfxByOSXfn27KYWFZoiEdxCmabS7eomqeD03uWEzWbgPW1hha69Bg1DcmSYZgDfISugtow6p+ozQSjaNnELlbz1SsiBMPbkoNj944IxSKkHgfiqwOyQm3JqHGjDH6Hp9OB3RyuQHoeWLrW9ulmWvnT/Dn+LC0T26YHeVeTO30U86r9ElBiv4iXa5JdflWqFecbjQC1Xs29yBkkFRNrfgJ4Txd/xOz0rhzFxZmcIwiJsQgh+WxSWLG3em02xmtyO7Rcxc6g+onVpEFXKiaYDqTWNDKE2wDSDPZauheyiiluj42gi5A086rSjuqqyidzWQb6FKYs73ZUM8drnYK36RT7zG8TFpV3RdrXbnui8eFRZ4bFHNlptHTwvqpZY/sDDP1R1q1EgrckMbZhOpHhKW/1GRd95eHlSGJPdTROtR3uEARZD0+1zBarw68p1k650DWua88cMrOQPKH1X8Ce++KIdFG2RtfI2P3lhPsD0gdpet0gDEC1peUXfrZVQYD3G8IfEjpYgDpgPa6zjblScidem628MPz4dnTnWrp1S7P2ILlGYinb9uCzSR17IvPoVITQvXk9KpTp1uzuWTnRQHMfUyNvgjHSAOwt3bmx5kEyC/04ujhUvQkiyPMCrDtiO/fLYkrWuqOLNr74l/VAJYU06YR7yNMfG1kEpRYkf96v0s3XK1tZEQBt26lZFPIMl/NOHYpbCfxCGZkpOGIFDojjo72p4VUuyGD/MZ41B99jcNVB2/Sqmc9XwALl/jjkJz6+aCmvLUePeLmhg2Bxrjkmf8iDfDnKByXM5lam3D\"}","SessionKey":"QXCUUKNB0T"}
2022-11-17 16:34:44.2787 DEBUG Reading from stream...
2022-11-17 16:34:44.2787 DEBUG Read finished
2022-11-17 16:34:44.2787 INFO Recieved from CE
However this is not a problem if byteArray property is smaller in size
2022-11-17 16:32:49.7558 INFO App Started!
2022-11-17 16:32:49.8809 DEBUG Read started
2022-11-17 16:32:49.8809 DEBUG StDin initialized
2022-11-17 16:32:49.8809 DEBUG Message length: 546
2022-11-17 16:32:49.8809 DEBUG Buffer lenght: 546
2022-11-17 16:32:49.8809 DEBUG Reading from stream...
2022-11-17 16:32:49.8809 DEBUG We are in reading process...please wait
2022-11-17 16:32:49.8809 DEBUG Read 546 numer of chars
2022-11-17 16:32:49.8809 DEBUG Read finished
2022-11-17 16:32:49.8809 INFO Recieved from CE {"CommandId":2,"CommandValue":"{\"ImportCertificates\":[],\"byteArray\":\"test/wqewq+./qweqeq//eqwq\"}","SessionKey":"0SZFlRVrQR"}
As you can see here from logs app does the full flow without a problem from Starting and reading and parsing my message.
I suspected that is something regarding the size of the array, but from what I've read you can send up to 1mb of data in one NativeMessage call, data that I want to send is about 4Kb. Not even close to the max allowed size.
Any ideas on what I am doing wrong?
I will post here also the Javascript code that send this, but I don't believe problem relies in Javascript code.
export const syncCertificates = async () => {
var requestToHost = await api.getInfo();
var responsefromHost = await nativeService.syncCertificates(requestToHost);
return certUploadResponse;
}
export const syncCertificates = async (certs) => {
var command = commands[1];
await sendNativeMessageV2(command.Id, certs);
}
async function sendNativeMessageV2(command, commandValue) {
commandInProgress = command;
var sessionKey = await storage.getSessionKey();
var message =
{
"CommandId": command,
"CommandValue": JSON.stringify(commandValue),
"SessionKey": sessionKey
}
return new Promise((resolve, reject) => {
chrome.runtime.sendNativeMessage('com.allianz.usercertificateautoenrollment', message,
async function (result) {
var response = await onNativeMessage(result);
resolve(response);
}
);
});
}
After more investigations I found this Why is my C# native messaging host hanging when reading a message sent by a Firefox browser extension?
Changing the loop as answered here did the trick.
Change the loop as follows:
using (var reader = new StreamReader(stdin))
{
var offset = 0;
while (offset < length && reader.Peek() >= 0)
{
offset += reader.Read(buffer, offset, length - offset);
}
}