This is an automated email from the ASF dual-hosted git repository.

twolf pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git


The following commit(s) were added to refs/heads/master by this push:
     new dc229b9fe [SSHD-1257] ChannelSession: don't flush out stream if 
already closed
dc229b9fe is described below

commit dc229b9fe9c04127bb9086a4393633e57cbdcdef
Author: Vincent Latombe <vinc...@latombe.net>
AuthorDate: Thu Mar 31 15:40:15 2022 +0200

    [SSHD-1257] ChannelSession: don't flush out stream if already closed
    
    Since OutputStream.close() is a no-op when the stream is already closed
    and does flush if not, use close() instead of flush().
    
    This use in ChannelSession is the last use of this OutputStream. It
    may get closed again when the ChannelSession itself closes, but that
    is then just a no-op.
---
 .../apache/sshd/server/channel/ChannelSession.java |  2 +-
 .../sshd/server/channel/ChannelSessionTest.java    | 54 ++++++++++++++++++++++
 2 files changed, 55 insertions(+), 1 deletion(-)

diff --git 
a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java 
b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
index 84b8b72e1..2bba1d46e 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
@@ -908,7 +908,7 @@ public class ChannelSession extends AbstractServerChannel {
 
         if (!isClosing()) {
             if (out != null) {
-                out.flush();
+                out.close();
             }
             sendEof();
             sendExitStatus(exitValue);
diff --git 
a/sshd-core/src/test/java/org/apache/sshd/server/channel/ChannelSessionTest.java
 
b/sshd-core/src/test/java/org/apache/sshd/server/channel/ChannelSessionTest.java
index 803b6c124..af8bf9540 100644
--- 
a/sshd-core/src/test/java/org/apache/sshd/server/channel/ChannelSessionTest.java
+++ 
b/sshd-core/src/test/java/org/apache/sshd/server/channel/ChannelSessionTest.java
@@ -58,6 +58,60 @@ public class ChannelSessionTest extends BaseTestSupport {
         super();
     }
 
+    /**
+     * Testing a command closing output stream when it completes
+     */
+    @Test // see SSHD-1257
+    public void closeOutputStream() throws Exception {
+        try (SshServer server = setupTestServer();
+             SshClient client = setupTestClient()) {
+
+            server.setShellFactory(session -> new CommandExecutionHelper(null) 
{
+                @Override
+                protected boolean handleCommandLine(String command) throws 
Exception {
+                    OutputStream out = getOutputStream();
+                    out.write((command + 
"\n").getBytes(StandardCharsets.UTF_8));
+                    boolean more = !"exit".equals(command);
+                    if (!more) {
+                        out.close();
+                    }
+                    return more;
+                }
+            });
+            server.start();
+            client.start();
+
+            try (ClientSession session = client.connect(getCurrentTestName(), 
TEST_LOCALHOST, server.getPort())
+                    .verify(CONNECT_TIMEOUT).getSession()) {
+                session.addPasswordIdentity(getCurrentTestName());
+                session.auth().verify(AUTH_TIMEOUT);
+
+                try (ClientChannel channel = 
session.createChannel(Channel.CHANNEL_SHELL)) {
+                    channel.open().verify(OPEN_TIMEOUT);
+
+                    OutputStream invertedIn = channel.getInvertedIn();
+                    String cmdSent = "echo foo\nexit\n";
+                    invertedIn.write(cmdSent.getBytes());
+                    invertedIn.flush();
+
+                    long waitStart = System.currentTimeMillis();
+                    Collection<ClientChannelEvent> result
+                            = 
channel.waitFor(EnumSet.of(ClientChannelEvent.CLOSED), 
TimeUnit.SECONDS.toMillis(11L));
+                    long waitEnd = System.currentTimeMillis();
+                    assertTrue("Wrong channel state after " + (waitEnd - 
waitStart) + " ms.: " + result,
+                            
result.containsAll(EnumSet.of(ClientChannelEvent.CLOSED)));
+
+                    byte[] b = new byte[1024];
+                    InputStream invertedOut = channel.getInvertedOut();
+                    int l = invertedOut.read(b);
+                    String cmdReceived = (l > 0) ? new String(b, 0, l) : "";
+
+                    assertEquals("Mismatched echoed command", cmdSent, 
cmdReceived);
+                }
+            }
+        }
+    }
+
     @Test
     public void testNoFlush() throws Exception {
         try (SshServer server = setupTestServer();

Reply via email to