Skip to content

Commit 1c0b68f

Browse files
committed
Merge pull request #363 from uProxy/trevj-newline-fix
fix issues with newlines on SSH connections
2 parents 0ca2a9a + e4df0e8 commit 1c0b68f

File tree

5 files changed

+44
-24
lines changed

5 files changed

+44
-24
lines changed

src/cloud/install/installer.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,9 @@ class CloudInstaller {
4949
connection.on('ready', () => {
5050
log.debug('logged into server');
5151

52-
var stdout = new queue.Queue<ArrayBuffer, void>();
53-
new linefeeder.LineFeeder(stdout).setSyncHandler((line: string) => {
52+
const stdoutRaw = new queue.Queue<ArrayBuffer, void>();
53+
const stdout = new linefeeder.LineFeeder(stdoutRaw);
54+
stdout.setSyncHandler((line: string) => {
5455
log.debug('STDOUT: %1', line);
5556
// Search for the URL anywhere in the line so we will
5657
// continue to work in the face of minor changes
@@ -67,8 +68,9 @@ class CloudInstaller {
6768
}
6869
});
6970

70-
var stderr = new queue.Queue<ArrayBuffer, void>();
71-
new linefeeder.LineFeeder(stderr).setSyncHandler((line: string) => {
71+
const stderrRaw = new queue.Queue<ArrayBuffer, void>();
72+
const stderr = new linefeeder.LineFeeder(stderrRaw);
73+
stderr.setSyncHandler((line: string) => {
7274
log.error('STDERR: %1', line);
7375
});
7476

@@ -81,14 +83,16 @@ class CloudInstaller {
8183
return;
8284
}
8385
stream.on('end', () => {
86+
stdout.flush();
87+
stderr.flush();
8488
connection.end();
8589
R({
8690
message: 'invitation URL not found'
8791
});
8892
}).on('data', (data:Buffer) => {
89-
stdout.handle(arraybuffers.bufferToArrayBuffer(data));
93+
stdoutRaw.handle(arraybuffers.bufferToArrayBuffer(data));
9094
}).stderr.on('data', (data: Buffer) => {
91-
stderr.handle(arraybuffers.bufferToArrayBuffer(data));
95+
stderrRaw.handle(arraybuffers.bufferToArrayBuffer(data));
9296
});
9397
});
9498
}).on('error', (e: Error) => {

src/cloud/social/provider.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -564,19 +564,21 @@ class Connection {
564564
return;
565565
}
566566

567-
var stdout = new queue.Queue<ArrayBuffer, void>();
568-
new linefeeder.LineFeeder(stdout).setSyncHandler((line: string) => {
567+
const stdoutRaw = new queue.Queue<ArrayBuffer, void>();
568+
const stdout = new linefeeder.LineFeeder(stdoutRaw);
569+
stdout.setSyncHandler((line: string) => {
569570
F(line);
570571
});
571572

572573
stream.on('data', (data: Buffer) => {
573-
stdout.handle(arraybuffers.bufferToArrayBuffer(data));
574+
stdoutRaw.handle(arraybuffers.bufferToArrayBuffer(data));
574575
}).stderr.on('data', (data: Buffer) => {
575576
R({
576577
message: 'output received on STDERR: ' + data.toString()
577578
});
578579
}).on('end', () => {
579580
log.debug('%1: exec stream end', this.name_);
581+
stdout.flush();
580582
});
581583
});
582584
});

src/net/linefeeder.spec.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,37 +5,40 @@ import linefeeder = require('./linefeeder');
55
import queue = require('../handler/queue');
66

77
describe('LineFeeder', function() {
8-
var bufferQueue: queue.Queue<ArrayBuffer, void>;
9-
var lines: linefeeder.LineFeeder;
8+
let bufferQueue: queue.Queue<ArrayBuffer, void>;
9+
let lines: linefeeder.LineFeeder;
1010

1111
beforeEach(() => {
1212
bufferQueue = new queue.Queue<ArrayBuffer, void>();
1313
lines = new linefeeder.LineFeeder(bufferQueue);
1414
});
1515

1616
it('one and done', (done) => {
17-
var s = 'hello world';
18-
bufferQueue.handle(arraybuffers.stringToArrayBuffer(s + '\n'));
17+
const s = 'hello world';
18+
bufferQueue.handle(arraybuffers.stringToArrayBuffer(s));
19+
lines.flush();
1920

2021
lines.setSyncNextHandler((result: string) => {
2122
expect(result).toEqual(s);
2223
done();
2324
});
2425
});
2526

26-
it('dangling lines', (done) => {
27-
var s = 'hello world';
27+
it('lines of multiple buffers', (done) => {
28+
const s = 'hello world';
2829
bufferQueue.handle(arraybuffers.stringToArrayBuffer('hello '));
2930
bufferQueue.handle(arraybuffers.stringToArrayBuffer('world\n'));
31+
lines.flush();
3032

3133
lines.setSyncNextHandler((result: string) => {
3234
expect(result).toEqual(s);
3335
done();
3436
});
3537
});
3638

37-
it('multiple lines in one buffer', (done) => {
39+
it('buffers of multiple lines', (done) => {
3840
bufferQueue.handle(arraybuffers.stringToArrayBuffer('a\nb\n'));
41+
lines.flush();
3942

4043
lines.setSyncNextHandler((result: string) => {
4144
expect(result).toEqual('a');

src/net/linefeeder.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,29 @@ export class LineFeeder extends queue.Queue<string, void> {
99
private static DELIMITER = arraybuffers.decodeByte(
1010
arraybuffers.stringToArrayBuffer('\n'));
1111

12-
constructor(source: queue.Queue<ArrayBuffer, void>) {
12+
private leftover_ = new ArrayBuffer(0);
13+
14+
constructor(private source_: queue.Queue<ArrayBuffer, void>) {
1315
super();
14-
let leftover = new ArrayBuffer(0);
15-
source.setSyncHandler((buffer: ArrayBuffer) => {
16-
leftover = arraybuffers.concat([leftover, buffer]);
17-
let i = arraybuffers.indexOf(leftover, LineFeeder.DELIMITER);
16+
source_.setSyncHandler((buffer: ArrayBuffer) => {
17+
this.leftover_ = arraybuffers.concat([this.leftover_, buffer]);
18+
let i = arraybuffers.indexOf(this.leftover_, LineFeeder.DELIMITER);
1819
while (i !== -1) {
19-
let parts = arraybuffers.split(leftover, i);
20+
let parts = arraybuffers.split(this.leftover_, i);
2021
let line = arraybuffers.arrayBufferToString(parts[0]);
21-
leftover = parts[1].slice(1);
22-
i = arraybuffers.indexOf(leftover, LineFeeder.DELIMITER);
22+
this.leftover_ = parts[1].slice(1);
23+
i = arraybuffers.indexOf(this.leftover_, LineFeeder.DELIMITER);
2324
this.handle(line);
2425
}
2526
});
2627
}
28+
29+
// Causes any pending line to be emitted. Intended to be called when the
30+
// underlying stream has terminated, possibly without any terminating
31+
// newline.
32+
public flush = () => {
33+
var s = arraybuffers.arrayBufferToString(this.leftover_);
34+
this.leftover_ = new ArrayBuffer(0);
35+
this.handle(s);
36+
}
2737
}

src/zork/freedom-module.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ function serveConnection(connection: tcp.Connection): void {
148148
connection.onceClosed.then((kind:tcp.SocketCloseKind) => {
149149
log.info('%1: closed (%2)',
150150
connection.connectionId, tcp.SocketCloseKind[kind]);
151+
lineFeeder.flush();
151152
});
152153
}
153154

0 commit comments

Comments
 (0)