Browse Source

fixed #8417 - ensure that serial output is chunked at utf8 char boundaries

Eugene Pankov 2 years ago
parent
commit
b97c334660

+ 3 - 1
tabby-serial/src/api.ts

@@ -3,7 +3,7 @@ import { SerialPortStream } from '@serialport/stream'
 import { LogService, NotificationsService } from 'tabby-core'
 import { Subject, Observable } from 'rxjs'
 import { Injector, NgZone } from '@angular/core'
-import { BaseSession, BaseTerminalProfile, LoginScriptsOptions, SessionMiddleware, StreamProcessingOptions, TerminalStreamProcessor } from 'tabby-terminal'
+import { BaseSession, BaseTerminalProfile, LoginScriptsOptions, SessionMiddleware, StreamProcessingOptions, TerminalStreamProcessor, UTF8SplitterMiddleware } from 'tabby-terminal'
 import { SerialService } from './services/serial.service'
 
 export interface SerialProfile extends BaseTerminalProfile {
@@ -64,6 +64,8 @@ export class SerialSession extends BaseSession {
             this.middleware.unshift(new SlowFeedMiddleware())
         }
 
+        this.middleware.push(new UTF8SplitterMiddleware())
+
         this.setLoginScriptsOptions(profile.options)
     }
 

+ 4 - 8
tabby-ssh/src/session/shell.ts

@@ -2,8 +2,8 @@ import { Observable, Subject } from 'rxjs'
 import stripAnsi from 'strip-ansi'
 import { ClientChannel } from 'ssh2'
 import { Injector } from '@angular/core'
-import { LogService, UTF8Splitter } from 'tabby-core'
-import { BaseSession } from 'tabby-terminal'
+import { LogService } from 'tabby-core'
+import { BaseSession, UTF8SplitterMiddleware } from 'tabby-terminal'
 import { SSHSession } from './ssh'
 import { SSHProfile } from '../api'
 
@@ -13,7 +13,6 @@ export class SSHShellSession extends BaseSession {
     get serviceMessage$ (): Observable<string> { return this.serviceMessage }
     private serviceMessage = new Subject<string>()
     private ssh: SSHSession|null
-    private decoder = new UTF8Splitter()
 
     constructor (
         injector: Injector,
@@ -24,6 +23,7 @@ export class SSHShellSession extends BaseSession {
         this.ssh = ssh
         this.setLoginScriptsOptions(this.profile.options)
         this.ssh.serviceMessage$.subscribe(m => this.serviceMessage.next(m))
+        this.middleware.push(new UTF8SplitterMiddleware())
     }
 
     async start (): Promise<void> {
@@ -61,14 +61,10 @@ export class SSHShellSession extends BaseSession {
         })
 
         this.shell.on('data', data => {
-            this.emitOutput(this.decoder.write(data))
+            this.emitOutput(data)
         })
 
         this.shell.on('end', () => {
-            const remainder = this.decoder.flush()
-            if (remainder.length) {
-                this.emitOutput(remainder)
-            }
             this.logger.info('Shell session ended')
             if (this.open) {
                 this.destroy()

+ 1 - 0
tabby-terminal/src/index.ts

@@ -94,6 +94,7 @@ export * from './api/interfaces'
 export * from './middleware/streamProcessing'
 export * from './middleware/loginScriptProcessing'
 export * from './middleware/oscProcessing'
+export * from './middleware/utf8Splitter'
 export * from './api/middleware'
 export * from './session'
 export { LoginScriptsSettingsComponent, StreamProcessingSettingsComponent }

+ 22 - 0
tabby-terminal/src/middleware/utf8Splitter.ts

@@ -0,0 +1,22 @@
+import { UTF8Splitter } from 'tabby-core'
+
+import { SessionMiddleware } from '../api/middleware'
+
+/**
+ * Ensures that the session output is chunked at UTF8 character boundaries.
+ */
+export class UTF8SplitterMiddleware extends SessionMiddleware {
+    private decoder = new UTF8Splitter()
+
+    feedFromSession (data: Buffer): void {
+        super.feedFromSession(this.decoder.write(data))
+    }
+
+    close (): void {
+        const remainder = this.decoder.flush()
+        if (remainder.length) {
+            super.feedFromSession(remainder)
+        }
+        super.close()
+    }
+}