Source:
private static int plainHttpConnection(String url, List<String> args, CLIConnectionFactory factory) throws IOException, InterruptedException { LOGGER.log(FINE, "Trying to connect to {0} via plain protocol over HTTP", url); URL jenkins = new URL(url + "cli?remoting=false"); FullDuplexHttpStream streams = new FullDuplexHttpStream(jenkins, factory.authorization); class ClientSideImpl extends PlainCLIProtocol.ClientSide { boolean complete; int exit = -1; ClientSideImpl(InputStream is, OutputStream os) throws IOException { super(is, os); if (is.read() != 0) { throw new IOException("expected to see initial zero byte"); } } @Override protected void onExit(int code) { this.exit = code; finished(); } @Override protected void onStdout(byte[] chunk) throws IOException { System.out.write(chunk); } @Override protected void onStderr(byte[] chunk) throws IOException { System.err.write(chunk); } @Override protected void handleClose() { finished(); } private synchronized void finished() { complete = true; notifyAll(); } } try (final ClientSideImpl connection = new ClientSideImpl(streams.getInputStream(), streams.getOutputStream())) { for (String arg : args) { connection.sendArg(arg); } connection.sendEncoding(Charset.defaultCharset().name()); connection.sendLocale(Locale.getDefault().toString()); connection.sendStart(); connection.begin(); final OutputStream stdin = connection.streamStdin(); new Thread("input reader") { @Override public void run() { try { int c; while ((c = System.in.read()) != -1) { stdin.write(c); } connection.sendEndStdin(); } catch (IOException x) { x.printStackTrace(); } } }.start(); synchronized (connection) { while (!connection.complete) { connection.wait(); } } return connection.exit; } }

Target:
private static int plainHttpConnection(String url, List<String> args, CLIConnectionFactory factory) throws IOException, InterruptedException { LOGGER.log(FINE, "Trying to connect to {0} via plain protocol over HTTP", url); FullDuplexHttpStream streams = new FullDuplexHttpStream(new URL(url), "cli?remoting=false", factory.authorization); class ClientSideImpl extends PlainCLIProtocol.ClientSide { boolean complete; int exit = -1; ClientSideImpl(InputStream is, OutputStream os) throws IOException { super(is, os); if (is.read() != 0) { throw new IOException("expected to see initial zero byte; perhaps you are connecting to an old server which does not support -http?"); } } @Override protected void onExit(int code) { this.exit = code; finished(); } @Override protected void onStdout(byte[] chunk) throws IOException { System.out.write(chunk); } @Override protected void onStderr(byte[] chunk) throws IOException { System.err.write(chunk); } @Override protected void handleClose() { finished(); } private synchronized void finished() { complete = true; notifyAll(); } } try (final ClientSideImpl connection = new ClientSideImpl(streams.getInputStream(), streams.getOutputStream())) { for (String arg : args) { connection.sendArg(arg); } connection.sendEncoding(Charset.defaultCharset().name()); connection.sendLocale(Locale.getDefault().toString()); connection.sendStart(); connection.begin(); final OutputStream stdin = connection.streamStdin(); new Thread("input reader") { @Override public void run() { try { int c; while ((c = System.in.read()) != -1) { stdin.write(c); } connection.sendEndStdin(); } catch (IOException x) { LOGGER.log(Level.WARNING, null, x); } } }.start(); synchronized (connection) { while (!connection.complete) { connection.wait(); } } return connection.exit; } }