Have you read the documentation or tried to understand the example before modifying it?
So, I need to be an professional programmer to build this?
Your “modification for /native-messaging” wasn’t a minor, it completely changed the logic, to the extent that your new program isn’t correct any more.
The addon’s logic is the same. There are no breaking modifications in the addon itself. What was replaced (not modified, but completely replaced) is the native application used. NodeJS and Python are possible examples, but I would like to add an Bash example to it.
What your program does is simply echoing the “pong” message to stdout.
What it should do at minimum is to prepend the length of the message in a 32-bit value in native byte order. See Native messaging - Mozilla | MDN for the expected protocol that you need to adhere to.
See Native messaging - Mozilla | MDN
Instead:
See json - How do I use a shell-script as Chrome Native Messaging host application - Stack Overflow
Remember what yourself have posted?
Here is a minimal example that assumes that the input ends with a }
, reads it (without processing) and replies with a result. Although this demo works,
It was very helpful for me, and I thank you for that!
I’ve applied it to my native application:
#!/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
message='{"message": "pong"}'
# 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
#while read line; do
# cat > /home/daniell/${line}.txty << ENDOFFILE
#thanks
#ENDOFFILE
# if [ "${line}" = "ping" ]; then
# echo "pong"
#fi
#done
But, still, the addon logs this error: “Attempt to postMessage on disconnected port”.
Note: unless you’re very experienced with Bash
That’s why I like shell script. Its the most democratic language I’ve found, that enables anyone to make beauty things.
bash is not a good choice for developing a native messaging host, because null bytes are not consistently preserved. For example, when stdin is \0x06\0x00\x00\x00"ping"
, your bit of code with while read line
will contain \0x06"ping"
Not even that my bash script is doing, simply because the addon isn’t even sending the message, I think. So, if bash “is so horrible” but at least can read \0x06"ping"
, why its not doing it?
without the NULL bytes, which is incorrect. The examples use Python and Node.js, which more fitting scripting languages than shell scripting in Bash.
There are workarounds for that: How do I use null bytes in Bash? - Unix & Linux Stack Exchange
Also, bash can run an Python or NodeJS script that directly receives the addon’s message, formats it and repasses to the bash script (but I’m opposed to it, as it isn’t anymore the bash script as the native application).
I’ll truly appreciate if you help me putting this bash script to work with the addon, and I will even send you a tip.