diff --git a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/SignedChunksInputStream.java b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/SignedChunksInputStream.java index a35133f9653..b0dfce64ffa 100644 --- a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/SignedChunksInputStream.java +++ b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/SignedChunksInputStream.java @@ -65,6 +65,46 @@ public int read() throws IOException { } } + @Override + public int read(byte b[], int off, int len) throws IOException { + if (b == null) { + throw new NullPointerException(); + } else if (off < 0 || len < 0 || len > b.length - off) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return 0; + } + int currentOff = off; + int currentLen = len; + int totalReadBytes = 0; + int realReadLen = 0; + int maxReadLen = 0; + do { + if (remainingData > 0) { + maxReadLen = Math.min(remainingData, currentLen); + realReadLen = originalStream.read(b, currentOff, maxReadLen); + if (realReadLen == -1) { + break; + } + currentOff += realReadLen; + currentLen -= realReadLen; + totalReadBytes += realReadLen; + remainingData -= realReadLen; + if (remainingData == 0) { + //read the "\r\n" at the end of the data section + originalStream.read(); + originalStream.read(); + } + } else { + remainingData = readHeader(); + if (remainingData == -1) { + break; + } + } + } while (currentLen > 0); + return totalReadBytes > 0 ? totalReadBytes : -1; + } + private int readHeader() throws IOException { int prev = -1; int curr = 0; diff --git a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/TestSignedChunksInputStream.java b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/TestSignedChunksInputStream.java index f1af7cb3784..3599c059b1f 100644 --- a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/TestSignedChunksInputStream.java +++ b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/TestSignedChunksInputStream.java @@ -49,32 +49,62 @@ public void emptyfile() throws IOException { @Test public void singlechunk() throws IOException { + //test simple read() InputStream is = fileContent("0A;chunk-signature" + "=23abb2bd920ddeeaac78a63ed808bc59fa6e7d3ef0e356474b82cdc2f8c93c40\r" + "\n1234567890\r\n"); String result = IOUtils.toString(is, Charset.forName("UTF-8")); Assert.assertEquals("1234567890", result); + + //test read(byte[],int,int) + is = fileContent("0A;chunk-signature" + + + "=23abb2bd920ddeeaac78a63ed808bc59fa6e7d3ef0e356474b82cdc2f8c93c40\r" + + "\n1234567890\r\n"); + byte[] bytes = new byte[10]; + IOUtils.read(is, bytes, 0, 10); + Assert.assertEquals("1234567890", new String(bytes)); } @Test public void singlechunkwithoutend() throws IOException { + //test simple read() InputStream is = fileContent("0A;chunk-signature" + "=23abb2bd920ddeeaac78a63ed808bc59fa6e7d3ef0e356474b82cdc2f8c93c40\r" + "\n1234567890"); String result = IOUtils.toString(is, Charset.forName("UTF-8")); Assert.assertEquals("1234567890", result); + + //test read(byte[],int,int) + is = fileContent("0A;chunk-signature" + + + "=23abb2bd920ddeeaac78a63ed808bc59fa6e7d3ef0e356474b82cdc2f8c93c40\r" + + "\n1234567890"); + byte[] bytes = new byte[10]; + IOUtils.read(is, bytes, 0, 10); + Assert.assertEquals("1234567890", new String(bytes)); } @Test public void multichunks() throws IOException { + //test simple read() InputStream is = fileContent("0a;chunk-signature=signature\r\n" + "1234567890\r\n" + "05;chunk-signature=signature\r\n" + "abcde\r\n"); String result = IOUtils.toString(is, Charset.forName("UTF-8")); Assert.assertEquals("1234567890abcde", result); + + //test read(byte[],int,int) + is = fileContent("0a;chunk-signature=signature\r\n" + + "1234567890\r\n" + + "05;chunk-signature=signature\r\n" + + "abcde\r\n"); + byte[] bytes = new byte[15]; + IOUtils.read(is, bytes, 0, 15); + Assert.assertEquals("1234567890abcde", new String(bytes)); } private InputStream fileContent(String content) {