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
This commit is contained in:
commit
e1faa5c1e9
|
@ -25,6 +25,7 @@ import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
|
@ -33,13 +34,17 @@ import java.net.SocketException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.AsynchronousServerSocketChannel;
|
import java.nio.channels.AsynchronousServerSocketChannel;
|
||||||
import java.nio.channels.AsynchronousSocketChannel;
|
import java.nio.channels.AsynchronousSocketChannel;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
import java.nio.channels.ServerSocketChannel;
|
import java.nio.channels.ServerSocketChannel;
|
||||||
import java.nio.channels.SocketChannel;
|
import java.nio.channels.SocketChannel;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.StandardOpenOption;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
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.toolchain.test.OS;
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.util.IO;
|
import org.eclipse.jetty.util.IO;
|
||||||
|
@ -452,4 +457,35 @@ public class IOTest
|
||||||
|
|
||||||
Assert.assertEquals(ByteBuffer.wrap(data), read);
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ import java.nio.file.attribute.FileAttribute;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.util.IO;
|
||||||
import org.eclipse.jetty.util.component.Destroyable;
|
import org.eclipse.jetty.util.component.Destroyable;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
@ -249,8 +250,9 @@ public abstract class AfterContentTransformer implements AsyncMiddleManServlet.C
|
||||||
int size = sourceBuffers.size();
|
int size = sourceBuffers.size();
|
||||||
if (size > 0)
|
if (size > 0)
|
||||||
{
|
{
|
||||||
inputFile.write(sourceBuffers.toArray(new ByteBuffer[size]));
|
ByteBuffer[] buffers = sourceBuffers.toArray(new ByteBuffer[size]);
|
||||||
sourceBuffers.clear();
|
sourceBuffers.clear();
|
||||||
|
IO.write(inputFile,buffers,0,buffers.length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inputFile.write(input);
|
inputFile.write(input);
|
||||||
|
@ -421,6 +423,7 @@ public abstract class AfterContentTransformer implements AsyncMiddleManServlet.C
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void overflow(ByteBuffer output) throws IOException
|
private void overflow(ByteBuffer output) throws IOException
|
||||||
{
|
{
|
||||||
if (outputFile == null)
|
if (outputFile == null)
|
||||||
|
@ -434,8 +437,10 @@ public abstract class AfterContentTransformer implements AsyncMiddleManServlet.C
|
||||||
int size = sinkBuffers.size();
|
int size = sinkBuffers.size();
|
||||||
if (size > 0)
|
if (size > 0)
|
||||||
{
|
{
|
||||||
outputFile.write(sinkBuffers.toArray(new ByteBuffer[size]));
|
ByteBuffer[] buffers = sinkBuffers.toArray(new ByteBuffer[size]);
|
||||||
sinkBuffers.clear();
|
sinkBuffers.clear();
|
||||||
|
|
||||||
|
IO.write(outputFile,buffers,0,buffers.length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
outputFile.write(output);
|
outputFile.write(output);
|
||||||
|
|
|
@ -30,6 +30,9 @@ import java.io.PrintWriter;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
|
import java.nio.channels.GatheringByteChannel;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
|
@ -415,9 +418,55 @@ public class IO
|
||||||
copy(in,bout);
|
copy(in,bout);
|
||||||
return bout.toByteArray();
|
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
|
* @return An outputstream to nowhere
|
||||||
*/
|
*/
|
||||||
public static OutputStream getNullStream()
|
public static OutputStream getNullStream()
|
||||||
|
@ -503,6 +552,7 @@ public class IO
|
||||||
}
|
}
|
||||||
private static NullWrite __nullWriter = new NullWrite();
|
private static NullWrite __nullWriter = new NullWrite();
|
||||||
private static PrintWriter __nullPrintWriter = new PrintWriter(__nullWriter);
|
private static PrintWriter __nullPrintWriter = new PrintWriter(__nullWriter);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -187,6 +187,21 @@ public class ResourceTest
|
||||||
return bdata;
|
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}")
|
@Parameters(name="{0}")
|
||||||
|
|
Loading…
Reference in New Issue