diff --git a/pom.xml b/pom.xml
index 2b5fe2119..9ee5cad51 100644
--- a/pom.xml
+++ b/pom.xml
@@ -67,6 +67,7 @@
1.3
1.6
2.3.3
+ 1.10.19
2.2
@@ -195,6 +196,13 @@
test
+
+ org.mockito
+ mockito-core
+ ${mockito.version}
+ test
+
+
com.google.code.findbugs
annotations
diff --git a/src/main/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandler.java b/src/main/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandler.java
index d4f19f2e3..706228d04 100644
--- a/src/main/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandler.java
+++ b/src/main/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandler.java
@@ -81,7 +81,7 @@ public int read() throws IOException {
}
if (current != null && current.readableBytes() > 0) {
- return current.readByte();
+ return current.readByte() & 0xff;
} else {
return read();
}
diff --git a/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveFromContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveFromContainerCmdExecTest.java
index aa4dcc575..caec336a2 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveFromContainerCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveFromContainerCmdExecTest.java
@@ -6,7 +6,14 @@
import java.io.InputStream;
import java.lang.reflect.Method;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
+import org.apache.commons.io.IOUtils;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
@@ -16,6 +23,7 @@
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.exception.NotFoundException;
+import com.github.dockerjava.core.util.CompressArchiveUtil;
import com.github.dockerjava.netty.AbstractNettyDockerClientTest;
@Test(groups = "integration")
@@ -70,4 +78,36 @@ public void copyFromNonExistingContainer() throws Exception {
} catch (NotFoundException ignored) {
}
}
+
+ @Test
+ public void copyFromContainerBinaryFile() throws Exception {
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox")
+ .withName("docker-java-itest-copyFromContainerBinaryFile").exec();
+
+ LOG.info("Created container: {}", container);
+ assertThat(container.getId(), not(isEmptyOrNullString()));
+
+ Path temp = Files.createTempFile("", ".tar.gz");
+ Path binaryFile = Paths.get("src/test/resources/testCopyFromArchive/binary.dat");
+ CompressArchiveUtil.tar(binaryFile, temp, true, false);
+
+ try (InputStream uploadStream = Files.newInputStream(temp)) {
+ dockerClient.copyArchiveToContainerCmd(container.getId()).withTarInputStream(uploadStream).exec();
+ }
+
+ InputStream response = dockerClient.copyArchiveFromContainerCmd(container.getId(), "/binary.dat").exec();
+ Boolean bytesAvailable = response.available() > 0;
+ assertTrue(bytesAvailable, "The file was not copied from the container.");
+
+ try (TarArchiveInputStream tarInputStream = new TarArchiveInputStream(response)) {
+ TarArchiveEntry nextTarEntry = tarInputStream.getNextTarEntry();
+
+ assertEquals(nextTarEntry.getName(), "binary.dat");
+ try (InputStream binaryFileInputStream = Files.newInputStream(binaryFile, StandardOpenOption.READ)) {
+ assertTrue(IOUtils.contentEquals(binaryFileInputStream, tarInputStream));
+ }
+
+ assertNull(tarInputStream.getNextTarEntry(), "Nothing except binary.dat is expected to be copied.");
+ }
+ }
}
diff --git a/src/test/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandlerTest.java b/src/test/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandlerTest.java
new file mode 100644
index 000000000..6652f3eba
--- /dev/null
+++ b/src/test/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandlerTest.java
@@ -0,0 +1,53 @@
+package com.github.dockerjava.netty.handler;
+
+import static org.testng.Assert.assertTrue;
+
+import java.io.InputStream;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufInputStream;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import org.apache.commons.io.IOUtils;
+import org.mockito.Mockito;
+import org.testng.annotations.Test;
+
+import com.github.dockerjava.core.async.ResultCallbackTemplate;
+
+/**
+ * @author Alexander Koshevoy
+ */
+public class HttpResponseStreamHandlerTest {
+ @Test
+ public void testNoBytesSkipped() throws Exception {
+ ResultCallbackTest callback = new ResultCallbackTest();
+ HttpResponseStreamHandler streamHandler = new HttpResponseStreamHandler(callback);
+ ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class);
+ ByteBuf buffer = generateByteBuf();
+ streamHandler.channelRead0(ctx, buffer);
+ streamHandler.channelReadComplete(ctx);
+
+ assertTrue(IOUtils.contentEquals(callback.getInputStream(), new ByteBufInputStream(buffer)));
+ }
+
+ private ByteBuf generateByteBuf() {
+ byte[] array = new byte[256];
+ for (int i = 0; i < array.length; i++) {
+ array[i] = (byte) i;
+ }
+ return Unpooled.copiedBuffer(array);
+ }
+
+ private static class ResultCallbackTest extends ResultCallbackTemplate {
+ private InputStream stream;
+
+ @Override
+ public void onNext(InputStream stream) {
+ this.stream = stream;
+ }
+
+ public InputStream getInputStream() {
+ return stream;
+ }
+ }
+}
diff --git a/src/test/resources/testCopyFromArchive/binary.dat b/src/test/resources/testCopyFromArchive/binary.dat
new file mode 100644
index 000000000..61bcc872c
Binary files /dev/null and b/src/test/resources/testCopyFromArchive/binary.dat differ