jetty-9 progress on jetty-server
This commit is contained in:
parent
979dae0021
commit
e348f2d4f5
|
@ -152,6 +152,12 @@ public enum HttpHeader
|
||||||
{
|
{
|
||||||
return _string.equalsIgnoreCase(s);
|
return _string.equalsIgnoreCase(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public String asString()
|
||||||
|
{
|
||||||
|
return _string;
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -60,8 +60,20 @@ public enum HttpMethod
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public ByteBuffer toBuffer()
|
public boolean is(String s)
|
||||||
|
{
|
||||||
|
return toString().equalsIgnoreCase(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public ByteBuffer asBuffer()
|
||||||
{
|
{
|
||||||
return _buffer.asReadOnlyBuffer();
|
return _buffer.asReadOnlyBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public String asString()
|
||||||
|
{
|
||||||
|
return toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ public class MimeTypes
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public ByteBuffer toBuffer()
|
public ByteBuffer asBuffer()
|
||||||
{
|
{
|
||||||
return _buffer.asReadOnlyBuffer();
|
return _buffer.asReadOnlyBuffer();
|
||||||
}
|
}
|
||||||
|
@ -86,6 +86,12 @@ public class MimeTypes
|
||||||
{
|
{
|
||||||
return _string.equalsIgnoreCase(s);
|
return _string.equalsIgnoreCase(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public String asString()
|
||||||
|
{
|
||||||
|
return _string;
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
@Override
|
@Override
|
||||||
|
@ -99,22 +105,21 @@ public class MimeTypes
|
||||||
private static final Logger LOG = Log.getLogger(MimeTypes.class);
|
private static final Logger LOG = Log.getLogger(MimeTypes.class);
|
||||||
public final static StringMap<MimeTypes.Type> CACHE= new StringMap<MimeTypes.Type>(true);
|
public final static StringMap<MimeTypes.Type> CACHE= new StringMap<MimeTypes.Type>(true);
|
||||||
private final static StringMap<ByteBuffer> TYPES= new StringMap<ByteBuffer>(true);
|
private final static StringMap<ByteBuffer> TYPES= new StringMap<ByteBuffer>(true);
|
||||||
private final static Map<String,ByteBuffer> __dftMimeMap = new HashMap<String,ByteBuffer>();
|
private final static Map<String,String> __dftMimeMap = new HashMap<String,String>();
|
||||||
private final static Map<String,String> __encodings = new HashMap<String,String>();
|
private final static Map<String,String> __encodings = new HashMap<String,String>();
|
||||||
|
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
|
|
||||||
for (MimeTypes.Type type : MimeTypes.Type.values())
|
for (MimeTypes.Type type : MimeTypes.Type.values())
|
||||||
{
|
{
|
||||||
CACHE.put(type.toString(),type);
|
CACHE.put(type.toString(),type);
|
||||||
TYPES.put(type.toString(),type.toBuffer());
|
TYPES.put(type.toString(),type.asBuffer());
|
||||||
|
|
||||||
int charset=type.toString().indexOf(";charset=");
|
int charset=type.toString().indexOf(";charset=");
|
||||||
if (charset>0)
|
if (charset>0)
|
||||||
{
|
{
|
||||||
CACHE.put(type.toString().replace(";charset=","; charset="),type);
|
CACHE.put(type.toString().replace(";charset=","; charset="),type);
|
||||||
TYPES.put(type.toString().replace(";charset=","; charset="),type.toBuffer());
|
TYPES.put(type.toString().replace(";charset=","; charset="),type.asBuffer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,13 +155,11 @@ public class MimeTypes
|
||||||
LOG.warn(e.toString());
|
LOG.warn(e.toString());
|
||||||
LOG.debug(e);
|
LOG.debug(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
private final Map<String,ByteBuffer> _mimeMap=new HashMap<String,ByteBuffer>();
|
private final Map<String,String> _mimeMap=new HashMap<String,String>();
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/** Constructor.
|
/** Constructor.
|
||||||
|
@ -166,7 +169,7 @@ public class MimeTypes
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public synchronized Map<String,ByteBuffer> getMimeMap()
|
public synchronized Map<String,String> getMimeMap()
|
||||||
{
|
{
|
||||||
return _mimeMap;
|
return _mimeMap;
|
||||||
}
|
}
|
||||||
|
@ -191,9 +194,9 @@ public class MimeTypes
|
||||||
* @return MIME type matching the longest dot extension of the
|
* @return MIME type matching the longest dot extension of the
|
||||||
* file name.
|
* file name.
|
||||||
*/
|
*/
|
||||||
public ByteBuffer getMimeByExtension(String filename)
|
public String getMimeByExtension(String filename)
|
||||||
{
|
{
|
||||||
ByteBuffer type=null;
|
String type=null;
|
||||||
|
|
||||||
if (filename!=null)
|
if (filename!=null)
|
||||||
{
|
{
|
||||||
|
@ -235,13 +238,13 @@ public class MimeTypes
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
private static ByteBuffer normalizeMimeType(String type)
|
private static String normalizeMimeType(String type)
|
||||||
{
|
{
|
||||||
MimeTypes.Type t =CACHE.get(type);
|
MimeTypes.Type t =CACHE.get(type);
|
||||||
if (t!=null)
|
if (t!=null)
|
||||||
return t.toBuffer();
|
return t.asString();
|
||||||
|
|
||||||
return BufferUtil.toBuffer(StringUtil.asciiToLowerCase(type));
|
return StringUtil.asciiToLowerCase(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
|
|
@ -46,10 +46,10 @@ public class MimeTypesTest
|
||||||
private void assertMimeTypeByExtension(String expectedMimeType, String filename)
|
private void assertMimeTypeByExtension(String expectedMimeType, String filename)
|
||||||
{
|
{
|
||||||
MimeTypes mimetypes = new MimeTypes();
|
MimeTypes mimetypes = new MimeTypes();
|
||||||
ByteBuffer contentType = mimetypes.getMimeByExtension(filename);
|
String contentType = mimetypes.getMimeByExtension(filename);
|
||||||
String prefix = "MimeTypes.getMimeByExtension(" + filename + ")";
|
String prefix = "MimeTypes.getMimeByExtension(" + filename + ")";
|
||||||
assertNotNull(prefix,contentType);
|
assertNotNull(prefix,contentType);
|
||||||
assertEquals(prefix,expectedMimeType,BufferUtil.toString(contentType));
|
assertEquals(prefix,expectedMimeType,contentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package org.eclipse.jetty.io;
|
package org.eclipse.jetty.io;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.Callback;
|
import org.eclipse.jetty.util.Callback;
|
||||||
|
import org.eclipse.jetty.util.ExecutorCallback;
|
||||||
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;
|
||||||
|
|
||||||
|
@ -11,21 +13,40 @@ public abstract class AbstractAsyncConnection implements AsyncConnection
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(AbstractAsyncConnection.class);
|
private static final Logger LOG = Log.getLogger(AbstractAsyncConnection.class);
|
||||||
private final AsyncEndPoint _endp;
|
private final AsyncEndPoint _endp;
|
||||||
private final ReadCallback _readCallback = new ReadCallback();
|
private final Callback<Void> _readCallback;
|
||||||
private final AtomicBoolean _readInterested = new AtomicBoolean();
|
private final AtomicBoolean _readInterested = new AtomicBoolean();
|
||||||
|
|
||||||
public AbstractAsyncConnection(AsyncEndPoint endp)
|
/* ------------------------------------------------------------ */
|
||||||
|
public AbstractAsyncConnection(AsyncEndPoint endp,Executor executor)
|
||||||
{
|
{
|
||||||
_endp=endp;
|
_endp=endp;
|
||||||
}
|
_readCallback= new ExecutorCallback<Void>(executor)
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected void onCompleted(Void context)
|
||||||
|
{
|
||||||
|
if (_readInterested.compareAndSet(true,false))
|
||||||
|
onReadable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onFailed(Void context, Throwable x)
|
||||||
|
{
|
||||||
|
onReadFail(x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
public abstract void onReadable();
|
public abstract void onReadable();
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
@Override
|
@Override
|
||||||
public void onOpen()
|
public void onOpen()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
@Override
|
@Override
|
||||||
public void onClose()
|
public void onClose()
|
||||||
{
|
{
|
||||||
|
@ -75,46 +96,4 @@ public abstract class AbstractAsyncConnection implements AsyncConnection
|
||||||
{
|
{
|
||||||
return String.format("%s@%x", getClass().getSimpleName(), hashCode());
|
return String.format("%s@%x", getClass().getSimpleName(), hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
private class ReadCallback implements Callback<Void>
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void completed(Void context)
|
|
||||||
{
|
|
||||||
if (_readInterested.compareAndSet(true,false))
|
|
||||||
{
|
|
||||||
new Thread(new Runnable()
|
|
||||||
{
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
onReadable();
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void failed(Void context, final Throwable x)
|
|
||||||
{
|
|
||||||
if (_readInterested.compareAndSet(true,false))
|
|
||||||
{
|
|
||||||
new Thread(new Runnable()
|
|
||||||
{
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
onReadFail(x);
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
return String.format("%s@%x",getClass().getSimpleName(),hashCode());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,6 +115,9 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements SelectorMa
|
||||||
@Override
|
@Override
|
||||||
public void onSelected()
|
public void onSelected()
|
||||||
{
|
{
|
||||||
|
boolean can_read;
|
||||||
|
boolean can_write;
|
||||||
|
|
||||||
synchronized (_lock)
|
synchronized (_lock)
|
||||||
{
|
{
|
||||||
_selected = true;
|
_selected = true;
|
||||||
|
@ -122,21 +125,11 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements SelectorMa
|
||||||
{
|
{
|
||||||
// If there is no key, then do nothing
|
// If there is no key, then do nothing
|
||||||
if (_key == null || !_key.isValid())
|
if (_key == null || !_key.isValid())
|
||||||
{
|
|
||||||
// TODO wake ups?
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// TODO do we need to test interest here ???
|
can_read = (_key.isReadable() && (_key.interestOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ);
|
||||||
boolean can_read = (_key.isReadable() && (_key.interestOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ);
|
can_write = (_key.isWritable() && (_key.interestOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE);
|
||||||
boolean can_write = (_key.isWritable() && (_key.interestOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE);
|
|
||||||
_interestOps = 0;
|
_interestOps = 0;
|
||||||
|
|
||||||
if (can_read)
|
|
||||||
readCompleted();
|
|
||||||
if (can_write)
|
|
||||||
completeWrite();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -144,6 +137,10 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements SelectorMa
|
||||||
_selected = false;
|
_selected = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (can_read)
|
||||||
|
readCompleted();
|
||||||
|
if (can_write)
|
||||||
|
completeWrite();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -212,8 +209,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements SelectorMa
|
||||||
Object ctx=_readContext;
|
Object ctx=_readContext;
|
||||||
_readCallback=null;
|
_readCallback=null;
|
||||||
_readContext=null;
|
_readContext=null;
|
||||||
System.err.printf("ReadComplete %s %s%n",ctx,cb);
|
cb.completed(ctx);
|
||||||
cb.completed(ctx); // TODO after lock released?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,8 +223,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements SelectorMa
|
||||||
_writeCallback=null;
|
_writeCallback=null;
|
||||||
_writeContext=null;
|
_writeContext=null;
|
||||||
_writeBuffers=null;
|
_writeBuffers=null;
|
||||||
System.err.printf("writeComplete %s %s%n",ctx,cb);
|
cb.completed(ctx);
|
||||||
cb.completed(ctx); // TODO after lock released?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,8 +236,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements SelectorMa
|
||||||
Object ctx=_readContext;
|
Object ctx=_readContext;
|
||||||
_readCallback=null;
|
_readCallback=null;
|
||||||
_readContext=null;
|
_readContext=null;
|
||||||
System.err.printf("ReadFail %s %s%n",ctx,cb);
|
cb.failed(ctx,cause);
|
||||||
cb.failed(ctx,cause); // TODO after lock released?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,8 +249,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements SelectorMa
|
||||||
Object ctx=_writeContext;
|
Object ctx=_writeContext;
|
||||||
_writeCallback=null;
|
_writeCallback=null;
|
||||||
_writeContext=null;
|
_writeContext=null;
|
||||||
System.err.printf("writeFailed %s %s%n",ctx,cb);
|
cb.failed(ctx,cause);
|
||||||
cb.failed(ctx,cause); // TODO after lock released?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ package org.eclipse.jetty.io;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
@ -101,19 +102,18 @@ public class SslConnection extends AbstractAsyncConnection
|
||||||
_outNet=BufferUtil.allocateDirect(packetSize);
|
_outNet=BufferUtil.allocateDirect(packetSize);
|
||||||
_inApp=BufferUtil.allocate(appSize);
|
_inApp=BufferUtil.allocate(appSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public SslConnection(SSLEngine engine,AsyncEndPoint endp)
|
public SslConnection(SSLEngine engine,AsyncEndPoint endp,Executor executor)
|
||||||
{
|
{
|
||||||
this(engine,endp,System.currentTimeMillis());
|
this(engine,endp,System.currentTimeMillis(),executor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public SslConnection(SSLEngine engine,AsyncEndPoint endp, long timeStamp)
|
public SslConnection(SSLEngine engine,AsyncEndPoint endp, long timeStamp,Executor executor)
|
||||||
{
|
{
|
||||||
super(endp);
|
super(endp, executor);
|
||||||
_engine=engine;
|
_engine=engine;
|
||||||
_session=_engine.getSession();
|
_session=_engine.getSession();
|
||||||
_endp=endp;
|
_endp=endp;
|
||||||
|
|
|
@ -102,8 +102,6 @@ public class ByteArrayEndPointTest
|
||||||
|
|
||||||
assertEquals(5,endp.flush(data));
|
assertEquals(5,endp.flush(data));
|
||||||
assertEquals("data.",BufferUtil.toString(endp.takeOutput()));
|
assertEquals("data.",BufferUtil.toString(endp.takeOutput()));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ import javax.net.ssl.SSLSocket;
|
||||||
|
|
||||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||||
|
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
|
@ -45,7 +46,7 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
|
||||||
{
|
{
|
||||||
SSLEngine engine = __sslCtxFactory.newSslEngine();
|
SSLEngine engine = __sslCtxFactory.newSslEngine();
|
||||||
engine.setUseClientMode(false);
|
engine.setUseClientMode(false);
|
||||||
SslConnection connection = new SslConnection(engine,endpoint);
|
SslConnection connection = new SslConnection(engine,endpoint,_threadPool);
|
||||||
|
|
||||||
AsyncConnection delegate = super.newConnection(channel,connection.getAppEndPoint());
|
AsyncConnection delegate = super.newConnection(channel,connection.getAppEndPoint());
|
||||||
connection.getAppEndPoint().setAsyncConnection(delegate);
|
connection.getAppEndPoint().setAsyncConnection(delegate);
|
||||||
|
|
|
@ -117,7 +117,7 @@ public class SelectChannelEndPointTest
|
||||||
|
|
||||||
public TestConnection(AsyncEndPoint endp)
|
public TestConnection(AsyncEndPoint endp)
|
||||||
{
|
{
|
||||||
super(endp);
|
super(endp,_threadPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -139,17 +139,14 @@ public class SelectChannelEndPointTest
|
||||||
int filled=_endp.fill(_in);
|
int filled=_endp.fill(_in);
|
||||||
if (filled>0)
|
if (filled>0)
|
||||||
progress=true;
|
progress=true;
|
||||||
System.err.println("filled "+filled);
|
|
||||||
|
|
||||||
// If the tests wants to block, then block
|
// If the tests wants to block, then block
|
||||||
while (_blockAt>0 && _endp.isOpen() && _in.remaining()<_blockAt)
|
while (_blockAt>0 && _endp.isOpen() && _in.remaining()<_blockAt)
|
||||||
{
|
{
|
||||||
FutureCallback<Void> blockingRead= new FutureCallback<>();
|
FutureCallback<Void> blockingRead= new FutureCallback<>();
|
||||||
System.err.println("blocking read on "+blockingRead);
|
|
||||||
_endp.readable(null,blockingRead);
|
_endp.readable(null,blockingRead);
|
||||||
blockingRead.get();
|
blockingRead.get();
|
||||||
filled=_endp.fill(_in);
|
filled=_endp.fill(_in);
|
||||||
System.err.println("FILLED "+filled);
|
|
||||||
progress|=filled>0;
|
progress|=filled>0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ package org.eclipse.jetty.server;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
import javax.servlet.ServletRequest;
|
import javax.servlet.ServletRequest;
|
||||||
|
@ -24,6 +25,7 @@ import org.eclipse.jetty.http.HttpFields;
|
||||||
import org.eclipse.jetty.http.HttpHeader;
|
import org.eclipse.jetty.http.HttpHeader;
|
||||||
import org.eclipse.jetty.http.HttpScheme;
|
import org.eclipse.jetty.http.HttpScheme;
|
||||||
import org.eclipse.jetty.io.AsyncConnection;
|
import org.eclipse.jetty.io.AsyncConnection;
|
||||||
|
import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
import org.eclipse.jetty.io.EndPoint;
|
import org.eclipse.jetty.io.EndPoint;
|
||||||
import org.eclipse.jetty.io.EofException;
|
import org.eclipse.jetty.io.EofException;
|
||||||
import org.eclipse.jetty.server.Connector.Statistics;
|
import org.eclipse.jetty.server.Connector.Statistics;
|
||||||
|
@ -53,13 +55,14 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co
|
||||||
private String _name;
|
private String _name;
|
||||||
|
|
||||||
private Server _server;
|
private Server _server;
|
||||||
private ThreadPool _threadPool;
|
private Executor _executor;
|
||||||
private String _host;
|
private String _host;
|
||||||
private int _port = 0;
|
private int _port = 0;
|
||||||
private int _acceptQueueSize = 0;
|
private int _acceptQueueSize = 0;
|
||||||
private int _acceptors = 1;
|
private int _acceptors = 1;
|
||||||
private int _acceptorPriorityOffset = 0;
|
private int _acceptorPriorityOffset = 0;
|
||||||
private boolean _reuseAddress = true;
|
private boolean _reuseAddress = true;
|
||||||
|
private ByteBufferPool _byteBufferPool;
|
||||||
|
|
||||||
private final Statistics _stats = new ConnectionStatistics();
|
private final Statistics _stats = new ConnectionStatistics();
|
||||||
|
|
||||||
|
@ -99,22 +102,40 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public ThreadPool getThreadPool()
|
public Executor findExecutor()
|
||||||
{
|
{
|
||||||
return _threadPool;
|
if (_executor==null && getServer()!=null)
|
||||||
|
return getServer().getThreadPool();
|
||||||
|
return _executor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
|
public Executor getExecutor()
|
||||||
|
{
|
||||||
|
return _executor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/** Set the ThreadPool.
|
public void setExecutor(Executor executor)
|
||||||
* The threadpool passed is added via {@link #addBean(Object)} so that
|
|
||||||
* it's lifecycle may be managed as a {@link AggregateLifeCycle}.
|
|
||||||
* @param threadPool the threadPool to set
|
|
||||||
*/
|
|
||||||
public void setThreadPool(ThreadPool pool)
|
|
||||||
{
|
{
|
||||||
removeBean(_threadPool);
|
removeBean(_executor);
|
||||||
_threadPool = pool;
|
_executor=executor;
|
||||||
addBean(_threadPool);
|
addBean(_executor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
|
public ByteBufferPool getByteBufferPool()
|
||||||
|
{
|
||||||
|
return _byteBufferPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setByteBufferPool(ByteBufferPool byteBufferPool)
|
||||||
|
{
|
||||||
|
removeBean(byteBufferPool);
|
||||||
|
_byteBufferPool = byteBufferPool;
|
||||||
|
addBean(_byteBufferPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -251,12 +272,6 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co
|
||||||
// open listener port
|
// open listener port
|
||||||
open();
|
open();
|
||||||
|
|
||||||
if (_threadPool == null)
|
|
||||||
{
|
|
||||||
_threadPool = _server.getThreadPool();
|
|
||||||
addBean(_threadPool,false);
|
|
||||||
}
|
|
||||||
|
|
||||||
super.doStart();
|
super.doStart();
|
||||||
|
|
||||||
// Start selector thread
|
// Start selector thread
|
||||||
|
@ -265,10 +280,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co
|
||||||
_acceptorThreads = new Thread[getAcceptors()];
|
_acceptorThreads = new Thread[getAcceptors()];
|
||||||
|
|
||||||
for (int i = 0; i < _acceptorThreads.length; i++)
|
for (int i = 0; i < _acceptorThreads.length; i++)
|
||||||
if (!_threadPool.dispatch(new Acceptor(i)))
|
findExecutor().execute(new Acceptor(i));
|
||||||
throw new IllegalStateException("!accepting");
|
|
||||||
if (_threadPool.isLowOnThreads())
|
|
||||||
LOG.warn("insufficient threads configured for {}",this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG.info("Started {}",this);
|
LOG.info("Started {}",this);
|
||||||
|
|
|
@ -99,7 +99,7 @@ public abstract class AbstractHttpConnector extends AbstractConnector implements
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
protected void checkForwardedHeaders(Request request) throws IOException
|
protected void checkForwardedHeaders(Request request) throws IOException
|
||||||
{
|
{
|
||||||
HttpFields httpFields = request.getConnection().getRequestFields();
|
HttpFields httpFields = request.getHttpChannel().getRequestFields();
|
||||||
|
|
||||||
// Do SSL first
|
// Do SSL first
|
||||||
if (getForwardedCipherSuiteHeader()!=null)
|
if (getForwardedCipherSuiteHeader()!=null)
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
package org.eclipse.jetty.server;
|
package org.eclipse.jetty.server;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
import org.eclipse.jetty.io.ByteBufferPool;
|
import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
import org.eclipse.jetty.io.EndPoint;
|
import org.eclipse.jetty.io.EndPoint;
|
||||||
|
@ -51,6 +52,9 @@ public interface Connector extends LifeCycle
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
Server getServer();
|
Server getServer();
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
Executor getExecutor();
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
ByteBufferPool getByteBufferPool();
|
ByteBufferPool getByteBufferPool();
|
||||||
|
|
||||||
|
|
|
@ -132,7 +132,7 @@ public class Dispatcher implements RequestDispatcher
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
baseRequest.setDispatcherType(DispatcherType.INCLUDE);
|
baseRequest.setDispatcherType(DispatcherType.INCLUDE);
|
||||||
baseRequest.getConnection().include();
|
baseRequest.getHttpChannel().include();
|
||||||
if (_named!=null)
|
if (_named!=null)
|
||||||
_contextHandler.handle(_named,baseRequest, (HttpServletRequest)request, (HttpServletResponse)response);
|
_contextHandler.handle(_named,baseRequest, (HttpServletRequest)request, (HttpServletResponse)response);
|
||||||
else
|
else
|
||||||
|
@ -183,7 +183,7 @@ public class Dispatcher implements RequestDispatcher
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
baseRequest.setAttributes(old_attr);
|
baseRequest.setAttributes(old_attr);
|
||||||
baseRequest.getConnection().included();
|
baseRequest.getHttpChannel().included();
|
||||||
baseRequest.setParameters(old_params);
|
baseRequest.setParameters(old_params);
|
||||||
baseRequest.setDispatcherType(old_type);
|
baseRequest.setDispatcherType(old_type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ import org.eclipse.jetty.http.HttpStatus;
|
||||||
import org.eclipse.jetty.http.HttpURI;
|
import org.eclipse.jetty.http.HttpURI;
|
||||||
import org.eclipse.jetty.http.HttpVersion;
|
import org.eclipse.jetty.http.HttpVersion;
|
||||||
import org.eclipse.jetty.http.MimeTypes;
|
import org.eclipse.jetty.http.MimeTypes;
|
||||||
|
import org.eclipse.jetty.io.AsyncConnection;
|
||||||
import org.eclipse.jetty.io.EndPoint;
|
import org.eclipse.jetty.io.EndPoint;
|
||||||
import org.eclipse.jetty.io.EofException;
|
import org.eclipse.jetty.io.EofException;
|
||||||
import org.eclipse.jetty.io.RuntimeIOException;
|
import org.eclipse.jetty.io.RuntimeIOException;
|
||||||
|
@ -71,7 +72,7 @@ public abstract class HttpChannel
|
||||||
private int _requests;
|
private int _requests;
|
||||||
|
|
||||||
private final Server _server;
|
private final Server _server;
|
||||||
private final EndPoint _endp;
|
private final AsyncConnection _connection;
|
||||||
private final HttpURI _uri;
|
private final HttpURI _uri;
|
||||||
|
|
||||||
private final HttpFields _requestFields;
|
private final HttpFields _requestFields;
|
||||||
|
@ -107,10 +108,10 @@ public abstract class HttpChannel
|
||||||
/** Constructor
|
/** Constructor
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public HttpChannel(Server server,EndPoint endp)
|
public HttpChannel(Server server,AsyncConnection connection)
|
||||||
{
|
{
|
||||||
_server = server;
|
_server = server;
|
||||||
_endp = endp;
|
_connection = connection;
|
||||||
_uri = new HttpURI(URIUtil.__CHARSET);
|
_uri = new HttpURI(URIUtil.__CHARSET);
|
||||||
_requestFields = new HttpFields();
|
_requestFields = new HttpFields();
|
||||||
_responseFields = new HttpFields(server.getMaxCookieVersion());
|
_responseFields = new HttpFields(server.getMaxCookieVersion());
|
||||||
|
@ -146,6 +147,7 @@ public abstract class HttpChannel
|
||||||
return _server;
|
return _server;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public AsyncContinuation getAsyncContinuation()
|
public AsyncContinuation getAsyncContinuation()
|
||||||
{
|
{
|
||||||
|
@ -188,16 +190,22 @@ public abstract class HttpChannel
|
||||||
return _response;
|
return _response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public AsyncConnection getConnection()
|
||||||
|
{
|
||||||
|
return _connection;
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public InetSocketAddress getLocalAddress()
|
public InetSocketAddress getLocalAddress()
|
||||||
{
|
{
|
||||||
return _endp.getLocalAddress();
|
return _connection.getEndPoint().getLocalAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public InetSocketAddress getRemoteAddress()
|
public InetSocketAddress getRemoteAddress()
|
||||||
{
|
{
|
||||||
return _endp.getRemoteAddress();
|
return _connection.getEndPoint().getRemoteAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
|
|
@ -80,7 +80,7 @@ public class HttpConnection extends AbstractAsyncConnection
|
||||||
*/
|
*/
|
||||||
public HttpConnection(HttpConnector connector, AsyncEndPoint endpoint, Server server)
|
public HttpConnection(HttpConnector connector, AsyncEndPoint endpoint, Server server)
|
||||||
{
|
{
|
||||||
super(endpoint);
|
super(endpoint,connector.getServer().getThreadPool());
|
||||||
_connector = connector;
|
_connector = connector;
|
||||||
_bufferPool=_connector.getByteBufferPool();
|
_bufferPool=_connector.getByteBufferPool();
|
||||||
|
|
||||||
|
@ -486,7 +486,7 @@ public class HttpConnection extends AbstractAsyncConnection
|
||||||
{
|
{
|
||||||
private HttpOverHttpChannel(Server server)
|
private HttpOverHttpChannel(Server server)
|
||||||
{
|
{
|
||||||
super(server,getEndPoint());
|
super(server,HttpConnection.this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -14,12 +14,15 @@
|
||||||
package org.eclipse.jetty.server;
|
package org.eclipse.jetty.server;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.io.AsyncConnection;
|
||||||
import org.eclipse.jetty.io.ByteArrayEndPoint;
|
import org.eclipse.jetty.io.ByteArrayEndPoint;
|
||||||
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
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;
|
||||||
|
@ -34,6 +37,7 @@ public class LocalConnector extends AbstractConnector
|
||||||
setMaxIdleTime(30000);
|
setMaxIdleTime(30000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Object getConnection()
|
public Object getConnection()
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
|
@ -46,11 +50,11 @@ public class LocalConnector extends AbstractConnector
|
||||||
|
|
||||||
public String getResponses(String requests, boolean keepOpen) throws Exception
|
public String getResponses(String requests, boolean keepOpen) throws Exception
|
||||||
{
|
{
|
||||||
ByteArrayBuffer result = getResponses(new ByteArrayBuffer(requests, StringUtil.__ISO_8859_1), keepOpen);
|
ByteBuffer result = getResponses(BufferUtil.toBuffer(requests,StringUtil.__UTF8_CHARSET), keepOpen);
|
||||||
return result==null?null:result.toString(StringUtil.__ISO_8859_1);
|
return result==null?null:BufferUtil.toString(result,StringUtil.__UTF8_CHARSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ByteArrayBuffer getResponses(ByteArrayBuffer requestsBuffer, boolean keepOpen) throws Exception
|
public ByteBuffer getResponses(ByteBuffer requestsBuffer, boolean keepOpen) throws Exception
|
||||||
{
|
{
|
||||||
CountDownLatch latch = new CountDownLatch(1);
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
Request request = new Request(requestsBuffer, keepOpen, latch);
|
Request request = new Request(requestsBuffer, keepOpen, latch);
|
||||||
|
@ -63,7 +67,7 @@ public class LocalConnector extends AbstractConnector
|
||||||
protected void accept(int acceptorID) throws IOException, InterruptedException
|
protected void accept(int acceptorID) throws IOException, InterruptedException
|
||||||
{
|
{
|
||||||
Request request = _requests.take();
|
Request request = _requests.take();
|
||||||
getThreadPool().dispatch(request);
|
findExecutor().execute(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void open() throws IOException
|
public void open() throws IOException
|
||||||
|
@ -81,18 +85,19 @@ public class LocalConnector extends AbstractConnector
|
||||||
|
|
||||||
public void executeRequest(String rawRequest) throws IOException
|
public void executeRequest(String rawRequest) throws IOException
|
||||||
{
|
{
|
||||||
Request request = new Request(new ByteArrayBuffer(rawRequest, "UTF-8"), true, null);
|
Request request = new Request(BufferUtil.toBuffer(rawRequest,StringUtil.__UTF8_CHARSET),true,null);
|
||||||
|
|
||||||
_requests.add(request);
|
_requests.add(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Request implements Runnable
|
private class Request implements Runnable
|
||||||
{
|
{
|
||||||
private final ByteArrayBuffer _requestsBuffer;
|
private final ByteBuffer _requestsBuffer;
|
||||||
private final boolean _keepOpen;
|
private final boolean _keepOpen;
|
||||||
private final CountDownLatch _latch;
|
private final CountDownLatch _latch;
|
||||||
private volatile ByteArrayBuffer _responsesBuffer;
|
private volatile ByteBuffer _responsesBuffer;
|
||||||
|
|
||||||
private Request(ByteArrayBuffer requestsBuffer, boolean keepOpen, CountDownLatch latch)
|
private Request(ByteBuffer requestsBuffer, boolean keepOpen, CountDownLatch latch)
|
||||||
{
|
{
|
||||||
_requestsBuffer = requestsBuffer;
|
_requestsBuffer = requestsBuffer;
|
||||||
_keepOpen = keepOpen;
|
_keepOpen = keepOpen;
|
||||||
|
@ -101,6 +106,7 @@ public class LocalConnector extends AbstractConnector
|
||||||
|
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ByteArrayEndPoint endPoint = new ByteArrayEndPoint(_requestsBuffer.asArray(), 1024)
|
ByteArrayEndPoint endPoint = new ByteArrayEndPoint(_requestsBuffer.asArray(), 1024)
|
||||||
|
@ -159,9 +165,10 @@ public class LocalConnector extends AbstractConnector
|
||||||
if (_latch != null)
|
if (_latch != null)
|
||||||
_latch.countDown();
|
_latch.countDown();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public ByteArrayBuffer getResponsesBuffer()
|
public ByteBuffer getResponsesBuffer()
|
||||||
{
|
{
|
||||||
return _responsesBuffer;
|
return _responsesBuffer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,12 +172,6 @@ public class Request implements HttpServletRequest
|
||||||
_fields=_channel.getRequestFields();
|
_fields=_channel.getRequestFields();
|
||||||
_async.setConnection(channel);
|
_async.setConnection(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public HttpChannel getHttpChannel()
|
|
||||||
{
|
|
||||||
return _channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public void addEventListener(final EventListener listener)
|
public void addEventListener(final EventListener listener)
|
||||||
|
@ -398,7 +392,7 @@ public class Request implements HttpServletRequest
|
||||||
/**
|
/**
|
||||||
* @return Returns the connection.
|
* @return Returns the connection.
|
||||||
*/
|
*/
|
||||||
public HttpChannel getConnection()
|
public HttpChannel getHttpChannel()
|
||||||
{
|
{
|
||||||
return _channel;
|
return _channel;
|
||||||
}
|
}
|
||||||
|
|
|
@ -350,6 +350,7 @@ public class ResourceCache
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return "ResourceCache["+_parent+","+_factory+"]@"+hashCode();
|
return "ResourceCache["+_parent+","+_factory+"]@"+hashCode();
|
||||||
|
@ -378,7 +379,7 @@ public class ResourceCache
|
||||||
_key=pathInContext;
|
_key=pathInContext;
|
||||||
_resource=resource;
|
_resource=resource;
|
||||||
|
|
||||||
_contentType=_mimeTypes.getMimeByExtension(_resource.toString());
|
_contentType=BufferUtil.toBuffer(_mimeTypes.getMimeByExtension(_resource.toString()));
|
||||||
boolean exists=resource.exists();
|
boolean exists=resource.exists();
|
||||||
_lastModified=exists?resource.lastModified():-1;
|
_lastModified=exists?resource.lastModified():-1;
|
||||||
_lastModifiedBytes=_lastModified<0?null:BufferUtil.toBuffer(HttpFields.formatDate(_lastModified));
|
_lastModifiedBytes=_lastModified<0?null:BufferUtil.toBuffer(HttpFields.formatDate(_lastModified));
|
||||||
|
@ -409,6 +410,7 @@ public class ResourceCache
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
public Resource getResource()
|
public Resource getResource()
|
||||||
{
|
{
|
||||||
return _resource;
|
return _resource;
|
||||||
|
@ -438,24 +440,28 @@ public class ResourceCache
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public ByteBuffer getLastModified()
|
@Override
|
||||||
|
public String getLastModified()
|
||||||
{
|
{
|
||||||
return _lastModifiedBytes;
|
return BufferUtil.toString(_lastModifiedBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public ByteBuffer getContentType()
|
@Override
|
||||||
|
public String getContentType()
|
||||||
{
|
{
|
||||||
return _contentType;
|
return BufferUtil.toString(_contentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
public void release()
|
public void release()
|
||||||
{
|
{
|
||||||
// don't release while cached. Release when invalidated.
|
// don't release while cached. Release when invalidated.
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
public ByteBuffer getIndirectBuffer()
|
public ByteBuffer getIndirectBuffer()
|
||||||
{
|
{
|
||||||
ByteBuffer buffer = _indirectBuffer.get();
|
ByteBuffer buffer = _indirectBuffer.get();
|
||||||
|
@ -477,6 +483,7 @@ public class ResourceCache
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
public ByteBuffer getDirectBuffer()
|
public ByteBuffer getDirectBuffer()
|
||||||
{
|
{
|
||||||
ByteBuffer buffer = _directBuffer.get();
|
ByteBuffer buffer = _directBuffer.get();
|
||||||
|
@ -497,12 +504,14 @@ public class ResourceCache
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
public long getContentLength()
|
public long getContentLength()
|
||||||
{
|
{
|
||||||
return _length;
|
return _length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
public InputStream getInputStream() throws IOException
|
public InputStream getInputStream() throws IOException
|
||||||
{
|
{
|
||||||
ByteBuffer indirect = getIndirectBuffer();
|
ByteBuffer indirect = getIndirectBuffer();
|
||||||
|
|
|
@ -1097,7 +1097,14 @@ public class Response implements HttpServletResponse
|
||||||
{
|
{
|
||||||
return _fields;
|
return _fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public long getContentCount()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
|
|
|
@ -18,6 +18,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.eclipse.jetty.http.HttpMethod;
|
import org.eclipse.jetty.http.HttpMethod;
|
||||||
import org.eclipse.jetty.http.HttpParser;
|
import org.eclipse.jetty.http.HttpParser;
|
||||||
|
import org.eclipse.jetty.io.AsyncConnection;
|
||||||
import org.eclipse.jetty.io.AsyncEndPoint;
|
import org.eclipse.jetty.io.AsyncEndPoint;
|
||||||
import org.eclipse.jetty.io.EndPoint;
|
import org.eclipse.jetty.io.EndPoint;
|
||||||
import org.eclipse.jetty.io.SelectChannelEndPoint;
|
import org.eclipse.jetty.io.SelectChannelEndPoint;
|
||||||
|
@ -42,7 +43,7 @@ public class ConnectHandler extends HandlerWrapper
|
||||||
private static final Logger LOG = Log.getLogger(ConnectHandler.class);
|
private static final Logger LOG = Log.getLogger(ConnectHandler.class);
|
||||||
|
|
||||||
private final Logger _logger = Log.getLogger(getClass().getName());
|
private final Logger _logger = Log.getLogger(getClass().getName());
|
||||||
private final SelectorManager _selectorManager = new Manager();
|
// TODO private final SelectorManager _selectorManager = new Manager();
|
||||||
private volatile int _connectTimeout = 5000;
|
private volatile int _connectTimeout = 5000;
|
||||||
private volatile int _writeTimeout = 30000;
|
private volatile int _writeTimeout = 30000;
|
||||||
private volatile ThreadPool _threadPool;
|
private volatile ThreadPool _threadPool;
|
||||||
|
@ -109,7 +110,7 @@ public class ConnectHandler extends HandlerWrapper
|
||||||
{
|
{
|
||||||
super.setServer(server);
|
super.setServer(server);
|
||||||
|
|
||||||
server.getContainer().update(this, null, _selectorManager, "selectManager");
|
// TODO server.getContainer().update(this, null, _selectorManager, "selectManager");
|
||||||
|
|
||||||
if (_privateThreadPool)
|
if (_privateThreadPool)
|
||||||
server.getContainer().update(this, null, _privateThreadPool, "threadpool", true);
|
server.getContainer().update(this, null, _privateThreadPool, "threadpool", true);
|
||||||
|
@ -149,13 +150,13 @@ public class ConnectHandler extends HandlerWrapper
|
||||||
if (_threadPool instanceof LifeCycle && !((LifeCycle)_threadPool).isRunning())
|
if (_threadPool instanceof LifeCycle && !((LifeCycle)_threadPool).isRunning())
|
||||||
((LifeCycle)_threadPool).start();
|
((LifeCycle)_threadPool).start();
|
||||||
|
|
||||||
_selectorManager.start();
|
// TODO _selectorManager.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doStop() throws Exception
|
protected void doStop() throws Exception
|
||||||
{
|
{
|
||||||
_selectorManager.stop();
|
// TODO _selectorManager.stop();
|
||||||
|
|
||||||
ThreadPool threadPool = _threadPool;
|
ThreadPool threadPool = _threadPool;
|
||||||
if (_privateThreadPool && _threadPool != null && threadPool instanceof LifeCycle)
|
if (_privateThreadPool && _threadPool != null && threadPool instanceof LifeCycle)
|
||||||
|
@ -167,7 +168,7 @@ public class ConnectHandler extends HandlerWrapper
|
||||||
@Override
|
@Override
|
||||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||||
{
|
{
|
||||||
if (HttpMethod.CONNECT.equalsIgnoreCase(request.getMethod()))
|
if (HttpMethod.CONNECT.is(request.getMethod()))
|
||||||
{
|
{
|
||||||
_logger.debug("CONNECT request for {}", request.getRequestURI());
|
_logger.debug("CONNECT request for {}", request.getRequestURI());
|
||||||
try
|
try
|
||||||
|
@ -228,6 +229,8 @@ public class ConnectHandler extends HandlerWrapper
|
||||||
// 1. when this unread data is written and the server replies before the clientToProxy
|
// 1. when this unread data is written and the server replies before the clientToProxy
|
||||||
// connection is installed (it is only installed after returning from this method)
|
// connection is installed (it is only installed after returning from this method)
|
||||||
// 2. when the client sends data before this unread data has been written.
|
// 2. when the client sends data before this unread data has been written.
|
||||||
|
|
||||||
|
/* TODO
|
||||||
AbstractHttpConnection httpConnection = AbstractHttpConnection.getCurrentHttpChannel();
|
AbstractHttpConnection httpConnection = AbstractHttpConnection.getCurrentHttpChannel();
|
||||||
ByteBuffer headerBuffer = ((HttpParser)httpConnection.getParser()).getHeaderBuffer();
|
ByteBuffer headerBuffer = ((HttpParser)httpConnection.getParser()).getHeaderBuffer();
|
||||||
ByteBuffer bodyBuffer = ((HttpParser)httpConnection.getParser()).getBodyBuffer();
|
ByteBuffer bodyBuffer = ((HttpParser)httpConnection.getParser()).getBodyBuffer();
|
||||||
|
@ -264,8 +267,10 @@ public class ConnectHandler extends HandlerWrapper
|
||||||
response.getOutputStream().close();
|
response.getOutputStream().close();
|
||||||
|
|
||||||
upgradeConnection(request, response, clientToProxy);
|
upgradeConnection(request, response, clientToProxy);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO
|
||||||
private ClientToProxyConnection prepareConnections(ConcurrentMap<String, Object> context, SocketChannel channel, ByteBuffer buffer)
|
private ClientToProxyConnection prepareConnections(ConcurrentMap<String, Object> context, SocketChannel channel, ByteBuffer buffer)
|
||||||
{
|
{
|
||||||
AbstractHttpConnection httpConnection = AbstractHttpConnection.getCurrentHttpChannel();
|
AbstractHttpConnection httpConnection = AbstractHttpConnection.getCurrentHttpChannel();
|
||||||
|
@ -274,7 +279,9 @@ public class ConnectHandler extends HandlerWrapper
|
||||||
clientToProxy.setConnection(proxyToServer);
|
clientToProxy.setConnection(proxyToServer);
|
||||||
proxyToServer.setConnection(clientToProxy);
|
proxyToServer.setConnection(clientToProxy);
|
||||||
return clientToProxy;
|
return clientToProxy;
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Handles the authentication before setting up the tunnel to the remote server.</p>
|
* <p>Handles the authentication before setting up the tunnel to the remote server.</p>
|
||||||
|
@ -292,6 +299,7 @@ public class ConnectHandler extends HandlerWrapper
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO
|
||||||
protected ClientToProxyConnection newClientToProxyConnection(ConcurrentMap<String, Object> context, SocketChannel channel, EndPoint endPoint, long timeStamp)
|
protected ClientToProxyConnection newClientToProxyConnection(ConcurrentMap<String, Object> context, SocketChannel channel, EndPoint endPoint, long timeStamp)
|
||||||
{
|
{
|
||||||
return new ClientToProxyConnection(context, channel, endPoint, timeStamp);
|
return new ClientToProxyConnection(context, channel, endPoint, timeStamp);
|
||||||
|
@ -301,6 +309,7 @@ public class ConnectHandler extends HandlerWrapper
|
||||||
{
|
{
|
||||||
return new ProxyToServerConnection(context, buffer);
|
return new ProxyToServerConnection(context, buffer);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
private SocketChannel connectToServer(HttpServletRequest request, String host, int port) throws IOException
|
private SocketChannel connectToServer(HttpServletRequest request, String host, int port) throws IOException
|
||||||
{
|
{
|
||||||
|
@ -358,11 +367,13 @@ public class ConnectHandler extends HandlerWrapper
|
||||||
_logger.debug("Upgraded connection to {}", connection);
|
_logger.debug("Upgraded connection to {}", connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO
|
||||||
private void register(SocketChannel channel, ProxyToServerConnection proxyToServer) throws IOException
|
private void register(SocketChannel channel, ProxyToServerConnection proxyToServer) throws IOException
|
||||||
{
|
{
|
||||||
_selectorManager.register(channel, proxyToServer);
|
_selectorManager.register(channel, proxyToServer);
|
||||||
proxyToServer.waitReady(_connectTimeout);
|
proxyToServer.waitReady(_connectTimeout);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Reads (with non-blocking semantic) into the given {@code buffer} from the given {@code endPoint}.</p>
|
* <p>Reads (with non-blocking semantic) into the given {@code buffer} from the given {@code endPoint}.</p>
|
||||||
|
@ -390,6 +401,7 @@ public class ConnectHandler extends HandlerWrapper
|
||||||
*/
|
*/
|
||||||
protected int write(EndPoint endPoint, ByteBuffer buffer, ConcurrentMap<String, Object> context) throws IOException
|
protected int write(EndPoint endPoint, ByteBuffer buffer, ConcurrentMap<String, Object> context) throws IOException
|
||||||
{
|
{
|
||||||
|
/* TODO
|
||||||
if (buffer == null)
|
if (buffer == null)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -413,8 +425,11 @@ public class ConnectHandler extends HandlerWrapper
|
||||||
}
|
}
|
||||||
_logger.debug("Written {}/{} bytes {}", builder, length, endPoint);
|
_logger.debug("Written {}/{} bytes {}", builder, length, endPoint);
|
||||||
return length;
|
return length;
|
||||||
|
*/
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO
|
||||||
private class Manager extends SelectorManager
|
private class Manager extends SelectorManager
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
|
@ -955,9 +970,11 @@ public class ConnectHandler extends HandlerWrapper
|
||||||
public void dump(Appendable out, String indent) throws IOException
|
public void dump(Appendable out, String indent) throws IOException
|
||||||
{
|
{
|
||||||
dumpThis(out);
|
dumpThis(out);
|
||||||
|
/* TODO
|
||||||
if (_privateThreadPool)
|
if (_privateThreadPool)
|
||||||
dump(out, indent, Arrays.asList(_threadPool, _selectorManager), TypeUtil.asList(getHandlers()), getBeans());
|
dump(out, indent, Arrays.asList(_threadPool, _selectorManager), TypeUtil.asList(getHandlers()), getBeans());
|
||||||
else
|
else
|
||||||
dump(out, indent, Arrays.asList(_selectorManager), TypeUtil.asList(getHandlers()), getBeans());
|
dump(out, indent, Arrays.asList(_selectorManager), TypeUtil.asList(getHandlers()), getBeans());
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1744,10 +1744,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
|
||||||
{
|
{
|
||||||
if (_mimeTypes == null)
|
if (_mimeTypes == null)
|
||||||
return null;
|
return null;
|
||||||
ByteBuffer mime = _mimeTypes.getMimeByExtension(file);
|
return _mimeTypes.getMimeByExtension(file);
|
||||||
if (mime != null)
|
|
||||||
return mime.toString();
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
|
|
@ -65,8 +65,9 @@ public class DebugHandler extends HandlerWrapper
|
||||||
String ex=null;
|
String ex=null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
final String d=_date.now();
|
long now=System.currentTimeMillis();
|
||||||
final int ms=_date.lastMs();
|
final String d=_date.format(now);
|
||||||
|
final int ms=(int)(now%1000);
|
||||||
|
|
||||||
if (retry)
|
if (retry)
|
||||||
_print.println(d+(ms>99?".":(ms>9?".0":".00"))+ms+":"+name+" RETRY");
|
_print.println(d+(ms>99?".":(ms>9?".0":".00"))+ms+":"+name+" RETRY");
|
||||||
|
@ -99,8 +100,9 @@ public class DebugHandler extends HandlerWrapper
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
thread.setName(old_name);
|
thread.setName(old_name);
|
||||||
final String d=_date.now();
|
long now=System.currentTimeMillis();
|
||||||
final int ms=_date.lastMs();
|
final String d=_date.format(now);
|
||||||
|
final int ms=(int)(now%1000);
|
||||||
suspend=baseRequest.getAsyncContinuation().isSuspended();
|
suspend=baseRequest.getAsyncContinuation().isSuspended();
|
||||||
if (suspend)
|
if (suspend)
|
||||||
{
|
{
|
||||||
|
@ -110,7 +112,7 @@ public class DebugHandler extends HandlerWrapper
|
||||||
else
|
else
|
||||||
_print.println(d+(ms>99?".":(ms>9?".0":".00"))+ms+":"+name+" "+base_response.getStatus()+
|
_print.println(d+(ms>99?".":(ms>9?".0":".00"))+ms+":"+name+" "+base_response.getStatus()+
|
||||||
(ex==null?"":("/"+ex))+
|
(ex==null?"":("/"+ex))+
|
||||||
" "+base_response.getContentType()+" "+base_response.getContentCount());
|
" "+base_response.getContentType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.eclipse.jetty.http.HttpMethod;
|
||||||
import org.eclipse.jetty.http.HttpStatus;
|
import org.eclipse.jetty.http.HttpStatus;
|
||||||
import org.eclipse.jetty.http.MimeTypes;
|
import org.eclipse.jetty.http.MimeTypes;
|
||||||
import org.eclipse.jetty.server.Request;
|
import org.eclipse.jetty.server.Request;
|
||||||
|
import org.eclipse.jetty.server.Response;
|
||||||
import org.eclipse.jetty.util.ByteArrayISO8859Writer;
|
import org.eclipse.jetty.util.ByteArrayISO8859Writer;
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -42,18 +43,19 @@ public class ErrorHandler extends AbstractHandler
|
||||||
/*
|
/*
|
||||||
* @see org.eclipse.jetty.server.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
|
* @see org.eclipse.jetty.server.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||||
{
|
{
|
||||||
AbstractHttpConnection connection = AbstractHttpConnection.getCurrentHttpChannel();
|
baseRequest.setHandled(true);
|
||||||
connection.getRequest().setHandled(true);
|
|
||||||
String method = request.getMethod();
|
String method = request.getMethod();
|
||||||
if(!method.equals(HttpMethod.GET) && !method.equals(HttpMethod.POST) && !method.equals(HttpMethod.HEAD))
|
if(!method.equals(HttpMethod.GET) && !method.equals(HttpMethod.POST) && !method.equals(HttpMethod.HEAD))
|
||||||
return;
|
return;
|
||||||
response.setContentType(MimeTypes.TEXT_HTML_8859_1);
|
response.setContentType(MimeTypes.Type.TEXT_HTML_8859_1.asString());
|
||||||
if (_cacheControl!=null)
|
if (_cacheControl!=null)
|
||||||
response.setHeader(HttpHeader.CACHE_CONTROL, _cacheControl);
|
response.setHeader(HttpHeader.CACHE_CONTROL.asString(), _cacheControl);
|
||||||
ByteArrayISO8859Writer writer= new ByteArrayISO8859Writer(4096);
|
ByteArrayISO8859Writer writer= new ByteArrayISO8859Writer(4096);
|
||||||
handleErrorPage(request, writer, connection.getResponse().getStatus(), connection.getResponse().getReason());
|
String reason=(response instanceof Response)?((Response)response).getReason():null; // TODO
|
||||||
|
handleErrorPage(request, writer, response.getStatus(), reason);
|
||||||
writer.flush();
|
writer.flush();
|
||||||
response.setContentLength(writer.size());
|
response.setContentLength(writer.size());
|
||||||
writer.writeTo(response.getOutputStream());
|
writer.writeTo(response.getOutputStream());
|
||||||
|
|
|
@ -210,7 +210,7 @@ public class GzipHandler extends HandlerWrapper
|
||||||
{
|
{
|
||||||
String ae = request.getHeader("accept-encoding");
|
String ae = request.getHeader("accept-encoding");
|
||||||
if (ae != null && ae.indexOf("gzip")>=0 && !response.containsHeader("Content-Encoding")
|
if (ae != null && ae.indexOf("gzip")>=0 && !response.containsHeader("Content-Encoding")
|
||||||
&& !HttpMethod.HEAD.equalsIgnoreCase(request.getMethod()))
|
&& !HttpMethod.HEAD.is(request.getMethod()))
|
||||||
{
|
{
|
||||||
if (_excluded!=null)
|
if (_excluded!=null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
package org.eclipse.jetty.server.handler;
|
package org.eclipse.jetty.server.handler;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -25,6 +26,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
import org.eclipse.jetty.http.HttpStatus;
|
import org.eclipse.jetty.http.HttpStatus;
|
||||||
import org.eclipse.jetty.http.PathMap;
|
import org.eclipse.jetty.http.PathMap;
|
||||||
import org.eclipse.jetty.io.EndPoint;
|
import org.eclipse.jetty.io.EndPoint;
|
||||||
|
import org.eclipse.jetty.server.HttpChannel;
|
||||||
import org.eclipse.jetty.server.Request;
|
import org.eclipse.jetty.server.Request;
|
||||||
import org.eclipse.jetty.util.IPAddressMap;
|
import org.eclipse.jetty.util.IPAddressMap;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
|
@ -178,14 +180,14 @@ public class IPAccessHandler extends HandlerWrapper
|
||||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||||
{
|
{
|
||||||
// Get the real remote IP (not the one set by the forwarded headers (which may be forged))
|
// Get the real remote IP (not the one set by the forwarded headers (which may be forged))
|
||||||
AbstractHttpConnection connection = baseRequest.getConnection();
|
HttpChannel channel = baseRequest.getHttpChannel();
|
||||||
if (connection!=null)
|
if (channel!=null)
|
||||||
{
|
{
|
||||||
EndPoint endp=connection.getEndPoint();
|
EndPoint endp=channel.getConnection().getEndPoint();
|
||||||
if (endp!=null)
|
if (endp!=null)
|
||||||
{
|
{
|
||||||
String addr = endp.getRemoteAddr();
|
InetSocketAddress address = endp.getRemoteAddress();
|
||||||
if (addr!=null && !isAddrUriAllowed(addr,baseRequest.getPathInfo()))
|
if (address!=null && !isAddrUriAllowed(address.getHostString(),baseRequest.getPathInfo()))
|
||||||
{
|
{
|
||||||
response.sendError(HttpStatus.FORBIDDEN_403);
|
response.sendError(HttpStatus.FORBIDDEN_403);
|
||||||
baseRequest.setHandled(true);
|
baseRequest.setHandled(true);
|
||||||
|
|
|
@ -116,10 +116,10 @@ public class MovedContextHandler extends ContextHandler
|
||||||
location.append(q);
|
location.append(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
response.setHeader(HttpHeader.LOCATION,location.toString());
|
response.setHeader(HttpHeader.LOCATION.asString(),location.toString());
|
||||||
|
|
||||||
if (_expires!=null)
|
if (_expires!=null)
|
||||||
response.setHeader(HttpHeader.EXPIRES,_expires);
|
response.setHeader(HttpHeader.EXPIRES.asString(),_expires);
|
||||||
|
|
||||||
response.setStatus(_permanent?HttpServletResponse.SC_MOVED_PERMANENTLY:HttpServletResponse.SC_FOUND);
|
response.setStatus(_permanent?HttpServletResponse.SC_MOVED_PERMANENTLY:HttpServletResponse.SC_FOUND);
|
||||||
response.setContentLength(0);
|
response.setContentLength(0);
|
||||||
|
|
|
@ -18,6 +18,7 @@ import java.io.OutputStream;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import javax.servlet.RequestDispatcher;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
@ -29,9 +30,11 @@ import org.eclipse.jetty.http.HttpStatus;
|
||||||
import org.eclipse.jetty.http.MimeTypes;
|
import org.eclipse.jetty.http.MimeTypes;
|
||||||
import org.eclipse.jetty.io.WriterOutputStream;
|
import org.eclipse.jetty.io.WriterOutputStream;
|
||||||
import org.eclipse.jetty.server.Dispatcher;
|
import org.eclipse.jetty.server.Dispatcher;
|
||||||
|
import org.eclipse.jetty.server.HttpOutput;
|
||||||
import org.eclipse.jetty.server.Request;
|
import org.eclipse.jetty.server.Request;
|
||||||
import org.eclipse.jetty.server.Response;
|
import org.eclipse.jetty.server.Response;
|
||||||
import org.eclipse.jetty.server.handler.ContextHandler.Context;
|
import org.eclipse.jetty.server.handler.ContextHandler.Context;
|
||||||
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.util.URIUtil;
|
import org.eclipse.jetty.util.URIUtil;
|
||||||
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;
|
||||||
|
@ -59,7 +62,7 @@ public class ResourceHandler extends HandlerWrapper
|
||||||
Resource _stylesheet;
|
Resource _stylesheet;
|
||||||
String[] _welcomeFiles={"index.html"};
|
String[] _welcomeFiles={"index.html"};
|
||||||
MimeTypes _mimeTypes = new MimeTypes();
|
MimeTypes _mimeTypes = new MimeTypes();
|
||||||
ByteArrayBuffer _cacheControl;
|
String _cacheControl;
|
||||||
boolean _aliases;
|
boolean _aliases;
|
||||||
boolean _directory;
|
boolean _directory;
|
||||||
|
|
||||||
|
@ -254,7 +257,7 @@ public class ResourceHandler extends HandlerWrapper
|
||||||
*/
|
*/
|
||||||
public void setCacheControl(String cacheControl)
|
public void setCacheControl(String cacheControl)
|
||||||
{
|
{
|
||||||
_cacheControl=cacheControl==null?null:new ByteArrayBuffer(cacheControl);
|
_cacheControl=cacheControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -293,11 +296,11 @@ public class ResourceHandler extends HandlerWrapper
|
||||||
{
|
{
|
||||||
String servletPath;
|
String servletPath;
|
||||||
String pathInfo;
|
String pathInfo;
|
||||||
Boolean included = request.getAttribute(Dispatcher.INCLUDE_REQUEST_URI) != null;
|
Boolean included = request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI) != null;
|
||||||
if (included != null && included.booleanValue())
|
if (included != null && included.booleanValue())
|
||||||
{
|
{
|
||||||
servletPath = (String)request.getAttribute(Dispatcher.INCLUDE_SERVLET_PATH);
|
servletPath = (String)request.getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH);
|
||||||
pathInfo = (String)request.getAttribute(Dispatcher.INCLUDE_PATH_INFO);
|
pathInfo = (String)request.getAttribute(RequestDispatcher.INCLUDE_PATH_INFO);
|
||||||
|
|
||||||
if (servletPath == null && pathInfo == null)
|
if (servletPath == null && pathInfo == null)
|
||||||
{
|
{
|
||||||
|
@ -345,6 +348,7 @@ public class ResourceHandler extends HandlerWrapper
|
||||||
/*
|
/*
|
||||||
* @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
|
* @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||||
{
|
{
|
||||||
if (baseRequest.isHandled())
|
if (baseRequest.isHandled())
|
||||||
|
@ -414,7 +418,7 @@ public class ResourceHandler extends HandlerWrapper
|
||||||
long last_modified=resource.lastModified();
|
long last_modified=resource.lastModified();
|
||||||
if (last_modified>0)
|
if (last_modified>0)
|
||||||
{
|
{
|
||||||
long if_modified=request.getDateHeader(HttpHeader.IF_MODIFIED_SINCE);
|
long if_modified=request.getDateHeader(HttpHeader.IF_MODIFIED_SINCE.asString());
|
||||||
if (if_modified>0 && last_modified/1000<=if_modified/1000)
|
if (if_modified>0 && last_modified/1000<=if_modified/1000)
|
||||||
{
|
{
|
||||||
response.setStatus(HttpStatus.NOT_MODIFIED_304);
|
response.setStatus(HttpStatus.NOT_MODIFIED_304);
|
||||||
|
@ -422,13 +426,13 @@ public class ResourceHandler extends HandlerWrapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteBuffer mime=_mimeTypes.getMimeByExtension(resource.toString());
|
String mime=_mimeTypes.getMimeByExtension(resource.toString());
|
||||||
if (mime==null)
|
if (mime==null)
|
||||||
mime=_mimeTypes.getMimeByExtension(request.getPathInfo());
|
mime=_mimeTypes.getMimeByExtension(request.getPathInfo());
|
||||||
|
|
||||||
// set the headers
|
// set the headers
|
||||||
doResponseHeaders(response,resource,mime!=null?mime.toString():null);
|
doResponseHeaders(response,resource,mime!=null?mime.toString():null);
|
||||||
response.setDateHeader(HttpHeader.LAST_MODIFIED,last_modified);
|
response.setDateHeader(HttpHeader.LAST_MODIFIED.asString(),last_modified);
|
||||||
if(skipContentBody)
|
if(skipContentBody)
|
||||||
return;
|
return;
|
||||||
// Send the content
|
// Send the content
|
||||||
|
@ -437,12 +441,13 @@ public class ResourceHandler extends HandlerWrapper
|
||||||
catch(IllegalStateException e) {out = new WriterOutputStream(response.getWriter());}
|
catch(IllegalStateException e) {out = new WriterOutputStream(response.getWriter());}
|
||||||
|
|
||||||
// See if a short direct method can be used?
|
// See if a short direct method can be used?
|
||||||
if (out instanceof AbstractHttpConnection.Output)
|
/* TODO file mapped buffers
|
||||||
|
if (out instanceof HttpOutput)
|
||||||
{
|
{
|
||||||
// TODO file mapped buffers
|
// TODO file mapped buffers
|
||||||
((AbstractHttpConnection.Output)out).sendContent(resource.getInputStream());
|
((HttpOutput)out).send(resource.getInputStream());
|
||||||
}
|
}
|
||||||
else
|
else*/
|
||||||
{
|
{
|
||||||
// Write content normally
|
// Write content normally
|
||||||
resource.writeTo(out,0,resource.length());
|
resource.writeTo(out,0,resource.length());
|
||||||
|
@ -483,18 +488,18 @@ public class ResourceHandler extends HandlerWrapper
|
||||||
HttpFields fields = ((Response)response).getHttpFields();
|
HttpFields fields = ((Response)response).getHttpFields();
|
||||||
|
|
||||||
if (length>0)
|
if (length>0)
|
||||||
fields.putLongField(HttpHeader.CONTENT_LENGTH_BUFFER,length);
|
fields.putLongField(HttpHeader.CONTENT_LENGTH,length);
|
||||||
|
|
||||||
if (_cacheControl!=null)
|
if (_cacheControl!=null)
|
||||||
fields.put(HttpHeader.CACHE_CONTROL_BUFFER,_cacheControl);
|
fields.put(HttpHeader.CACHE_CONTROL,_cacheControl);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (length>0)
|
if (length>0)
|
||||||
response.setHeader(HttpHeader.CONTENT_LENGTH,Long.toString(length));
|
response.setHeader(HttpHeader.CONTENT_LENGTH.asString(),Long.toString(length));
|
||||||
|
|
||||||
if (_cacheControl!=null)
|
if (_cacheControl!=null)
|
||||||
response.setHeader(HttpHeader.CACHE_CONTROL,_cacheControl.toString());
|
response.setHeader(HttpHeader.CACHE_CONTROL.asString(),_cacheControl.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import java.net.Socket;
|
||||||
import java.nio.channels.SelectionKey;
|
import java.nio.channels.SelectionKey;
|
||||||
import java.nio.channels.ServerSocketChannel;
|
import java.nio.channels.ServerSocketChannel;
|
||||||
import java.nio.channels.SocketChannel;
|
import java.nio.channels.SocketChannel;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
import org.eclipse.jetty.continuation.Continuation;
|
import org.eclipse.jetty.continuation.Continuation;
|
||||||
import org.eclipse.jetty.io.AsyncConnection;
|
import org.eclipse.jetty.io.AsyncConnection;
|
||||||
|
@ -240,10 +241,9 @@ public class SelectChannelConnector extends AbstractHttpConnector
|
||||||
@Override
|
@Override
|
||||||
public boolean dispatch(Runnable task)
|
public boolean dispatch(Runnable task)
|
||||||
{
|
{
|
||||||
ThreadPool pool=getThreadPool();
|
Executor executor = findExecutor();
|
||||||
if (pool==null)
|
executor.execute(task);
|
||||||
pool=getServer().getThreadPool();
|
return true;
|
||||||
return pool.dispatch(task);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -85,7 +85,7 @@ public class SslCertificates
|
||||||
*/
|
*/
|
||||||
public static void customize(SSLSession sslSession, EndPoint endpoint, Request request) throws IOException
|
public static void customize(SSLSession sslSession, EndPoint endpoint, Request request) throws IOException
|
||||||
{
|
{
|
||||||
request.setScheme(HttpScheme.HTTPS);
|
request.setScheme(HttpScheme.HTTPS.asString());
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,6 +22,7 @@ import javax.net.ssl.SSLSession;
|
||||||
import javax.net.ssl.SSLSocket;
|
import javax.net.ssl.SSLSocket;
|
||||||
|
|
||||||
import org.eclipse.jetty.http.HttpScheme;
|
import org.eclipse.jetty.http.HttpScheme;
|
||||||
|
import org.eclipse.jetty.io.AsyncConnection;
|
||||||
import org.eclipse.jetty.io.AsyncEndPoint;
|
import org.eclipse.jetty.io.AsyncEndPoint;
|
||||||
import org.eclipse.jetty.io.EndPoint;
|
import org.eclipse.jetty.io.EndPoint;
|
||||||
import org.eclipse.jetty.io.RuntimeIOException;
|
import org.eclipse.jetty.io.RuntimeIOException;
|
||||||
|
@ -40,7 +41,6 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||||
public class SslSelectChannelConnector extends SelectChannelConnector implements SslConnector
|
public class SslSelectChannelConnector extends SelectChannelConnector implements SslConnector
|
||||||
{
|
{
|
||||||
private final SslContextFactory _sslContextFactory;
|
private final SslContextFactory _sslContextFactory;
|
||||||
private Buffers _sslBuffers;
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public SslSelectChannelConnector()
|
public SslSelectChannelConnector()
|
||||||
|
@ -59,7 +59,6 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements
|
||||||
{
|
{
|
||||||
_sslContextFactory = sslContextFactory;
|
_sslContextFactory = sslContextFactory;
|
||||||
addBean(_sslContextFactory);
|
addBean(_sslContextFactory);
|
||||||
setUseDirectBuffers(false);
|
|
||||||
setSoLingerTime(30000);
|
setSoLingerTime(30000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,11 +89,12 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements
|
||||||
* HttpRequest to be customised.
|
* HttpRequest to be customised.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void customize(EndPoint endpoint, Request request) throws IOException
|
public void customize(Request request) throws IOException
|
||||||
{
|
{
|
||||||
request.setScheme(HttpScheme.HTTPS);
|
request.setScheme(HttpScheme.HTTPS.asString());
|
||||||
super.customize(endpoint,request);
|
super.customize(request);
|
||||||
|
|
||||||
|
EndPoint endpoint = request.getHttpChannel().getConnection().getEndPoint();
|
||||||
SslConnection.AppEndPoint sslEndpoint=(SslConnection.AppEndPoint)endpoint;
|
SslConnection.AppEndPoint sslEndpoint=(SslConnection.AppEndPoint)endpoint;
|
||||||
SSLEngine sslEngine=sslEndpoint.getSslEngine();
|
SSLEngine sslEngine=sslEndpoint.getSslEngine();
|
||||||
SSLSession sslSession=sslEngine.getSession();
|
SSLSession sslSession=sslEngine.getSession();
|
||||||
|
@ -546,7 +546,7 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements
|
||||||
SSLEngine engine = createSSLEngine(channel);
|
SSLEngine engine = createSSLEngine(channel);
|
||||||
SslConnection connection = newSslConnection(endpoint, engine);
|
SslConnection connection = newSslConnection(endpoint, engine);
|
||||||
AsyncConnection delegate = newPlainConnection(channel, connection.getAppEndPoint());
|
AsyncConnection delegate = newPlainConnection(channel, connection.getAppEndPoint());
|
||||||
connection.getAppEndPoint().setConnection(delegate);
|
connection.getAppEndPoint().setAsyncConnection(delegate);
|
||||||
connection.setAllowRenegotiate(_sslContextFactory.isAllowRenegotiate());
|
connection.setAllowRenegotiate(_sslContextFactory.isAllowRenegotiate());
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
@ -563,7 +563,7 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements
|
||||||
|
|
||||||
protected SslConnection newSslConnection(AsyncEndPoint endpoint, SSLEngine engine)
|
protected SslConnection newSslConnection(AsyncEndPoint endpoint, SSLEngine engine)
|
||||||
{
|
{
|
||||||
return new SslConnection(engine, endpoint);
|
return new SslConnection(engine, endpoint,findExecutor());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -607,12 +607,6 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements
|
||||||
|
|
||||||
SSLSession sslSession = sslEngine.getSession();
|
SSLSession sslSession = sslEngine.getSession();
|
||||||
|
|
||||||
_sslBuffers = BuffersFactory.newBuffers(
|
|
||||||
getUseDirectBuffers()?Type.DIRECT:Type.INDIRECT,sslSession.getApplicationBufferSize(),
|
|
||||||
getUseDirectBuffers()?Type.DIRECT:Type.INDIRECT,sslSession.getApplicationBufferSize(),
|
|
||||||
getUseDirectBuffers()?Type.DIRECT:Type.INDIRECT,getMaxBuffers()
|
|
||||||
);
|
|
||||||
|
|
||||||
if (getRequestHeaderSize()<sslSession.getApplicationBufferSize())
|
if (getRequestHeaderSize()<sslSession.getApplicationBufferSize())
|
||||||
setRequestHeaderSize(sslSession.getApplicationBufferSize());
|
setRequestHeaderSize(sslSession.getApplicationBufferSize());
|
||||||
if (getRequestBufferSize()<sslSession.getApplicationBufferSize())
|
if (getRequestBufferSize()<sslSession.getApplicationBufferSize())
|
||||||
|
@ -628,16 +622,7 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements
|
||||||
@Override
|
@Override
|
||||||
protected void doStop() throws Exception
|
protected void doStop() throws Exception
|
||||||
{
|
{
|
||||||
_sslBuffers=null;
|
|
||||||
super.doStop();
|
super.doStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* @return SSL buffers
|
|
||||||
*/
|
|
||||||
public Buffers getSslBuffers()
|
|
||||||
{
|
|
||||||
return _sslBuffers;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,7 +124,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
endpoint.exchange(baseRequest.getConnection().getEndPoint());
|
endpoint.exchange(baseRequest.getHttpChannel().getEndPoint());
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{}
|
{}
|
||||||
|
@ -197,7 +197,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
endpoint.exchange(baseRequest.getConnection().getEndPoint());
|
endpoint.exchange(baseRequest.getHttpChannel().getEndPoint());
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -983,7 +983,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
|
|
||||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||||
{
|
{
|
||||||
_endp=baseRequest.getConnection().getEndPoint();
|
_endp=baseRequest.getHttpChannel().getEndPoint();
|
||||||
response.setHeader("test","value");
|
response.setHeader("test","value");
|
||||||
response.setStatus(200);
|
response.setStatus(200);
|
||||||
response.setContentType("text/plain");
|
response.setContentType("text/plain");
|
||||||
|
|
|
@ -592,7 +592,7 @@ public class ConnectHandlerTest extends AbstractConnectHandlerTest
|
||||||
}
|
}
|
||||||
else if ("/close".equals(uri))
|
else if ("/close".equals(uri))
|
||||||
{
|
{
|
||||||
request.getConnection().getEndPoint().close();
|
request.getHttpChannel().getEndPoint().close();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -136,7 +136,7 @@ public class SSLCloseTest extends TestCase
|
||||||
baseRequest.setHandled(true);
|
baseRequest.setHandled(true);
|
||||||
response.setStatus(200);
|
response.setStatus(200);
|
||||||
response.setHeader("test","value");
|
response.setHeader("test","value");
|
||||||
__endp=(AsyncEndPoint)baseRequest.getConnection().getEndPoint();
|
__endp=(AsyncEndPoint)baseRequest.getHttpChannel().getEndPoint();
|
||||||
|
|
||||||
OutputStream out=response.getOutputStream();
|
OutputStream out=response.getOutputStream();
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ public class ServerHTTPSPDYAsyncConnectionFactory extends ServerSPDYAsyncConnect
|
||||||
|
|
||||||
HTTPSPDYAsyncEndPoint asyncEndPoint = new HTTPSPDYAsyncEndPoint(endPoint, stream);
|
HTTPSPDYAsyncEndPoint asyncEndPoint = new HTTPSPDYAsyncEndPoint(endPoint, stream);
|
||||||
ServerHTTPSPDYAsyncConnection connection = new ServerHTTPSPDYAsyncConnection(connector,
|
ServerHTTPSPDYAsyncConnection connection = new ServerHTTPSPDYAsyncConnection(connector,
|
||||||
asyncEndPoint, connector.getServer(), (SPDYAsyncConnection)endPoint.getConnection(),
|
asyncEndPoint, connector.getServer(), (SPDYAsyncConnection)endPoint.getHttpChannel(),
|
||||||
pushStrategy, stream);
|
pushStrategy, stream);
|
||||||
asyncEndPoint.setConnection(connection);
|
asyncEndPoint.setConnection(connection);
|
||||||
stream.setAttribute(CONNECTION_ATTRIBUTE, connection);
|
stream.setAttribute(CONNECTION_ATTRIBUTE, connection);
|
||||||
|
|
|
@ -251,8 +251,13 @@ public class DateCache
|
||||||
|
|
||||||
return tick._string;
|
return tick._string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public String now()
|
||||||
|
{
|
||||||
|
return _tick._string;
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
private void formatNow()
|
private void formatNow()
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,17 @@ import java.util.concurrent.Executor;
|
||||||
|
|
||||||
public class ExecutorCallback<C> implements Callback<C>
|
public class ExecutorCallback<C> implements Callback<C>
|
||||||
{
|
{
|
||||||
|
private final static Integer ZERO = new Integer(0);
|
||||||
|
private final static ThreadLocal<Integer> __calls = new ThreadLocal<Integer>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected Integer initialValue()
|
||||||
|
{
|
||||||
|
return ZERO;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final int _maxRecursion;
|
||||||
private final Executor _executor;
|
private final Executor _executor;
|
||||||
private final Runnable _onNullContextCompleted = new Runnable()
|
private final Runnable _onNullContextCompleted = new Runnable()
|
||||||
{
|
{
|
||||||
|
@ -13,25 +24,56 @@ public class ExecutorCallback<C> implements Callback<C>
|
||||||
};
|
};
|
||||||
|
|
||||||
public ExecutorCallback(Executor executor)
|
public ExecutorCallback(Executor executor)
|
||||||
|
{
|
||||||
|
this(executor,4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecutorCallback(Executor executor,int maxRecursion)
|
||||||
{
|
{
|
||||||
_executor=executor;
|
_executor=executor;
|
||||||
|
_maxRecursion=maxRecursion;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void completed(final C context)
|
public void completed(final C context)
|
||||||
{
|
{
|
||||||
if (execute())
|
// Should we execute?
|
||||||
|
if (!execute())
|
||||||
{
|
{
|
||||||
_executor.execute(context==null?
|
// Do we have a recursion limit?
|
||||||
_onNullContextCompleted:
|
if (_maxRecursion<=0)
|
||||||
new Runnable()
|
|
||||||
{
|
{
|
||||||
@Override
|
// No, so just call it directly
|
||||||
public void run() { onCompleted(context);}
|
onCompleted(context);
|
||||||
});
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Has this thread exceeded the recursion limit
|
||||||
|
Integer calls=__calls.get();
|
||||||
|
if (calls<_maxRecursion)
|
||||||
|
{
|
||||||
|
// No, so increment recursion count, call, then decrement
|
||||||
|
try
|
||||||
|
{
|
||||||
|
__calls.set(calls+1);
|
||||||
|
onCompleted(context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
__calls.set(calls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
onCompleted(context);
|
// fallen through to here so execute
|
||||||
|
_executor.execute(context==null?_onNullContextCompleted:new Runnable()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void run() { onCompleted(context);}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onCompleted(C context)
|
protected void onCompleted(C context)
|
||||||
|
@ -42,6 +84,7 @@ public class ExecutorCallback<C> implements Callback<C>
|
||||||
@Override
|
@Override
|
||||||
public void failed(final C context, final Throwable x)
|
public void failed(final C context, final Throwable x)
|
||||||
{
|
{
|
||||||
|
// Always execute failure
|
||||||
_executor.execute(new Runnable()
|
_executor.execute(new Runnable()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in New Issue