diff options
author | Roland Grunberg | 2016-12-07 19:23:15 +0000 |
---|---|---|
committer | Jeff Johnston | 2016-12-07 20:57:11 +0000 |
commit | 9a1f34ca2b8519ca21bb32388eed70da5c711db8 (patch) | |
tree | 724c96f11a5f93ee0c03c04e283341188c70dcb2 | |
parent | 83565ae96b4e18b6d9c75b961df81460ff1392f6 (diff) | |
download | org.eclipse.linuxtools-9a1f34ca2b8519ca21bb32388eed70da5c711db8.tar.gz org.eclipse.linuxtools-9a1f34ca2b8519ca21bb32388eed70da5c711db8.tar.xz org.eclipse.linuxtools-9a1f34ca2b8519ca21bb32388eed70da5c711db8.zip |
Bug 508858: Pass a blocking InputStream to the TarArchiveInputStream.
The input stream returned from copyContainer may be passing back
available bytes which may not default to be 0. In this case, the
tar input stream may be reading a header record and treat this
incomplete record as EOF. Also fixed buffering to only write out
what was read (number of bytes).
Change-Id: Icbab8dc460eb613acf6e12cd2f5aba192c52e774
Reviewed-on: https://git.eclipse.org/r/86664
Tested-by: Hudson CI
Reviewed-by: Jeff Johnston <jjohnstn@redhat.com>
-rw-r--r-- | containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CopyFromContainerCommandHandler.java | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CopyFromContainerCommandHandler.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CopyFromContainerCommandHandler.java index 9a28890bd9..a6ad0806a3 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CopyFromContainerCommandHandler.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CopyFromContainerCommandHandler.java @@ -13,6 +13,7 @@ package org.eclipse.linuxtools.internal.docker.ui.commands; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.util.List; import org.apache.commons.compress.archivers.tar.TarArchiveEntry; @@ -109,10 +110,17 @@ public class CopyFromContainerCommandHandler extends AbstractHandler { COPY_FROM_CONTAINER_JOB_SUBTASK, proxy.getFullPath())); monitor.worked(1); + InputStream in = ((DockerConnection) connection) + .copyContainer(container.id(), + proxy.getLink()); + /* + * The input stream from copyContainer might be + * incomplete or non-blocking so we should wrap it + * in a stream that is guaranteed to block until + * data is available. + */ TarArchiveInputStream k = new TarArchiveInputStream( - ((DockerConnection) connection) - .copyContainer(container.id(), - proxy.getLink())); + new BlockingInputStream(in)); TarArchiveEntry te = null; while ((te = k.getNextTarEntry()) != null) { long size = te.getSize(); @@ -126,17 +134,19 @@ public class CopyFromContainerCommandHandler extends AbstractHandler { f.createNewFile(); } FileOutputStream os = new FileOutputStream(f); - if (size > 4096) - size = 4096; - byte[] barray = new byte[(int) size]; - while (k.read(barray) > -1) { + int bufferSize = ((int) size > 4096 ? 4096 + : (int) size); + byte[] barray = new byte[bufferSize]; + int result = -1; + while ((result = k.read(barray, 0, + bufferSize)) > -1) { if (monitor.isCanceled()) { monitor.done(); k.close(); os.close(); return Status.CANCEL_STATUS; } - os.write(barray); + os.write(barray, 0, result); } os.close(); } @@ -172,4 +182,20 @@ public class CopyFromContainerCommandHandler extends AbstractHandler { } + /** + * A blocking input stream that waits until data is available. + */ + public class BlockingInputStream extends InputStream { + private InputStream in; + + public BlockingInputStream(InputStream in) { + this.in = in; + } + + @Override + public int read() throws IOException { + return in.read(); + } + } + } |