44/// <reference path='../../../../third_party/typings/ssh2/ssh2.d.ts' />
55
66import arraybuffers = require( '../../arraybuffers/arraybuffers' ) ;
7+ import linefeeder = require( '../../net/linefeeder' ) ;
78import logging = require( '../../logging/logging' ) ;
9+ import queue = require( '../../handler/queue' ) ;
810
911// https://github.com/borisyankov/DefinitelyTyped/blob/master/ssh2/ssh2-tests.ts
1012import * as ssh2 from 'ssh2' ;
@@ -280,7 +282,7 @@ export class CloudSocialProvider {
280282 // the instance (safe because all we've done is run ping).
281283 log . info ( 'new proxying session %1' , payload . proxyingId ) ;
282284 if ( ! ( destinationClientId in this . savedContacts_ ) ) {
283- return Promise . reject ( 'unknown client ' + destinationClientId ) ;
285+ return Promise . reject ( new Error ( 'unknown client ' + destinationClientId ) ) ;
284286 }
285287 return this . reconnect_ ( this . savedContacts_ [ destinationClientId ] . invite ) . then (
286288 ( connection : Connection ) => {
@@ -293,14 +295,14 @@ export class CloudSocialProvider {
293295 connection . sendMessage ( JSON . stringify ( payload ) ) ;
294296 } ) ;
295297 } else {
296- return Promise . reject ( 'unknown client ' + destinationClientId ) ;
298+ return Promise . reject ( new Error ( 'unknown client ' + destinationClientId ) ) ;
297299 }
298300 }
299301 } else {
300- return Promise . reject ( 'message has no or wrong type field' ) ;
302+ return Promise . reject ( new Error ( 'message has no or wrong type field' ) ) ;
301303 }
302304 } catch ( e ) {
303- return Promise . reject ( 'could not de-serialise message: ' + e . message ) ;
305+ return Promise . reject ( new Error ( 'could not de-serialise message: ' + e . message ) ) ;
304306 }
305307 }
306308
@@ -349,7 +351,7 @@ export class CloudSocialProvider {
349351 // Return nothing for type checking purposes.
350352 } ) ;
351353 } catch ( e ) {
352- return Promise . reject ( 'could not parse invite code: ' + e . message ) ;
354+ return Promise . reject ( new Error ( 'could not parse invite code: ' + e . message ) ) ;
353355 }
354356 }
355357
@@ -395,7 +397,7 @@ class Connection {
395397 // TODO: timeout
396398 public connect = ( ) : Promise < void > => {
397399 if ( this . state_ !== ConnectionState . NEW ) {
398- return Promise . reject ( 'can only connect in NEW state' ) ;
400+ return Promise . reject ( new Error ( 'can only connect in NEW state' ) ) ;
399401 }
400402 this . state_ = ConnectionState . CONNECTING ;
401403
@@ -424,49 +426,45 @@ class Connection {
424426 ZORK_HOST , ZORK_PORT , ( e : Error , stream : ssh2 . Channel ) => {
425427 if ( e ) {
426428 this . close ( ) ;
427- R ( 'error establishing tunnel: ' + e . toString ( ) ) ;
429+ R ( new Error ( 'error establishing tunnel: ' + e . toString ( ) ) ) ;
430+ return ;
428431 }
429432 this . setState_ ( ConnectionState . WAITING_FOR_PING ) ;
430433
431434 this . stream_ = stream ;
432435
433- // TODO: add error handler for stream
434- let leftover = new ArrayBuffer ( 0 ) ;
435- this . stream_ . on ( 'data' , ( data : Buffer ) => {
436- leftover = arraybuffers . concat ( [ leftover ,
437- arraybuffers . bufferToArrayBuffer ( data ) ] ) ;
438- let i = arraybuffers . indexOf ( leftover , Connection . COMMAND_DELIMITER ) ;
439- while ( i !== - 1 ) {
440- let parts = arraybuffers . split ( leftover , i ) ;
441- let reply = arraybuffers . arrayBufferToString ( parts [ 0 ] ) . trim ( ) ;
442- leftover = parts [ 1 ] . slice ( 1 ) ;
443- i = arraybuffers . indexOf ( leftover , Connection . COMMAND_DELIMITER ) ;
444-
445- switch ( this . state_ ) {
446- case ConnectionState . WAITING_FOR_PING :
447- if ( reply === 'ping' ) {
448- this . setState_ ( ConnectionState . ESTABLISHED ) ;
449- F ( ) ;
450- } else {
451- this . close ( ) ;
452- R ( new Error ( 'did not receive ping from server on login: ' +
453- reply ) ) ;
454- }
455- break ;
456- case ConnectionState . ESTABLISHED :
457- try {
458- this . received_ ( JSON . parse ( reply ) ) ;
459- } catch ( e ) {
460- log . warn ( '%1: could not de-serialise signalling message: %2' ,
461- this . invite_ , reply ) ;
462- }
463- break ;
464- default :
465- log . warn ( '%1: did not expect message in state %2: %3' ,
466- this . name_ , ConnectionState [ this . state_ ] , reply ) ;
436+ var bufferQueue = new queue . Queue < ArrayBuffer , void > ( ) ;
437+ new linefeeder . LineFeeder ( bufferQueue ) . setSyncHandler ( ( reply : string ) => {
438+ log . debug ( '%1: received message: %2' , this . name_ , reply ) ;
439+ switch ( this . state_ ) {
440+ case ConnectionState . WAITING_FOR_PING :
441+ if ( reply === 'ping' ) {
442+ this . setState_ ( ConnectionState . ESTABLISHED ) ;
443+ F ( ) ;
444+ } else {
467445 this . close ( ) ;
468- }
446+ R ( new Error ( 'did not receive ping from server on login: ' +
447+ reply ) ) ;
448+ }
449+ break ;
450+ case ConnectionState . ESTABLISHED :
451+ try {
452+ this . received_ ( JSON . parse ( reply ) ) ;
453+ } catch ( e ) {
454+ log . warn ( '%1: could not de-serialise signalling message: %2' ,
455+ this . invite_ , reply ) ;
456+ }
457+ break ;
458+ default :
459+ log . warn ( '%1: did not expect message in state %2: %3' ,
460+ this . name_ , ConnectionState [ this . state_ ] , reply ) ;
461+ this . close ( ) ;
469462 }
463+ } ) ;
464+
465+ // TODO: add error handler for stream
466+ stream . on ( 'data' , ( buffer : Buffer ) => {
467+ bufferQueue . handle ( arraybuffers . bufferToArrayBuffer ( buffer ) ) ;
470468 } ) . on ( 'error' , ( e : Error ) => {
471469 // This occurs when:
472470 // - host cannot be reached, e.g. non-existant hostname
@@ -529,7 +527,7 @@ class Connection {
529527 // Fetches the server's description, i.e. /banner.
530528 public getBanner = ( ) : Promise < string > => {
531529 if ( this . state_ !== ConnectionState . ESTABLISHED ) {
532- return Promise . reject ( 'can only fetch banner in ESTABLISHED state' ) ;
530+ return Promise . reject ( new Error ( 'can only fetch banner in ESTABLISHED state' ) ) ;
533531 }
534532 return new Promise < string > ( ( F , R ) => {
535533 this . client_ . exec ( 'cat /banner' , ( e : Error , stream : ssh2 . Channel ) => {
0 commit comments