How to parse JSON from stdin at Chrome Native Messaging host?
Asked Answered
S

0

2

Related:

Utilizing the code at How do I use a shell-script as Chrome Native Messaging host application to send JSON from client (app) to host

#!/bin/bash
# Loop forever, to deal with chrome.runtime.connectNative
while IFS= read -r -n1 c; do
    # Read the first message
    # Assuming that the message ALWAYS ends with a },
    # with no }s in the string. Adopt this piece of code if needed.
    if [ "$c" != '}' ] ; then
        continue
    fi
    # do stuff
    message='{"message": "'$c'"}'
    # Calculate the byte size of the string.
    # NOTE: This assumes that byte length is identical to the string length!
    # Do not use multibyte (unicode) characters, escape them instead, e.g.
    # message='"Some unicode character:\u1234"'
    messagelen=${#message}

    # Convert to an integer in native byte order.
    # If you see an error message in Chrome's stdout with
    # "Native Messaging host tried sending a message that is ... bytes long.",
    # then just swap the order, i.e. messagelen1 <-> messagelen4 and
    # messagelen2 <-> messagelen3
    messagelen1=$(( ($messagelen      ) & 0xFF ))               
    messagelen2=$(( ($messagelen >>  8) & 0xFF ))               
    messagelen3=$(( ($messagelen >> 16) & 0xFF ))               
    messagelen4=$(( ($messagelen >> 24) & 0xFF ))               

    # Print the message byte length followed by the actual message.
    printf "$(printf '\\x%x\\x%x\\x%x\\x%x' \
        $messagelen1 $messagelen2 $messagelen3 $messagelen4)%s" "$message"

done

which results in

{"message":"}"}

being received at the client application.

The loop obviously does not capture the variable $c within the while loop.

With JSON input from client

{"text":"abc"}

using JavaScript we could get the single property of the JSON string by checking the characters at preceding and following indexes

var result = "";
var i = 0;
var input = '{"text":"abc"}';
while (i < input.length) {

  if (input[i - 2] === ":" && input[i - 1] === '"' || result.length) {
    result += input[i];
  }

  if (input[i + 1] === '"' && input[i + 2] === "}") {
    // do stuff
    break;
  }
  
  ++i;
  
};

console.log(result);

yet not certain exactly how to covert the if conditions to bash from JavaScript to get the single JSON property that the code above would match and concatenate to a string following How do I compare two string variables in an 'if' statement in Bash? and How to concatenate string variables in Bash?. And given a JSON object having nested properties using nested or multiple if conditions would require adjusting the code potentially multiple times for the specific JSON passed to the host.

The documentation describes the protocol

Native messaging protocol

Chrome starts each native messaging host in a separate process and communicates with it using standard input (stdin) and standard output (stdout). The same format is used to send messages in both directions: each message is serialized using JSON, UTF-8 encoded and is preceded with 32-bit message length in native byte order.

Could not locate any Answers at SO which definitely described the procedure for parsing JSON from stdin at host of Chrome Native Messsaging app using bash.

How to create a general solution or algorithm (including descriptions of each step necessary for the the protocol and the language) to parse JSON sent from client at the host from stdin, get and set the correct 32-bit message length in native byte order of the JSON response message that will be sent (e.g., echo; printf) to the client using bash?

Secondrate answered 24/1, 2018 at 2:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.