diff --git a/cli/src/main/java/hudson/cli/CLI.java b/cli/src/main/java/hudson/cli/CLI.java index 7835020c604a..dfa172893929 100644 --- a/cli/src/main/java/hudson/cli/CLI.java +++ b/cli/src/main/java/hudson/cli/CLI.java @@ -29,7 +29,6 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.cli.client.Messages; -import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.File; import java.io.IOException; @@ -366,14 +365,21 @@ public void close() throws IOException { ws.set(wsb.buildAsync(URI.create(url.replaceFirst("^http", "ws") + "cli/ws"), new WebSocket.Listener() { @Override public CompletionStage onBinary(WebSocket webSocket, ByteBuffer data, boolean last) { + // TODO if !last, buffer up (though CLIAction.ws does not currently send partial messages) try { - connection.handle(new DataInputStream(new ByteArrayInputStream(data.array()))); + connection.handle(new DataInputStream(new ByteBufferBackedInputStream(data))); } catch (IOException x) { + x.printStackTrace(); LOGGER.log(Level.WARNING, null, x); } + webSocket.request(1); return null; } @Override + public void onOpen(WebSocket webSocket) { + webSocket.request(1); + } + @Override public void onError(WebSocket webSocket, Throwable error) { LOGGER.log(Level.WARNING, null, error); } @@ -400,6 +406,30 @@ public void onError(WebSocket webSocket, Throwable error) { } } + // https://stackoverflow.com/a/6603018/12916 + private static final class ByteBufferBackedInputStream extends InputStream { + final ByteBuffer buf; + ByteBufferBackedInputStream(ByteBuffer buf) { + this.buf = buf; + } + @Override + public int read() throws IOException { + if (!buf.hasRemaining()) { + return -1; + } + return buf.get() & 0xFF; + } + @Override + public int read(byte[] bytes, int off, int len) throws IOException { + if (!buf.hasRemaining()) { + return -1; + } + len = Math.min(len, buf.remaining()); + buf.get(bytes, off, len); + return len; + } + } + private static int plainHttpConnection(String url, List args, CLIConnectionFactory factory) throws GeneralSecurityException, IOException, InterruptedException { LOGGER.log(FINE, "Trying to connect to {0} via plain protocol over HTTP", url);