You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by "Guillaume Nodet (JIRA)" <ji...@apache.org> on 2018/05/28 09:39:00 UTC

[jira] [Resolved] (SSHD-449) SSH Exec channel with ClientChannel.Streaming.Async

     [ https://issues.apache.org/jira/browse/SSHD-449?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Guillaume Nodet resolved SSHD-449.
----------------------------------
    Resolution: Fixed

> 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
>            Assignee: Guillaume Nodet
>            Priority: Critical
>             Fix For: 2.0.0
>
>
> 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
(v7.6.3#76005)