Container exec encoding

I’m a bit inexperienced with both go & with text encoding and would appreciate any insights that are available…

when running in ruby:

retval = hyperkit.execute_command(container_name, command, wait_for_websocket: true, interactive: false, sync: false)

which calls LXD’s /1.0/containers/<name>/exec REST endpoint with those options. I get and successfully establish a number of websocket connections in order to capture the output.

Backstory:

I’ve gone through a couple of websocket libraries on my receiving end, but keep encountering issues that I didn’t like, so then I move on to the next library. They all gave me actual text messages in a Ruby string (when they worked), so this wasn’t an issue with them. But I’ve now settled on faye/websocket-driver-ruby and they actually give me binary messages (on stdout e.g.), from the LXD host, instead of text messages.

This implementation does seem more ‘raw’ and from digging through your code I found https://github.com/lxc/lxd/blob/master/shared/network.go#L170-L176 (enter my go newb-ness) If I read that right, you are in fact sending binary? (L183 has me scratching my head) If that’s right, though, I’d be willing to bet that the past libs did some text encoding for me under the hood. They were pretty high-level.

####Questions:
(assuming I’m not in the rabbit-hole of a bad websocket impl - are you sending text?)

  1. could I send an encoding header during the HTTP upgrade-to-websocket process and would it be honored?
  2. (enter my encoding newb-ness) I’m responding at this point in time with:

I have validated that I get an Array of Int’s, instead of a string. (This impl sends both text and binary through the same event handler). ev.data.pack('U*') interprets the array as UTF8 and returns a string. Safe move? Or is there something more deterministic that I should be doing? A different more generic encoding? (This of course works for me with en_US.UTF8). But what happens when the container is not running ASCII or UTF8 by default?

Or is there some other way for us to communicate the encoding?

Or do I need to carry this issue to faye/websocket-driver-ruby because you are sending text?

The encoding is whichever encoding the container is using for its locale. So that’s container dependent, though these days, assuming UTF-8 should be pretty safe.

LXD doesn’t treat any of that websocket traffic as strings, it reads a bunch of bytes from a tty in the kernel and sends those bytes unmodified over websocket. If you do need to get things as a string, then you need to do the decoding yourself which either requires you to know what locale is used in the container to use the right encoding, or assume that everyone is doing UTF-8 these days and use that.

Note that UTF-8 is a superset of ASCII, so no problem there. You’ll only run into problems if the container is using UTF-16 somehow or if it’s using one of the very old ISO-XXXX type locales.