diff options
author | Greg Wilkins | 2015-07-23 01:34:59 +0000 |
---|---|---|
committer | Greg Wilkins | 2015-07-23 01:34:59 +0000 |
commit | e1faa5c1e920ee4071c5dc2dab575b9452b4f625 (patch) | |
tree | 12717b50c397303b10ec368c878741e7aa1f3dcd | |
parent | 7686a19db9121c048644908db69e63e99da17ea9 (diff) | |
parent | ac8316756c53e7c2be8b81fa1ecb4f35dabd576e (diff) | |
download | org.eclipse.jetty.project-e1faa5c1e920ee4071c5dc2dab575b9452b4f625.tar.gz org.eclipse.jetty.project-e1faa5c1e920ee4071c5dc2dab575b9452b4f625.tar.xz org.eclipse.jetty.project-e1faa5c1e920ee4071c5dc2dab575b9452b4f625.zip |
Merge remote-tracking branch 'origin/jetty-9.2.x'
Conflicts:
jetty-util/src/main/java/org/eclipse/jetty/util/IO.java
jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceTest.java
4 files changed, 109 insertions, 3 deletions
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java index 81bf8be1cb..573d1b077c 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java @@ -25,6 +25,7 @@ import static org.junit.Assert.fail; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; @@ -33,13 +34,17 @@ import java.net.SocketException; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousServerSocketChannel; import java.nio.channels.AsynchronousSocketChannel; +import java.nio.channels.FileChannel; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.charset.StandardCharsets; +import java.nio.file.StandardOpenOption; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.io.ClientConnectionFactory.Helper; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.OS; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.IO; @@ -452,4 +457,35 @@ public class IOTest Assert.assertEquals(ByteBuffer.wrap(data), read); } + + @Test + public void testGatherWrite() throws Exception + { + File dir = MavenTestingUtils.getTargetTestingDir(); + if (!dir.exists()) + dir.mkdir(); + + File file = File.createTempFile("test",".txt",dir); + file.deleteOnExit(); + FileChannel out = FileChannel.open(file.toPath(), + StandardOpenOption.CREATE, + StandardOpenOption.READ, + StandardOpenOption.WRITE, + StandardOpenOption.DELETE_ON_CLOSE); + + ByteBuffer[] buffers = new ByteBuffer[4096]; + long expected=0; + for (int i=0;i<buffers.length;i++) + { + buffers[i]=BufferUtil.toBuffer(i); + expected+=buffers[i].remaining(); + } + + long wrote = IO.write(out,buffers,0,buffers.length); + + assertEquals(expected,wrote); + + for (int i=0;i<buffers.length;i++) + assertEquals(0,buffers[i].remaining()); + } } diff --git a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AfterContentTransformer.java b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AfterContentTransformer.java index e34aed18f0..b0b919c4e5 100644 --- a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AfterContentTransformer.java +++ b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AfterContentTransformer.java @@ -33,6 +33,7 @@ import java.nio.file.attribute.FileAttribute; import java.util.ArrayList; import java.util.List; +import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.component.Destroyable; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -249,8 +250,9 @@ public abstract class AfterContentTransformer implements AsyncMiddleManServlet.C int size = sourceBuffers.size(); if (size > 0) { - inputFile.write(sourceBuffers.toArray(new ByteBuffer[size])); + ByteBuffer[] buffers = sourceBuffers.toArray(new ByteBuffer[size]); sourceBuffers.clear(); + IO.write(inputFile,buffers,0,buffers.length); } } inputFile.write(input); @@ -421,6 +423,7 @@ public abstract class AfterContentTransformer implements AsyncMiddleManServlet.C return stream; } + private void overflow(ByteBuffer output) throws IOException { if (outputFile == null) @@ -434,8 +437,10 @@ public abstract class AfterContentTransformer implements AsyncMiddleManServlet.C int size = sinkBuffers.size(); if (size > 0) { - outputFile.write(sinkBuffers.toArray(new ByteBuffer[size])); + ByteBuffer[] buffers = sinkBuffers.toArray(new ByteBuffer[size]); sinkBuffers.clear(); + + IO.write(outputFile,buffers,0,buffers.length); } } outputFile.write(output); diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/IO.java b/jetty-util/src/main/java/org/eclipse/jetty/util/IO.java index f89068a489..355936b0d9 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/IO.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/IO.java @@ -30,6 +30,9 @@ import java.io.PrintWriter; import java.io.Reader; import java.io.StringWriter; import java.io.Writer; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.channels.GatheringByteChannel; import java.nio.charset.Charset; import org.eclipse.jetty.util.log.Log; @@ -415,9 +418,55 @@ public class IO copy(in,bout); return bout.toByteArray(); } - + /* ------------------------------------------------------------ */ /** + * A gathering write utility wrapper. + * <p>This method wraps a gather write with a loop that handles the limitations of some operating systems that + * have a limit on the number of buffers written. The method loops on the write until either all the content + * is written or no progress is made. + * @param out The GatheringgByteChannel to write to + * @param buffers The buffers to write + * @param offset The offset into the buffers array + * @param length The length in buffers to write + * @return The total bytes written + * @throws IOException + */ + public static long write(GatheringByteChannel out, ByteBuffer[] buffers, int offset, int length) throws IOException + { + long total=0; + write: while (length>0) + { + // Write as much as we can + long wrote=out.write(buffers,offset,length); + + // If we can't write any more, give up + if (wrote==0) + break; + + // count the total + total+=wrote; + + // Look for unwritten content + for (int i=offset;i<buffers.length;i++) + { + if (buffers[i].hasRemaining()) + { + // loop with new offset and length; + length=length-(i-offset); + offset=i; + continue write; + } + } + length=0; + } + + return total; + } + + + /* ------------------------------------------------------------ */ + /** * @return An outputstream to nowhere */ public static OutputStream getNullStream() @@ -503,6 +552,7 @@ public class IO } private static NullWrite __nullWriter = new NullWrite(); private static PrintWriter __nullPrintWriter = new PrintWriter(__nullWriter); + } diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceTest.java index 89c600c50c..33258d0e1d 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceTest.java @@ -187,6 +187,21 @@ public class ResourceTest return bdata; } } + + /* ------------------------------------------------------------ */ + @Test + public void testEncodeAddPath () + throws Exception + { + Resource r; + + r = Resource.newResource(__userURL+"TestData/").addPath("foo%/b r"); + Assert.assertThat(r.getURI().toString(),Matchers.endsWith("/foo%25/b%20r")); + + r = Resource.newResource("jar:"+__userURL+"TestData/test.zip!/subdir/").addPath("foo%/b r"); + Assert.assertThat(r.getURI().toString(),Matchers.endsWith("/foo%25/b%20r")); + } + @Parameters(name="{0}") |