Skip to content

Commit

Permalink
Fix early half-close exit command finishing a stream early
Browse files Browse the repository at this point in the history
  • Loading branch information
Joannis committed Aug 30, 2024
1 parent 350e1a4 commit f265b4e
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 12 deletions.
2 changes: 1 addition & 1 deletion Examples/OpenSSH/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ FROM ubuntu:latest

RUN apt update && apt install openssh-server sudo -y

RUN echo 'ubuntu:test' | chpasswd
RUN echo "ubuntu:test" | chpasswd

RUN service ssh start

Expand Down
1 change: 0 additions & 1 deletion Sources/Citadel/ClientSession.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ final class ClientHandshakeHandler: ChannelInboundHandler {
}

func userInboundEventTriggered(context: ChannelHandlerContext, event: Any) {
print(event)
if event is UserAuthSuccessEvent {
self.promise.succeed(())
}
Expand Down
24 changes: 15 additions & 9 deletions Sources/Citadel/TTY/Client/TTY.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,12 @@ final class ExecCommandHandler: ChannelDuplexHandler {
typealias OutboundOut = SSHChannelData

let logger: Logger
let onOutput: (Channel, Output) -> ()

init(logger: Logger, onOutput: @escaping (Channel, Output) -> ()) {
let onOutput: (Channel, Output) -> Void

init(
logger: Logger,
onOutput: @escaping (Channel, Output) -> Void
) {
self.logger = logger
self.onOutput = onOutput
}
Expand Down Expand Up @@ -160,6 +163,7 @@ extension SSHClient {
}

var hasReceivedChannelSuccess = false
var exitCode: Int?

let handler = ExecCommandHandler(logger: logger) { channel, output in
switch output {
Expand All @@ -168,7 +172,13 @@ extension SSHClient {
case .stderr(let stderr):
streamContinuation.yield(.stderr(stderr))
case .eof(let error):
streamContinuation.finish(throwing: error)
if let error {
streamContinuation.finish(throwing: error)
} else if let exitCode, exitCode != 0 {
streamContinuation.finish(throwing: CommandFailed(exitCode: exitCode))
} else {
streamContinuation.finish()
}
case .channelSuccess:
if inShell, !hasReceivedChannelSuccess {
let commandData = SSHChannelData(type: .channel,
Expand All @@ -177,11 +187,7 @@ extension SSHClient {
hasReceivedChannelSuccess = true
}
case .exit(let status):
if status == 0 {
streamContinuation.finish()
} else {
streamContinuation.finish(throwing: CommandFailed(exitCode: status))
}
exitCode = status
}
}

Expand Down
3 changes: 2 additions & 1 deletion Tests/CitadelTests/Citadel2Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,8 @@ final class Citadel2Tests: XCTestCase {
reconnect: .never
)

_ = try await client.executeCommand("ls")
let output = try await client.executeCommand("ls /")
XCTAssertFalse(String(buffer: output).isEmpty)

try await client.close()
}
Expand Down

0 comments on commit f265b4e

Please sign in to comment.