Skip to content

Commit

Permalink
Add charset support for SSH as well
Browse files Browse the repository at this point in the history
  • Loading branch information
NI committed Oct 2, 2019
1 parent 81a9424 commit e77ad35
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 11 deletions.
65 changes: 57 additions & 8 deletions ui/commands/ssh.js
Expand Up @@ -289,6 +289,24 @@ const initialFieldDef = {
return "Look like " + addr.type + " address";
}
},
Encoding: {
name: "Encoding",
description: "The character encoding of the server",
type: "select",
value: "utf-8",
example: common.charsetPresets.join(","),
verify(d) {
for (let i in common.charsetPresets) {
if (common.charsetPresets[i] !== d) {
continue;
}

return "";
}

throw new Error('The character encoding "' + d + '" is not supported');
}
},
Notice: {
name: "Notice",
description: "",
Expand Down Expand Up @@ -535,6 +553,7 @@ class Wizard {
let config = {
user: common.strToUint8Array(configInput.user),
auth: getAuthMethodFromStr(configInput.authentication),
charset: configInput.charset,
credential: sessionData.credential,
host: address.parseHostPort(configInput.host, DEFAULT_PORT),
fingerprint: configInput.fingerprint
Expand Down Expand Up @@ -585,6 +604,7 @@ class Wizard {
configInput.user + "@" + configInput.host,
self.info,
self.controls.get("SSH", {
charset: configInput.charset,
send(data) {
return commandHandler.sendData(data);
},
Expand Down Expand Up @@ -659,7 +679,17 @@ class Wizard {
self.hasStarted = true;

self.streams.request(COMMAND_ID, sd => {
return self.buildCommand(sd, this.config, this.session);
return self.buildCommand(
sd,
{
user: this.config.user,
authentication: this.config.authentication,
host: this.config.host,
charset: this.config.charset ? this.config.charset : "utf-8",
fingerprint: this.config.fingerprint
},
this.session
);
});

return self.stepWaitForAcceptWait();
Expand All @@ -679,6 +709,7 @@ class Wizard {
user: r.user,
authentication: r.authentication,
host: r.host,
charset: r.encoding,
fingerprint: ""
},
this.session
Expand All @@ -692,6 +723,7 @@ class Wizard {
{ name: "User" },
{ name: "Host" },
{ name: "Authentication" },
{ name: "Encoding" },
{ name: "Notice" }
])
);
Expand Down Expand Up @@ -828,20 +860,28 @@ export class Command {
}

launch(info, launcher, streams, subs, controls, history) {
let matchResult = launcher.match(new RegExp("^(.*)\\@(.*)\\|(.*)$"));
const d = launcher.split("|", 3);

if (d.length < 2) {
throw new Exception('Given launcher "' + launcher + '" was invalid');
}

const userHostName = d[0].match(new RegExp("^(.*)\\@(.*)$"));

if (!matchResult || matchResult.length !== 4) {
if (!userHostName || userHostName.length !== 3) {
throw new Exception('Given launcher "' + launcher + '" was malformed');
}

let user = matchResult[1],
host = matchResult[2],
auth = matchResult[3];
let user = userHostName[1],
host = userHostName[2],
auth = d[1],
charset = d.length >= 3 && d[2] ? d[2] : "utf-8"; // RM after depreciation

try {
initialFieldDef["User"].verify(user);
initialFieldDef["Host"].verify(host);
initialFieldDef["Authentication"].verify(auth);
initialFieldDef["Encoding"].verify(charset);
} catch (e) {
throw new Exception(
'Given launcher "' + launcher + '" was malformed ' + e
Expand All @@ -853,7 +893,8 @@ export class Command {
{
user: user,
host: host,
authentication: auth
authentication: auth,
charset: charset
},
null,
streams,
Expand All @@ -864,6 +905,14 @@ export class Command {
}

launcher(config) {
return config.user + "@" + config.host + "|" + config.authentication;
return (
config.user +
"@" +
config.host +
"|" +
config.authentication +
"|" +
(config.charset ? config.charset : "utf-8")
);
}
}
37 changes: 34 additions & 3 deletions ui/control/ssh.js
Expand Up @@ -15,6 +15,8 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

import * as iconv from "iconv-lite";

import * as subscribe from "../stream/subscribe.js";
import * as reader from "../stream/reader.js";
import * as color from "../commands/color.js";
Expand All @@ -24,6 +26,35 @@ class Control {
this.colorM = color;
this.colors = this.colorM.get();

this.charset = data.charset;

if (this.charset === "utf-8") {
let enc = new TextEncoder();

this.charsetDecoder = d => {
return d;
};

this.charsetEncoder = dStr => {
return enc.encode(dStr);
};
} else {
let dec = new TextDecoder(this.charset),
enc = new TextEncoder();

this.charsetDecoder = d => {
return enc.encode(
dec.decode(d, {
stream: true
})
);
};

this.charsetEncoder = dStr => {
return iconv.encode(dStr, this.charset);
};
}

this.enable = false;
this.sender = data.send;
this.closer = data.close;
Expand All @@ -34,15 +65,15 @@ class Control {

data.events.place("stdout", async rd => {
try {
self.subs.resolve(await reader.readCompletely(rd));
self.subs.resolve(self.charsetDecoder(await reader.readCompletely(rd)));
} catch (e) {
// Do nothing
}
});

data.events.place("stderr", async rd => {
try {
self.subs.resolve(await reader.readCompletely(rd));
self.subs.resolve(self.charsetDecoder(await reader.readCompletely(rd)));
} catch (e) {
// Do nothing
}
Expand Down Expand Up @@ -91,7 +122,7 @@ class Control {
return;
}

return this.sender(new TextEncoder().encode(data));
return this.sender(this.charsetEncoder(data));
}

color() {
Expand Down

0 comments on commit e77ad35

Please sign in to comment.