Yarin Benado created SSHD-449:
---------------------------------

             Summary: SSH Exec channel with ClientChannel.Streaming.Async 
                 Key: SSHD-449
                 URL: https://issues.apache.org/jira/browse/SSHD-449
             Project: MINA SSHD
          Issue Type: Bug
    Affects Versions: 0.14.0
            Reporter: Yarin Benado
            Priority: Critical


It looks like there is an issue with combining exec channel with 
ClientChannel.Streaming.Async.

You cannot use the channel.gerAsyncOut() to add a listener to it before the 
channel is opened, therefore open() call on the channel will fire the command 
to the server, and response might arrive before there are any listeners 
attached.
If a listener is not attached in-time (in the test below even 100 millis are 
suffice to cause it to miss the registration) the channel simply returns an 
empty output on the stream.


Here is a test added in ClientTest.java that reproduces the problem:
{code}
@Test
public void testExecAsyncClient() throws Exception {
    client.start();
    ClientSession session = client.connect("smx", "localhost", 
port).await().getSession();
    session.addPasswordIdentity("smx");
    session.auth().verify();
    final ByteArrayOutputStream baosOut = new ByteArrayOutputStream();
    final ByteArrayOutputStream baosErr = new ByteArrayOutputStream();

    final ChannelExec channel = session.createExecChannel("test");
    channel.setStreaming(ClientChannel.Streaming.Async);
    OpenFuture open = channel.open();

    
    Thread.sleep(100); // Removing this line will make the test succeed
    open.addListener(new SshFutureListener<OpenFuture>() {
        public void operationComplete(OpenFuture future) {
            channel.getAsyncOut().read(new Buffer())
                    .addListener(new SshFutureListener<IoReadFuture>() {
                        public void operationComplete(IoReadFuture future) {
                            try {
                                future.verify();
                                Buffer buffer = future.getBuffer();
                                baosOut.write(buffer.array(), buffer.rpos(), 
buffer.available());
                                buffer.rpos(buffer.rpos() + buffer.available());
                                buffer.compact();
                                
channel.getAsyncOut().read(buffer).addListener(this);
                            } catch (IOException e) {
                                if (!channel.isClosing()) {
                                    e.printStackTrace();
                                    channel.close(true);
                                }
                            }
                        }
                    });
            channel.getAsyncErr().read(new Buffer())
                    .addListener(new SshFutureListener<IoReadFuture>() {
                        public void operationComplete(IoReadFuture future) {
                            try {
                                future.verify();
                                Buffer buffer = future.getBuffer();
                                baosErr.write(buffer.array(), buffer.rpos(), 
buffer.available());
                                buffer.rpos(buffer.rpos() + buffer.available());
                                buffer.compact();
                                
channel.getAsyncErr().read(buffer).addListener(this);
                            } catch (IOException e) {
                                if (!channel.isClosing()) {
                                    e.printStackTrace();
                                    channel.close(true);
                                }
                            }
                        }
                    });
        }
    });

    channel.waitFor(ClientChannel.CLOSED, 0);

    assertFalse(baosErr.size() == 0);

    client.close(true);
}
{code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to