Merge remote-tracking branch 'origin/jetty-9.4.x'
This commit is contained in:
commit
3c29947a0d
|
@ -15,4 +15,4 @@ http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
|
||||||
[ini-template]
|
[ini-template]
|
||||||
## Hide the gcloud libraries from deployed webapps
|
## Hide the gcloud libraries from deployed webapps
|
||||||
jetty.webapp.addServerClasses+=,file:${jetty.base}/lib/gcloud/
|
jetty.webapp.addServerClasses+=,${jetty.base.uri}/lib/gcloud/
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<name>Jetty :: GCloud</name>
|
<name>Jetty :: GCloud</name>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<gcloud.version>0.8.3-beta</gcloud.version>
|
<gcloud.version>0.9.2-beta</gcloud.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
|
|
@ -150,6 +150,24 @@ readConfig()
|
||||||
source "$1"
|
source "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dumpEnv()
|
||||||
|
{
|
||||||
|
echo "JAVA = $JAVA"
|
||||||
|
echo "JAVA_OPTIONS = ${JAVA_OPTIONS[*]}"
|
||||||
|
echo "JETTY_HOME = $JETTY_HOME"
|
||||||
|
echo "JETTY_BASE = $JETTY_BASE"
|
||||||
|
echo "START_D = $START_D"
|
||||||
|
echo "START_INI = $START_INI"
|
||||||
|
echo "JETTY_START = $JETTY_START"
|
||||||
|
echo "JETTY_CONF = $JETTY_CONF"
|
||||||
|
echo "JETTY_ARGS = ${JETTY_ARGS[*]}"
|
||||||
|
echo "JETTY_RUN = $JETTY_RUN"
|
||||||
|
echo "JETTY_PID = $JETTY_PID"
|
||||||
|
echo "JETTY_START_LOG= $JETTY_START_LOG"
|
||||||
|
echo "JETTY_STATE = $JETTY_STATE"
|
||||||
|
echo "RUN_CMD = ${RUN_CMD[*]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
|
@ -278,6 +296,14 @@ then
|
||||||
[ -d "$JETTY_RUN" ] || mkdir $JETTY_RUN
|
[ -d "$JETTY_RUN" ] || mkdir $JETTY_RUN
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
#####################################################
|
||||||
|
# define start log location
|
||||||
|
#####################################################
|
||||||
|
if [ -z "$JETTY_START_LOG" ]
|
||||||
|
then
|
||||||
|
JETTY_START_LOG="$JETTY_RUN/$NAME-start.log"
|
||||||
|
fi
|
||||||
|
|
||||||
#####################################################
|
#####################################################
|
||||||
# Find a pid and state file
|
# Find a pid and state file
|
||||||
#####################################################
|
#####################################################
|
||||||
|
@ -401,17 +427,7 @@ RUN_CMD=("$JAVA" ${RUN_ARGS[@]})
|
||||||
#####################################################
|
#####################################################
|
||||||
if (( DEBUG ))
|
if (( DEBUG ))
|
||||||
then
|
then
|
||||||
echo "START_INI = $START_INI"
|
dumpEnv
|
||||||
echo "START_D = $START_D"
|
|
||||||
echo "JETTY_HOME = $JETTY_HOME"
|
|
||||||
echo "JETTY_BASE = $JETTY_BASE"
|
|
||||||
echo "JETTY_CONF = $JETTY_CONF"
|
|
||||||
echo "JETTY_PID = $JETTY_PID"
|
|
||||||
echo "JETTY_START = $JETTY_START"
|
|
||||||
echo "JETTY_ARGS = ${JETTY_ARGS[*]}"
|
|
||||||
echo "JAVA_OPTIONS = ${JAVA_OPTIONS[*]}"
|
|
||||||
echo "JAVA = $JAVA"
|
|
||||||
echo "RUN_CMD = ${RUN_CMD[*]}"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
|
@ -434,7 +450,7 @@ case "$ACTION" in
|
||||||
CH_USER="-c$JETTY_USER"
|
CH_USER="-c$JETTY_USER"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
start-stop-daemon -S -p"$JETTY_PID" $CH_USER -d"$JETTY_BASE" -b -m -a "$JAVA" -- "${RUN_ARGS[@]}" start-log-file="$JETTY_RUN/start.log"
|
start-stop-daemon -S -p"$JETTY_PID" $CH_USER -d"$JETTY_BASE" -b -m -a "$JAVA" -- "${RUN_ARGS[@]}" start-log-file="$JETTY_START_LOG"
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
|
@ -456,7 +472,7 @@ case "$ACTION" in
|
||||||
chown "$JETTY_USER" "$JETTY_PID"
|
chown "$JETTY_USER" "$JETTY_PID"
|
||||||
# FIXME: Broken solution: wordsplitting, pathname expansion, arbitrary command execution, etc.
|
# FIXME: Broken solution: wordsplitting, pathname expansion, arbitrary command execution, etc.
|
||||||
su - "$JETTY_USER" $SU_SHELL -c "
|
su - "$JETTY_USER" $SU_SHELL -c "
|
||||||
exec ${RUN_CMD[*]} start-log-file="$JETTY_RUN/start.log" > /dev/null &
|
exec ${RUN_CMD[*]} start-log-file="$JETTY_START_LOG" > /dev/null &
|
||||||
disown \$!
|
disown \$!
|
||||||
echo \$! > '$JETTY_PID'"
|
echo \$! > '$JETTY_PID'"
|
||||||
else
|
else
|
||||||
|
@ -569,20 +585,7 @@ case "$ACTION" in
|
||||||
echo "Jetty NOT running"
|
echo "Jetty NOT running"
|
||||||
fi
|
fi
|
||||||
echo
|
echo
|
||||||
echo "START_INI = $START_INI"
|
dumpEnv
|
||||||
echo "START_D = $START_D"
|
|
||||||
echo "JETTY_HOME = $JETTY_HOME"
|
|
||||||
echo "JETTY_BASE = $JETTY_BASE"
|
|
||||||
echo "JETTY_CONF = $JETTY_CONF"
|
|
||||||
echo "JETTY_PID = $JETTY_PID"
|
|
||||||
echo "JETTY_START = $JETTY_START"
|
|
||||||
echo "JETTY_LOGS = $JETTY_LOGS"
|
|
||||||
echo "JETTY_STATE = $JETTY_STATE"
|
|
||||||
echo "CLASSPATH = $CLASSPATH"
|
|
||||||
echo "JAVA = $JAVA"
|
|
||||||
echo "JAVA_OPTIONS = ${JAVA_OPTIONS[*]}"
|
|
||||||
echo "JETTY_ARGS = ${JETTY_ARGS[*]}"
|
|
||||||
echo "RUN_CMD = ${RUN_CMD[*]}"
|
|
||||||
echo
|
echo
|
||||||
|
|
||||||
if running "$JETTY_PID"
|
if running "$JETTY_PID"
|
||||||
|
|
|
@ -55,8 +55,25 @@ public class HttpGenerator
|
||||||
new MetaData.Response(HttpVersion.HTTP_1_1,INTERNAL_SERVER_ERROR_500,null,new HttpFields(){{put(HttpHeader.CONNECTION,HttpHeaderValue.CLOSE);}},0);
|
new MetaData.Response(HttpVersion.HTTP_1_1,INTERNAL_SERVER_ERROR_500,null,new HttpFields(){{put(HttpHeader.CONNECTION,HttpHeaderValue.CLOSE);}},0);
|
||||||
|
|
||||||
// states
|
// states
|
||||||
public enum State { START, COMMITTED, COMPLETING, COMPLETING_1XX, END }
|
public enum State
|
||||||
public enum Result { NEED_CHUNK,NEED_INFO,NEED_HEADER,NEED_CHUNK_TRAILER, FLUSH,CONTINUE,SHUTDOWN_OUT,DONE}
|
{
|
||||||
|
START,
|
||||||
|
COMMITTED,
|
||||||
|
COMPLETING,
|
||||||
|
COMPLETING_1XX,
|
||||||
|
END
|
||||||
|
}
|
||||||
|
public enum Result
|
||||||
|
{
|
||||||
|
NEED_CHUNK, // Need a small chunk buffer of CHUNK_SIZE
|
||||||
|
NEED_INFO, // Need the request/response metadata info
|
||||||
|
NEED_HEADER, // Need a buffer to build HTTP headers into
|
||||||
|
NEED_CHUNK_TRAILER, // Need a large chunk buffer for last chunk and trailers
|
||||||
|
FLUSH, // The buffers previously generated should be flushed
|
||||||
|
CONTINUE, // Continue generating the message
|
||||||
|
SHUTDOWN_OUT, // Need EOF to be signaled
|
||||||
|
DONE // Message generation complete
|
||||||
|
}
|
||||||
|
|
||||||
// other statics
|
// other statics
|
||||||
public static final int CHUNK_SIZE = 12;
|
public static final int CHUNK_SIZE = 12;
|
||||||
|
|
|
@ -134,6 +134,7 @@ public class AsyncProxyServlet extends ProxyServlet
|
||||||
private final Request proxyRequest;
|
private final Request proxyRequest;
|
||||||
private final DeferredContentProvider provider;
|
private final DeferredContentProvider provider;
|
||||||
|
|
||||||
|
|
||||||
protected StreamReader(HttpServletRequest request, HttpServletResponse response, Request proxyRequest, DeferredContentProvider provider)
|
protected StreamReader(HttpServletRequest request, HttpServletResponse response, Request proxyRequest, DeferredContentProvider provider)
|
||||||
{
|
{
|
||||||
this.request = request;
|
this.request = request;
|
||||||
|
@ -168,9 +169,7 @@ public class AsyncProxyServlet extends ProxyServlet
|
||||||
int requestId = _log.isDebugEnabled() ? getRequestId(request) : 0;
|
int requestId = _log.isDebugEnabled() ? getRequestId(request) : 0;
|
||||||
ServletInputStream input = request.getInputStream();
|
ServletInputStream input = request.getInputStream();
|
||||||
|
|
||||||
// First check for isReady() because it has
|
while (input.isReady())
|
||||||
// side effects, and then for isFinished().
|
|
||||||
while (input.isReady() && !input.isFinished())
|
|
||||||
{
|
{
|
||||||
int read = input.read(buffer);
|
int read = input.read(buffer);
|
||||||
if (_log.isDebugEnabled())
|
if (_log.isDebugEnabled())
|
||||||
|
@ -182,20 +181,17 @@ public class AsyncProxyServlet extends ProxyServlet
|
||||||
onRequestContent(request, proxyRequest, provider, buffer, 0, read, this);
|
onRequestContent(request, proxyRequest, provider, buffer, 0, read, this);
|
||||||
return Action.SCHEDULED;
|
return Action.SCHEDULED;
|
||||||
}
|
}
|
||||||
|
else if (read < 0)
|
||||||
|
{
|
||||||
|
if (_log.isDebugEnabled())
|
||||||
|
_log.debug("{} asynchronous read complete on {}", requestId, input);
|
||||||
|
return Action.SUCCEEDED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input.isFinished())
|
if (_log.isDebugEnabled())
|
||||||
{
|
_log.debug("{} asynchronous read pending on {}", requestId, input);
|
||||||
if (_log.isDebugEnabled())
|
return Action.IDLE;
|
||||||
_log.debug("{} asynchronous read complete on {}", requestId, input);
|
|
||||||
return Action.SUCCEEDED;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (_log.isDebugEnabled())
|
|
||||||
_log.debug("{} asynchronous read pending on {}", requestId, input);
|
|
||||||
return Action.IDLE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onRequestContent(HttpServletRequest request, Request proxyRequest, DeferredContentProvider provider, byte[] buffer, int offset, int length, Callback callback)
|
protected void onRequestContent(HttpServletRequest request, Request proxyRequest, DeferredContentProvider provider, byte[] buffer, int offset, int length, Callback callback)
|
||||||
|
|
|
@ -52,18 +52,19 @@ import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
@RunWith(Parameterized.class)
|
||||||
public class AsyncProxyServletLoadTest
|
public class ProxyServletLoadTest
|
||||||
{
|
{
|
||||||
@Parameterized.Parameters(name = "{0}")
|
@Parameterized.Parameters(name = "{0}")
|
||||||
public static Iterable<Object[]> data()
|
public static Iterable<Object[]> data()
|
||||||
{
|
{
|
||||||
return Arrays.asList(new Object[][]{
|
return Arrays.asList(new Object[][]{
|
||||||
|
{ProxyServlet.class},
|
||||||
{AsyncProxyServlet.class},
|
{AsyncProxyServlet.class},
|
||||||
{AsyncMiddleManServlet.class}
|
{AsyncMiddleManServlet.class}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Logger LOG = Log.getLogger(AsyncProxyServletLoadTest.class);
|
private static final Logger LOG = Log.getLogger(ProxyServletLoadTest.class);
|
||||||
private static final String PROXIED_HEADER = "X-Proxied";
|
private static final String PROXIED_HEADER = "X-Proxied";
|
||||||
|
|
||||||
private HttpClient client;
|
private HttpClient client;
|
||||||
|
@ -73,7 +74,7 @@ public class AsyncProxyServletLoadTest
|
||||||
private Server server;
|
private Server server;
|
||||||
private ServerConnector serverConnector;
|
private ServerConnector serverConnector;
|
||||||
|
|
||||||
public AsyncProxyServletLoadTest(Class<?> proxyServletClass) throws Exception
|
public ProxyServletLoadTest(Class<?> proxyServletClass) throws Exception
|
||||||
{
|
{
|
||||||
proxyServlet = (AbstractProxyServlet)proxyServletClass.newInstance();
|
proxyServlet = (AbstractProxyServlet)proxyServletClass.newInstance();
|
||||||
}
|
}
|
||||||
|
@ -170,7 +171,7 @@ public class AsyncProxyServletLoadTest
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.assertTrue(activeClientLatch.await(clientCount * iterations * 10, TimeUnit.MILLISECONDS));
|
Assert.assertTrue(activeClientLatch.await(Math.max(clientCount * iterations * 10, 5000), TimeUnit.MILLISECONDS));
|
||||||
Assert.assertTrue(success.get());
|
Assert.assertTrue(success.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +212,7 @@ public class AsyncProxyServletLoadTest
|
||||||
|
|
||||||
if (response.getStatus() != 200)
|
if (response.getStatus() != 200)
|
||||||
{
|
{
|
||||||
LOG.warn("Got response <{}>, expecting <{}>", response.getStatus(), 200);
|
LOG.warn("Got response <{}>, expecting <{}> iteration=", response.getStatus(), 200,iterations);
|
||||||
// allow all ClientLoops to finish
|
// allow all ClientLoops to finish
|
||||||
success.set(false);
|
success.set(false);
|
||||||
}
|
}
|
||||||
|
@ -224,7 +225,7 @@ public class AsyncProxyServletLoadTest
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
LOG.warn("Error processing request", x);
|
LOG.warn("Error processing request "+iterations, x);
|
||||||
success.set(false);
|
success.set(false);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
|
@ -417,7 +417,12 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
|
||||||
status == HttpStatus.NO_CONTENT_204 ||
|
status == HttpStatus.NO_CONTENT_204 ||
|
||||||
status == HttpStatus.NOT_MODIFIED_304);
|
status == HttpStatus.NOT_MODIFIED_304);
|
||||||
if (hasContent && !_response.isContentComplete(_response.getHttpOutput().getWritten()))
|
if (hasContent && !_response.isContentComplete(_response.getHttpOutput().getWritten()))
|
||||||
_transport.abort(new IOException("insufficient content written"));
|
{
|
||||||
|
if (isCommitted())
|
||||||
|
_transport.abort(new IOException("insufficient content written"));
|
||||||
|
else
|
||||||
|
_response.sendError(HttpStatus.INTERNAL_SERVER_ERROR_500,"insufficient content written");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_response.closeOutput();
|
_response.closeOutput();
|
||||||
_request.setHandled(true);
|
_request.setHandled(true);
|
||||||
|
|
|
@ -18,10 +18,6 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.server;
|
package org.eclipse.jetty.server;
|
||||||
|
|
||||||
import static javax.servlet.RequestDispatcher.ERROR_EXCEPTION;
|
|
||||||
import static javax.servlet.RequestDispatcher.ERROR_MESSAGE;
|
|
||||||
import static javax.servlet.RequestDispatcher.ERROR_STATUS_CODE;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
@ -42,6 +38,10 @@ import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.util.thread.Locker;
|
import org.eclipse.jetty.util.thread.Locker;
|
||||||
import org.eclipse.jetty.util.thread.Scheduler;
|
import org.eclipse.jetty.util.thread.Scheduler;
|
||||||
|
|
||||||
|
import static javax.servlet.RequestDispatcher.ERROR_EXCEPTION;
|
||||||
|
import static javax.servlet.RequestDispatcher.ERROR_MESSAGE;
|
||||||
|
import static javax.servlet.RequestDispatcher.ERROR_STATUS_CODE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of AsyncContext interface that holds the state of request-response cycle.
|
* Implementation of AsyncContext interface that holds the state of request-response cycle.
|
||||||
*/
|
*/
|
||||||
|
@ -87,7 +87,7 @@ public class HttpChannelState
|
||||||
/**
|
/**
|
||||||
* The state of the servlet async API.
|
* The state of the servlet async API.
|
||||||
*/
|
*/
|
||||||
public enum Async
|
private enum Async
|
||||||
{
|
{
|
||||||
NOT_ASYNC,
|
NOT_ASYNC,
|
||||||
STARTED, // AsyncContext.startAsync() has been called
|
STARTED, // AsyncContext.startAsync() has been called
|
||||||
|
@ -99,27 +99,24 @@ public class HttpChannelState
|
||||||
ERRORED // The error has been processed
|
ERRORED // The error has been processed
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Interest
|
private enum Interest
|
||||||
{
|
{
|
||||||
NONE(false),
|
NONE(false),
|
||||||
NEEDED(true),
|
NEEDED(true),
|
||||||
INTERESTED(true);
|
REGISTERED(true);
|
||||||
|
|
||||||
final boolean _interested;
|
private final boolean _interested;
|
||||||
boolean isInterested() { return _interested;}
|
|
||||||
boolean notInterested() { return !_interested;}
|
|
||||||
|
|
||||||
Interest(boolean interest)
|
Interest(boolean interest)
|
||||||
{
|
{
|
||||||
_interested = interest;
|
_interested = interest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isInterested() { return _interested;}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final boolean DEBUG=LOG.isDebugEnabled();
|
|
||||||
private final Locker _locker=new Locker();
|
private final Locker _locker=new Locker();
|
||||||
private final HttpChannel _channel;
|
private final HttpChannel _channel;
|
||||||
|
|
||||||
private List<AsyncListener> _asyncListeners;
|
private List<AsyncListener> _asyncListeners;
|
||||||
private State _state;
|
private State _state;
|
||||||
private Async _async;
|
private Async _async;
|
||||||
|
@ -223,7 +220,7 @@ public class HttpChannelState
|
||||||
{
|
{
|
||||||
try(Locker.Lock lock= _locker.lock())
|
try(Locker.Lock lock= _locker.lock())
|
||||||
{
|
{
|
||||||
if(DEBUG)
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("handling {}",toStringLocked());
|
LOG.debug("handling {}",toStringLocked());
|
||||||
|
|
||||||
switch(_state)
|
switch(_state)
|
||||||
|
@ -298,7 +295,7 @@ public class HttpChannelState
|
||||||
|
|
||||||
try(Locker.Lock lock= _locker.lock())
|
try(Locker.Lock lock= _locker.lock())
|
||||||
{
|
{
|
||||||
if(DEBUG)
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("startAsync {}",toStringLocked());
|
LOG.debug("startAsync {}",toStringLocked());
|
||||||
if (_state!=State.DISPATCHED || _async!=Async.NOT_ASYNC)
|
if (_state!=State.DISPATCHED || _async!=Async.NOT_ASYNC)
|
||||||
throw new IllegalStateException(this.getStatusStringLocked());
|
throw new IllegalStateException(this.getStatusStringLocked());
|
||||||
|
@ -340,7 +337,6 @@ public class HttpChannelState
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void asyncError(Throwable failure)
|
public void asyncError(Throwable failure)
|
||||||
{
|
{
|
||||||
AsyncContextEvent event = null;
|
AsyncContextEvent event = null;
|
||||||
|
@ -394,7 +390,7 @@ public class HttpChannelState
|
||||||
|
|
||||||
try(Locker.Lock lock= _locker.lock())
|
try(Locker.Lock lock= _locker.lock())
|
||||||
{
|
{
|
||||||
if(DEBUG)
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("unhandle {}",toStringLocked());
|
LOG.debug("unhandle {}",toStringLocked());
|
||||||
|
|
||||||
switch(_state)
|
switch(_state)
|
||||||
|
@ -432,7 +428,9 @@ public class HttpChannelState
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STARTED:
|
case STARTED:
|
||||||
if (_asyncRead.isInterested() && _asyncReadPossible)
|
// If a read is possible and either we are interested in reads or we have
|
||||||
|
// to call onAllDataRead, then we need a READ_CALLBACK
|
||||||
|
if (_asyncReadPossible && (_asyncRead.isInterested() || _channel.getRequest().getHttpInput().isAsyncEOF()))
|
||||||
{
|
{
|
||||||
_state=State.ASYNC_IO;
|
_state=State.ASYNC_IO;
|
||||||
_asyncRead=Interest.NONE;
|
_asyncRead=Interest.NONE;
|
||||||
|
@ -450,7 +448,7 @@ public class HttpChannelState
|
||||||
action=Action.WAIT;
|
action=Action.WAIT;
|
||||||
if (_asyncRead==Interest.NEEDED)
|
if (_asyncRead==Interest.NEEDED)
|
||||||
{
|
{
|
||||||
_asyncRead=Interest.INTERESTED;
|
_asyncRead=Interest.REGISTERED;
|
||||||
read_interested=true;
|
read_interested=true;
|
||||||
}
|
}
|
||||||
Scheduler scheduler=_channel.getScheduler();
|
Scheduler scheduler=_channel.getScheduler();
|
||||||
|
@ -503,7 +501,7 @@ public class HttpChannelState
|
||||||
AsyncContextEvent event;
|
AsyncContextEvent event;
|
||||||
try(Locker.Lock lock= _locker.lock())
|
try(Locker.Lock lock= _locker.lock())
|
||||||
{
|
{
|
||||||
if(DEBUG)
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("dispatch {} -> {}",toStringLocked(),path);
|
LOG.debug("dispatch {} -> {}",toStringLocked(),path);
|
||||||
|
|
||||||
boolean started=false;
|
boolean started=false;
|
||||||
|
@ -557,7 +555,7 @@ public class HttpChannelState
|
||||||
AsyncContextEvent event;
|
AsyncContextEvent event;
|
||||||
try(Locker.Lock lock= _locker.lock())
|
try(Locker.Lock lock= _locker.lock())
|
||||||
{
|
{
|
||||||
if(DEBUG)
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("onTimeout {}",toStringLocked());
|
LOG.debug("onTimeout {}",toStringLocked());
|
||||||
|
|
||||||
if (_async!=Async.STARTED)
|
if (_async!=Async.STARTED)
|
||||||
|
@ -656,7 +654,7 @@ public class HttpChannelState
|
||||||
AsyncContextEvent event;
|
AsyncContextEvent event;
|
||||||
try(Locker.Lock lock= _locker.lock())
|
try(Locker.Lock lock= _locker.lock())
|
||||||
{
|
{
|
||||||
if(DEBUG)
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("complete {}",toStringLocked());
|
LOG.debug("complete {}",toStringLocked());
|
||||||
|
|
||||||
boolean started=false;
|
boolean started=false;
|
||||||
|
@ -694,7 +692,7 @@ public class HttpChannelState
|
||||||
{
|
{
|
||||||
try(Locker.Lock lock= _locker.lock())
|
try(Locker.Lock lock= _locker.lock())
|
||||||
{
|
{
|
||||||
if(DEBUG)
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("error complete {}",toStringLocked());
|
LOG.debug("error complete {}",toStringLocked());
|
||||||
|
|
||||||
_async=Async.COMPLETE;
|
_async=Async.COMPLETE;
|
||||||
|
@ -729,7 +727,7 @@ public class HttpChannelState
|
||||||
|
|
||||||
try(Locker.Lock lock= _locker.lock())
|
try(Locker.Lock lock= _locker.lock())
|
||||||
{
|
{
|
||||||
if(DEBUG)
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("onError {} {}",toStringLocked(),failure);
|
LOG.debug("onError {} {}",toStringLocked(),failure);
|
||||||
|
|
||||||
// Set error on request.
|
// Set error on request.
|
||||||
|
@ -739,8 +737,7 @@ public class HttpChannelState
|
||||||
_event.getSuppliedRequest().setAttribute(ERROR_STATUS_CODE,code);
|
_event.getSuppliedRequest().setAttribute(ERROR_STATUS_CODE,code);
|
||||||
_event.getSuppliedRequest().setAttribute(ERROR_EXCEPTION,failure);
|
_event.getSuppliedRequest().setAttribute(ERROR_EXCEPTION,failure);
|
||||||
_event.getSuppliedRequest().setAttribute(RequestDispatcher.ERROR_EXCEPTION_TYPE,failure==null?null:failure.getClass());
|
_event.getSuppliedRequest().setAttribute(RequestDispatcher.ERROR_EXCEPTION_TYPE,failure==null?null:failure.getClass());
|
||||||
|
_event.getSuppliedRequest().setAttribute(ERROR_MESSAGE,reason);
|
||||||
_event.getSuppliedRequest().setAttribute(ERROR_MESSAGE,reason!=null?reason:null);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -750,7 +747,7 @@ public class HttpChannelState
|
||||||
baseRequest.setAttribute(ERROR_STATUS_CODE,code);
|
baseRequest.setAttribute(ERROR_STATUS_CODE,code);
|
||||||
baseRequest.setAttribute(ERROR_EXCEPTION,failure);
|
baseRequest.setAttribute(ERROR_EXCEPTION,failure);
|
||||||
baseRequest.setAttribute(RequestDispatcher.ERROR_EXCEPTION_TYPE,failure==null?null:failure.getClass());
|
baseRequest.setAttribute(RequestDispatcher.ERROR_EXCEPTION_TYPE,failure==null?null:failure.getClass());
|
||||||
baseRequest.setAttribute(ERROR_MESSAGE,reason!=null?reason:null);
|
baseRequest.setAttribute(ERROR_MESSAGE,reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Are we blocking?
|
// Are we blocking?
|
||||||
|
@ -847,7 +844,7 @@ public class HttpChannelState
|
||||||
|
|
||||||
try(Locker.Lock lock= _locker.lock())
|
try(Locker.Lock lock= _locker.lock())
|
||||||
{
|
{
|
||||||
if(DEBUG)
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("onComplete {}",toStringLocked());
|
LOG.debug("onComplete {}",toStringLocked());
|
||||||
|
|
||||||
switch(_state)
|
switch(_state)
|
||||||
|
@ -904,7 +901,7 @@ public class HttpChannelState
|
||||||
cancelTimeout();
|
cancelTimeout();
|
||||||
try(Locker.Lock lock= _locker.lock())
|
try(Locker.Lock lock= _locker.lock())
|
||||||
{
|
{
|
||||||
if(DEBUG)
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("recycle {}",toStringLocked());
|
LOG.debug("recycle {}",toStringLocked());
|
||||||
|
|
||||||
switch(_state)
|
switch(_state)
|
||||||
|
@ -934,7 +931,7 @@ public class HttpChannelState
|
||||||
cancelTimeout();
|
cancelTimeout();
|
||||||
try(Locker.Lock lock= _locker.lock())
|
try(Locker.Lock lock= _locker.lock())
|
||||||
{
|
{
|
||||||
if(DEBUG)
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("upgrade {}",toStringLocked());
|
LOG.debug("upgrade {}",toStringLocked());
|
||||||
|
|
||||||
switch(_state)
|
switch(_state)
|
||||||
|
@ -1124,9 +1121,8 @@ public class HttpChannelState
|
||||||
_channel.getRequest().setAttribute(name,attribute);
|
_channel.getRequest().setAttribute(name,attribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
/* ------------------------------------------------------------ */
|
* Called to signal async read isReady() has returned false.
|
||||||
/** Called to signal async read isReady() has returned false.
|
|
||||||
* This indicates that there is no content available to be consumed
|
* This indicates that there is no content available to be consumed
|
||||||
* and that once the channel enteres the ASYNC_WAIT state it will
|
* and that once the channel enteres the ASYNC_WAIT state it will
|
||||||
* register for read interest by calling {@link HttpChannel#asyncReadFillInterested()}
|
* register for read interest by calling {@link HttpChannel#asyncReadFillInterested()}
|
||||||
|
@ -1137,17 +1133,17 @@ public class HttpChannelState
|
||||||
boolean interested=false;
|
boolean interested=false;
|
||||||
try(Locker.Lock lock= _locker.lock())
|
try(Locker.Lock lock= _locker.lock())
|
||||||
{
|
{
|
||||||
if(DEBUG)
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("onReadUnready {}",toStringLocked());
|
LOG.debug("onReadUnready {}",toStringLocked());
|
||||||
|
|
||||||
// We were already unready, this is not a state change, so do nothing
|
// We were already unready, this is not a state change, so do nothing
|
||||||
if (_asyncRead!=Interest.INTERESTED)
|
if (_asyncRead!=Interest.REGISTERED)
|
||||||
{
|
{
|
||||||
_asyncReadPossible=false; // Assumes this has been checked in isReady() with lock held
|
_asyncReadPossible=false; // Assumes this has been checked in isReady() with lock held
|
||||||
if (_state==State.ASYNC_WAIT)
|
if (_state==State.ASYNC_WAIT)
|
||||||
{
|
{
|
||||||
interested=true;
|
interested=true;
|
||||||
_asyncRead=Interest.INTERESTED;
|
_asyncRead=Interest.REGISTERED;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
_asyncRead=Interest.NEEDED;
|
_asyncRead=Interest.NEEDED;
|
||||||
|
@ -1158,8 +1154,8 @@ public class HttpChannelState
|
||||||
_channel.asyncReadFillInterested();
|
_channel.asyncReadFillInterested();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/**
|
||||||
/** Called to signal that content is now available to read.
|
* Called to signal that content is now available to read.
|
||||||
* If the channel is in ASYNC_WAIT state and unready (ie isReady() has
|
* If the channel is in ASYNC_WAIT state and unready (ie isReady() has
|
||||||
* returned false), then the state is changed to ASYNC_WOKEN and true
|
* returned false), then the state is changed to ASYNC_WOKEN and true
|
||||||
* is returned.
|
* is returned.
|
||||||
|
@ -1170,7 +1166,7 @@ public class HttpChannelState
|
||||||
boolean woken=false;
|
boolean woken=false;
|
||||||
try(Locker.Lock lock= _locker.lock())
|
try(Locker.Lock lock= _locker.lock())
|
||||||
{
|
{
|
||||||
if(DEBUG)
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("onReadPossible {}",toStringLocked());
|
LOG.debug("onReadPossible {}",toStringLocked());
|
||||||
|
|
||||||
_asyncReadPossible=true;
|
_asyncReadPossible=true;
|
||||||
|
@ -1183,8 +1179,8 @@ public class HttpChannelState
|
||||||
return woken;
|
return woken;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/**
|
||||||
/** Called to signal that the channel is ready for a callback.
|
* Called to signal that the channel is ready for a callback.
|
||||||
* This is similar to calling {@link #onReadUnready()} followed by
|
* This is similar to calling {@link #onReadUnready()} followed by
|
||||||
* {@link #onReadPossible()}, except that as content is already
|
* {@link #onReadPossible()}, except that as content is already
|
||||||
* available, read interest is never set.
|
* available, read interest is never set.
|
||||||
|
@ -1195,10 +1191,10 @@ public class HttpChannelState
|
||||||
boolean woken=false;
|
boolean woken=false;
|
||||||
try(Locker.Lock lock= _locker.lock())
|
try(Locker.Lock lock= _locker.lock())
|
||||||
{
|
{
|
||||||
if(DEBUG)
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("onReadReady {}",toStringLocked());
|
LOG.debug("onReadReady {}",toStringLocked());
|
||||||
|
|
||||||
_asyncRead=Interest.INTERESTED;
|
_asyncRead=Interest.REGISTERED;
|
||||||
_asyncReadPossible=true;
|
_asyncReadPossible=true;
|
||||||
if (_state==State.ASYNC_WAIT)
|
if (_state==State.ASYNC_WAIT)
|
||||||
{
|
{
|
||||||
|
@ -1209,8 +1205,8 @@ public class HttpChannelState
|
||||||
return woken;
|
return woken;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/**
|
||||||
/** Called to signal that a read has read -1.
|
* Called to signal that a read has read -1.
|
||||||
* Will wake if the read was called while in ASYNC_WAIT state
|
* Will wake if the read was called while in ASYNC_WAIT state
|
||||||
* @return true if woken
|
* @return true if woken
|
||||||
*/
|
*/
|
||||||
|
@ -1219,21 +1215,20 @@ public class HttpChannelState
|
||||||
boolean woken=false;
|
boolean woken=false;
|
||||||
try(Locker.Lock lock= _locker.lock())
|
try(Locker.Lock lock= _locker.lock())
|
||||||
{
|
{
|
||||||
if(DEBUG)
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("onReadEof {}",toStringLocked());
|
LOG.debug("onReadEof {}",toStringLocked());
|
||||||
|
|
||||||
if (_state==State.ASYNC_WAIT)
|
if (_state==State.ASYNC_WAIT)
|
||||||
{
|
{
|
||||||
woken=true;
|
woken=true;
|
||||||
_state=State.ASYNC_WOKEN;
|
_state=State.ASYNC_WOKEN;
|
||||||
_asyncRead=Interest.INTERESTED;
|
_asyncRead=Interest.REGISTERED;
|
||||||
_asyncReadPossible=true;
|
_asyncReadPossible=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return woken;
|
return woken;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public boolean isReadPossible()
|
public boolean isReadPossible()
|
||||||
{
|
{
|
||||||
try(Locker.Lock lock= _locker.lock())
|
try(Locker.Lock lock= _locker.lock())
|
||||||
|
@ -1242,14 +1237,13 @@ public class HttpChannelState
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public boolean onWritePossible()
|
public boolean onWritePossible()
|
||||||
{
|
{
|
||||||
boolean handle=false;
|
boolean handle=false;
|
||||||
|
|
||||||
try(Locker.Lock lock= _locker.lock())
|
try(Locker.Lock lock= _locker.lock())
|
||||||
{
|
{
|
||||||
if(DEBUG)
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("onWritePossible {}",toStringLocked());
|
LOG.debug("onWritePossible {}",toStringLocked());
|
||||||
|
|
||||||
_asyncWritePossible=true;
|
_asyncWritePossible=true;
|
||||||
|
@ -1262,5 +1256,4 @@ public class HttpChannelState
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -709,6 +709,14 @@ public class HttpInput extends ServletInputStream implements Runnable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAsyncEOF()
|
||||||
|
{
|
||||||
|
synchronized (_inputQ)
|
||||||
|
{
|
||||||
|
return _state == AEOF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isReady()
|
public boolean isReady()
|
||||||
{
|
{
|
||||||
|
@ -1121,4 +1129,5 @@ public class HttpInput extends ServletInputStream implements Runnable
|
||||||
return "AEOF";
|
return "AEOF";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1114,8 +1114,10 @@ public class Response implements HttpServletResponse
|
||||||
@Override
|
@Override
|
||||||
public void setBufferSize(int size)
|
public void setBufferSize(int size)
|
||||||
{
|
{
|
||||||
if (isCommitted() || getContentCount() > 0)
|
if (isCommitted())
|
||||||
throw new IllegalStateException("cannot set buffer size when response is committed or written to");
|
throw new IllegalStateException("cannot set buffer size after response is in committed state");
|
||||||
|
if (getContentCount() > 0)
|
||||||
|
throw new IllegalStateException("cannot set buffer size after response has " + getContentCount() + " bytes already written");
|
||||||
if (size < __MIN_BUFFER_SIZE)
|
if (size < __MIN_BUFFER_SIZE)
|
||||||
size = __MIN_BUFFER_SIZE;
|
size = __MIN_BUFFER_SIZE;
|
||||||
_out.setBufferSize(size);
|
_out.setBufferSize(size);
|
||||||
|
@ -1215,7 +1217,9 @@ public class Response implements HttpServletResponse
|
||||||
|
|
||||||
protected MetaData.Response newResponseMetaData()
|
protected MetaData.Response newResponseMetaData()
|
||||||
{
|
{
|
||||||
return new MetaData.Response(_channel.getRequest().getHttpVersion(), getStatus(), getReason(), _fields, getLongContentLength());
|
MetaData.Response info = new MetaData.Response(_channel.getRequest().getHttpVersion(), getStatus(), getReason(), _fields, getLongContentLength());
|
||||||
|
// TODO info.setTrailerSupplier(trailers);
|
||||||
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get the MetaData.Response committed for this response.
|
/** Get the MetaData.Response committed for this response.
|
||||||
|
|
|
@ -761,7 +761,18 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
||||||
throw new IllegalStateException("Null contextPath");
|
throw new IllegalStateException("Null contextPath");
|
||||||
|
|
||||||
if (_logger==null)
|
if (_logger==null)
|
||||||
_logger = Log.getLogger(getDisplayName() == null?getContextPath():getDisplayName());
|
{
|
||||||
|
String log_name = getDisplayName();
|
||||||
|
if (log_name == null || log_name.isEmpty())
|
||||||
|
{
|
||||||
|
log_name = getContextPath();
|
||||||
|
if (log_name!=null || log_name.startsWith("/"))
|
||||||
|
log_name = log_name.substring(1);
|
||||||
|
if (log_name==null || log_name.isEmpty())
|
||||||
|
log_name = Integer.toHexString(hashCode());
|
||||||
|
}
|
||||||
|
_logger = Log.getLogger("org.eclipse.jetty.ContextHandler."+log_name);
|
||||||
|
}
|
||||||
ClassLoader old_classloader = null;
|
ClassLoader old_classloader = null;
|
||||||
Thread current_thread = null;
|
Thread current_thread = null;
|
||||||
Context old_context = null;
|
Context old_context = null;
|
||||||
|
|
|
@ -20,6 +20,7 @@ package org.eclipse.jetty.server;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.hamcrest.Matchers.not;
|
import static org.hamcrest.Matchers.not;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
@ -442,10 +443,22 @@ public class HttpManyWaysToCommitTest extends AbstractHttpTest
|
||||||
server.start();
|
server.start();
|
||||||
|
|
||||||
HttpTester.Response response = executeRequest();
|
HttpTester.Response response = executeRequest();
|
||||||
assertThat("response has no status", response.getStatus(), is(0));
|
assertThat("response is error", response.getStatus(), is(500));
|
||||||
|
assertFalse("response not eof", response.isEarlyEOF());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetContentLengthAndFlushWriteInsufficientBytes() throws Exception
|
||||||
|
{
|
||||||
|
server.setHandler(new SetContentLengthAndWriteInsufficientBytesHandler(true));
|
||||||
|
server.start();
|
||||||
|
|
||||||
|
HttpTester.Response response = executeRequest();
|
||||||
|
assertThat("response has no status", response.getStatus(), is(200));
|
||||||
assertTrue("response eof", response.isEarlyEOF());
|
assertTrue("response eof", response.isEarlyEOF());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSetContentLengthAndWriteExactlyThatAmountOfBytes() throws Exception
|
public void testSetContentLengthAndWriteExactlyThatAmountOfBytes() throws Exception
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.start;
|
package org.eclipse.jetty.start;
|
||||||
|
|
||||||
|
import static org.eclipse.jetty.start.UsageException.ERR_BAD_GRAPH;
|
||||||
|
import static org.eclipse.jetty.start.UsageException.ERR_BAD_STOP_PROPS;
|
||||||
import static org.eclipse.jetty.start.UsageException.ERR_INVOKE_MAIN;
|
import static org.eclipse.jetty.start.UsageException.ERR_INVOKE_MAIN;
|
||||||
import static org.eclipse.jetty.start.UsageException.ERR_NOT_STOPPED;
|
import static org.eclipse.jetty.start.UsageException.ERR_NOT_STOPPED;
|
||||||
import static org.eclipse.jetty.start.UsageException.ERR_UNKNOWN;
|
import static org.eclipse.jetty.start.UsageException.ERR_UNKNOWN;
|
||||||
|
@ -492,19 +494,38 @@ public class Main
|
||||||
|
|
||||||
private void doStop(StartArgs args)
|
private void doStop(StartArgs args)
|
||||||
{
|
{
|
||||||
String stopHost = args.getProperties().getString("STOP.HOST");
|
Props.Prop stopHostProp = args.getProperties().getProp("STOP.HOST", true);
|
||||||
int stopPort = Integer.parseInt(args.getProperties().getString("STOP.PORT"));
|
Props.Prop stopPortProp = args.getProperties().getProp("STOP.PORT", true);
|
||||||
String stopKey = args.getProperties().getString("STOP.KEY");
|
Props.Prop stopKeyProp = args.getProperties().getProp("STOP.KEY", true);
|
||||||
|
Props.Prop stopWaitProp = args.getProperties().getProp("STOP.WAIT", true);
|
||||||
|
|
||||||
if (args.getProperties().getString("STOP.WAIT") != null)
|
String stopHost = "127.0.0.1";
|
||||||
|
int stopPort = -1;
|
||||||
|
String stopKey = "";
|
||||||
|
|
||||||
|
if (stopHostProp != null)
|
||||||
{
|
{
|
||||||
int stopWait = Integer.parseInt(args.getProperties().getString("STOP.WAIT"));
|
stopHost = stopHostProp.value;
|
||||||
|
}
|
||||||
|
|
||||||
stop(stopHost,stopPort,stopKey,stopWait);
|
if (stopPortProp != null)
|
||||||
|
{
|
||||||
|
stopPort = Integer.parseInt(stopPortProp.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(stopKeyProp != null)
|
||||||
|
{
|
||||||
|
stopKey = stopKeyProp.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stopWaitProp != null)
|
||||||
|
{
|
||||||
|
int stopWait = Integer.parseInt(stopWaitProp.value);
|
||||||
|
stop(stopHost, stopPort, stopKey, stopWait);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stop(stopHost,stopPort,stopKey);
|
stop(stopHost, stopPort, stopKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,19 +543,22 @@ public class Main
|
||||||
public void stop(String host, int port, String key, int timeout)
|
public void stop(String host, int port, String key, int timeout)
|
||||||
{
|
{
|
||||||
if (host==null || host.length()==0)
|
if (host==null || host.length()==0)
|
||||||
host="127.0.0.1";
|
{
|
||||||
|
host = "127.0.0.1";
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (port <= 0)
|
if ( (port <= 0) || (port > 65535) )
|
||||||
{
|
{
|
||||||
StartLog.error("STOP.PORT system property must be specified");
|
System.err.println("STOP.PORT property must be specified with a valid port number");
|
||||||
|
usageExit(ERR_BAD_STOP_PROPS);
|
||||||
}
|
}
|
||||||
if (key == null)
|
if (key == null)
|
||||||
{
|
{
|
||||||
key = "";
|
key = "";
|
||||||
StartLog.info("STOP.KEY system property must be specified");
|
System.err.println("STOP.KEY property must be specified");
|
||||||
StartLog.info("Using empty key");
|
System.err.println("Using empty key");
|
||||||
}
|
}
|
||||||
|
|
||||||
try (Socket s = new Socket(InetAddress.getByName(host),port))
|
try (Socket s = new Socket(InetAddress.getByName(host),port))
|
||||||
|
|
|
@ -29,6 +29,7 @@ public class UsageException extends RuntimeException
|
||||||
public static final int ERR_NOT_STOPPED = -4;
|
public static final int ERR_NOT_STOPPED = -4;
|
||||||
public static final int ERR_BAD_ARG = -5;
|
public static final int ERR_BAD_ARG = -5;
|
||||||
public static final int ERR_BAD_GRAPH = -6;
|
public static final int ERR_BAD_GRAPH = -6;
|
||||||
|
public static final int ERR_BAD_STOP_PROPS = -7;
|
||||||
public static final int ERR_UNKNOWN = -9;
|
public static final int ERR_UNKNOWN = -9;
|
||||||
private int exitCode;
|
private int exitCode;
|
||||||
|
|
||||||
|
|
|
@ -16,4 +16,4 @@ logging
|
||||||
-Dorg.eclipse.jetty.util.log.class?=org.eclipse.jetty.util.log.Slf4jLog
|
-Dorg.eclipse.jetty.util.log.class?=org.eclipse.jetty.util.log.Slf4jLog
|
||||||
|
|
||||||
[ini]
|
[ini]
|
||||||
jetty.webapp.addServerClasses+=,file:${jetty.base}/lib/slf4j/
|
jetty.webapp.addServerClasses+=,${jetty.base.uri}/lib/slf4j/
|
||||||
|
|
|
@ -16,4 +16,4 @@ logging
|
||||||
-Dorg.eclipse.jetty.util.log.class?=org.eclipse.jetty.util.log.Slf4jLog
|
-Dorg.eclipse.jetty.util.log.class?=org.eclipse.jetty.util.log.Slf4jLog
|
||||||
|
|
||||||
[ini]
|
[ini]
|
||||||
jetty.webapp.addServerClasses+=,file:${jetty.base}/lib/slf4j/,file:${jetty.base}/lib/log4j/
|
jetty.webapp.addServerClasses+=,${jetty.base.uri}/lib/slf4j/,${jetty.base.uri}/lib/log4j/
|
||||||
|
|
|
@ -16,4 +16,4 @@ logging
|
||||||
-Dorg.eclipse.jetty.util.log.class?=org.eclipse.jetty.util.log.Slf4jLog
|
-Dorg.eclipse.jetty.util.log.class?=org.eclipse.jetty.util.log.Slf4jLog
|
||||||
|
|
||||||
[ini]
|
[ini]
|
||||||
jetty.webapp.addServerClasses+=,file:${jetty.base}/lib/slf4j/,file:${jetty.base}/lib/log4j2/
|
jetty.webapp.addServerClasses+=,${jetty.base.uri}/lib/slf4j/,${jetty.base.uri}/lib/log4j2/
|
||||||
|
|
|
@ -16,4 +16,4 @@ logging
|
||||||
-Dorg.eclipse.jetty.util.log.class?=org.eclipse.jetty.util.log.Slf4jLog
|
-Dorg.eclipse.jetty.util.log.class?=org.eclipse.jetty.util.log.Slf4jLog
|
||||||
|
|
||||||
[ini]
|
[ini]
|
||||||
jetty.webapp.addServerClasses+=,file:${jetty.base}/lib/slf4j/,file:${jetty.base}/lib/logback/
|
jetty.webapp.addServerClasses+=,${jetty.base.uri}/lib/slf4j/,${jetty.base.uri}/lib/logback/
|
||||||
|
|
|
@ -16,4 +16,4 @@ logging
|
||||||
-Dorg.eclipse.jetty.util.log.class?=org.eclipse.jetty.util.log.Slf4jLog
|
-Dorg.eclipse.jetty.util.log.class?=org.eclipse.jetty.util.log.Slf4jLog
|
||||||
|
|
||||||
[ini]
|
[ini]
|
||||||
jetty.webapp.addServerClasses+=,file:${jetty.base}/lib/slf4j/
|
jetty.webapp.addServerClasses+=,${jetty.base.uri}/lib/slf4j/
|
||||||
|
|
|
@ -19,8 +19,10 @@
|
||||||
package org.eclipse.jetty.util;
|
package org.eclipse.jetty.util;
|
||||||
|
|
||||||
|
|
||||||
|
import org.eclipse.jetty.toolchain.test.JDK;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
import org.junit.Assume;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class TypeUtilTest
|
public class TypeUtilTest
|
||||||
|
@ -124,8 +126,18 @@ public class TypeUtilTest
|
||||||
@Test
|
@Test
|
||||||
public void testLoadedFrom() throws Exception
|
public void testLoadedFrom() throws Exception
|
||||||
{
|
{
|
||||||
|
Assume.assumeFalse(JDK.IS_9);
|
||||||
Assert.assertThat(TypeUtil.getLoadedFrom(String.class).toString(),Matchers.containsString("/rt.jar"));
|
Assert.assertThat(TypeUtil.getLoadedFrom(String.class).toString(),Matchers.containsString("/rt.jar"));
|
||||||
Assert.assertThat(TypeUtil.getLoadedFrom(Assert.class).toString(),Matchers.containsString(".jar"));
|
Assert.assertThat(TypeUtil.getLoadedFrom(Assert.class).toString(),Matchers.containsString(".jar"));
|
||||||
Assert.assertThat(TypeUtil.getLoadedFrom(TypeUtil.class).toString(),Matchers.containsString("/classes/"));
|
Assert.assertThat(TypeUtil.getLoadedFrom(TypeUtil.class).toString(),Matchers.containsString("/classes/"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLoadedFrom9() throws Exception
|
||||||
|
{
|
||||||
|
Assume.assumeTrue(JDK.IS_9);
|
||||||
|
Assert.assertThat(TypeUtil.getLoadedFrom(String.class).toString(),Matchers.containsString("jrt:/java.base/java/lang/String.clas"));
|
||||||
|
Assert.assertThat(TypeUtil.getLoadedFrom(Assert.class).toString(),Matchers.containsString(".jar"));
|
||||||
|
Assert.assertThat(TypeUtil.getLoadedFrom(TypeUtil.class).toString(),Matchers.containsString("/classes/"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,8 @@ lib/jetty-webapp-${jetty.version}.jar
|
||||||
## Lists of patterns are comma separated and may be either:
|
## Lists of patterns are comma separated and may be either:
|
||||||
## + a qualified classname e.g. 'com.acme.Foo'
|
## + a qualified classname e.g. 'com.acme.Foo'
|
||||||
## + a package name e.g. 'net.example.'
|
## + a package name e.g. 'net.example.'
|
||||||
## + a jar file e.g. 'file:${jetty.base}/lib/dependency.jar'
|
## + a jar file e.g. '${jetty.base.uri}/lib/dependency.jar'
|
||||||
## + a directory of jars,resource or classes e.g. 'file:${jetty.base}/resources'
|
## + a directory of jars,resource or classes e.g. '${jetty.base.uri}/resources'
|
||||||
## + A pattern preceeded with a '-' is an exclusion, all other patterns are inclusions
|
## + A pattern preceeded with a '-' is an exclusion, all other patterns are inclusions
|
||||||
##
|
##
|
||||||
## The +=, operator appends to a CSV list with a comma as needed.
|
## The +=, operator appends to a CSV list with a comma as needed.
|
||||||
|
|
|
@ -1252,7 +1252,7 @@ public class AsyncIOServletTest extends AbstractTest
|
||||||
@Override
|
@Override
|
||||||
public void onDataAvailable() throws IOException
|
public void onDataAvailable() throws IOException
|
||||||
{
|
{
|
||||||
while (input.isReady() && !input.isFinished())
|
while (input.isReady())
|
||||||
{
|
{
|
||||||
int b = input.read();
|
int b = input.read();
|
||||||
if (b>0)
|
if (b>0)
|
||||||
|
@ -1260,8 +1260,8 @@ public class AsyncIOServletTest extends AbstractTest
|
||||||
// System.err.printf("0x%2x %s %n", b, Character.isISOControl(b)?"?":(""+(char)b));
|
// System.err.printf("0x%2x %s %n", b, Character.isISOControl(b)?"?":(""+(char)b));
|
||||||
out.write(b);
|
out.write(b);
|
||||||
}
|
}
|
||||||
else
|
else if (b<0)
|
||||||
onAllDataRead();
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,11 +59,12 @@ public class SessionEvictionFailureTest
|
||||||
*/
|
*/
|
||||||
public static class MockSessionDataStore extends AbstractSessionDataStore
|
public static class MockSessionDataStore extends AbstractSessionDataStore
|
||||||
{
|
{
|
||||||
public boolean _nextResult;
|
public boolean[] _nextStoreResult;
|
||||||
|
public int i = 0;
|
||||||
|
|
||||||
public void setNextResult (boolean goodOrBad)
|
public MockSessionDataStore (boolean[] results)
|
||||||
{
|
{
|
||||||
_nextResult = goodOrBad;
|
_nextStoreResult = results;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -108,7 +109,7 @@ public class SessionEvictionFailureTest
|
||||||
@Override
|
@Override
|
||||||
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
|
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
|
||||||
{
|
{
|
||||||
if (!_nextResult)
|
if (_nextStoreResult != null && !_nextStoreResult[i++])
|
||||||
{
|
{
|
||||||
throw new IllegalStateException("Testing store");
|
throw new IllegalStateException("Testing store");
|
||||||
}
|
}
|
||||||
|
@ -132,6 +133,12 @@ public class SessionEvictionFailureTest
|
||||||
*/
|
*/
|
||||||
public static class MockSessionDataStoreFactory extends AbstractSessionDataStoreFactory
|
public static class MockSessionDataStoreFactory extends AbstractSessionDataStoreFactory
|
||||||
{
|
{
|
||||||
|
public boolean[] _nextStoreResults;
|
||||||
|
|
||||||
|
public void setNextStoreResults(boolean[] storeResults)
|
||||||
|
{
|
||||||
|
_nextStoreResults = storeResults;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.SessionDataStoreFactory#getSessionDataStore(org.eclipse.jetty.server.session.SessionHandler)
|
* @see org.eclipse.jetty.server.session.SessionDataStoreFactory#getSessionDataStore(org.eclipse.jetty.server.session.SessionHandler)
|
||||||
|
@ -139,7 +146,7 @@ public class SessionEvictionFailureTest
|
||||||
@Override
|
@Override
|
||||||
public SessionDataStore getSessionDataStore(SessionHandler handler) throws Exception
|
public SessionDataStore getSessionDataStore(SessionHandler handler) throws Exception
|
||||||
{
|
{
|
||||||
return new MockSessionDataStore();
|
return new MockSessionDataStore(_nextStoreResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -208,7 +215,7 @@ public class SessionEvictionFailureTest
|
||||||
TestServer server = new TestServer (0, inactivePeriod, scavengePeriod, cacheFactory, storeFactory);
|
TestServer server = new TestServer (0, inactivePeriod, scavengePeriod, cacheFactory, storeFactory);
|
||||||
ServletContextHandler context = server.addContext(contextPath);
|
ServletContextHandler context = server.addContext(contextPath);
|
||||||
context.getSessionHandler().getSessionCache().setSaveOnInactiveEviction(true);
|
context.getSessionHandler().getSessionCache().setSaveOnInactiveEviction(true);
|
||||||
MockSessionDataStore ds = new MockSessionDataStore();
|
MockSessionDataStore ds = new MockSessionDataStore(new boolean[] {true, false, true, false, true});
|
||||||
context.getSessionHandler().getSessionCache().setSessionDataStore(ds);
|
context.getSessionHandler().getSessionCache().setSessionDataStore(ds);
|
||||||
|
|
||||||
TestServlet servlet = new TestServlet();
|
TestServlet servlet = new TestServlet();
|
||||||
|
@ -226,7 +233,6 @@ public class SessionEvictionFailureTest
|
||||||
String url = "http://localhost:" + port1 + contextPath + servletMapping;
|
String url = "http://localhost:" + port1 + contextPath + servletMapping;
|
||||||
|
|
||||||
// Create the session
|
// Create the session
|
||||||
ds.setNextResult(true);
|
|
||||||
ContentResponse response = client.GET(url + "?action=init");
|
ContentResponse response = client.GET(url + "?action=init");
|
||||||
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
|
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
|
||||||
String sessionCookie = response.getHeaders().get("Set-Cookie");
|
String sessionCookie = response.getHeaders().get("Set-Cookie");
|
||||||
|
@ -234,13 +240,10 @@ public class SessionEvictionFailureTest
|
||||||
// Mangle the cookie, replacing Path with $Path, etc.
|
// Mangle the cookie, replacing Path with $Path, etc.
|
||||||
sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
|
sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
|
||||||
|
|
||||||
ds.setNextResult(false);
|
|
||||||
|
|
||||||
//Wait for the eviction period to expire - save on evict should fail but session
|
//Wait for the eviction period to expire - save on evict should fail but session
|
||||||
//should remain in the cache
|
//should remain in the cache
|
||||||
pause(evictionPeriod);
|
pause(evictionPeriod+(int)(evictionPeriod*0.5));
|
||||||
|
|
||||||
ds.setNextResult(true);
|
|
||||||
|
|
||||||
// Make another request to see if the session is still in the cache and can be used,
|
// Make another request to see if the session is still in the cache and can be used,
|
||||||
//allow it to be saved this time
|
//allow it to be saved this time
|
||||||
|
@ -249,12 +252,11 @@ public class SessionEvictionFailureTest
|
||||||
response = request.send();
|
response = request.send();
|
||||||
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
|
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
|
||||||
assertNull(response.getHeaders().get("Set-Cookie")); //check that the cookie wasn't reset
|
assertNull(response.getHeaders().get("Set-Cookie")); //check that the cookie wasn't reset
|
||||||
ds.setNextResult(false);
|
|
||||||
|
|
||||||
//Wait for the eviction period to expire again
|
//Wait for the eviction period to expire again
|
||||||
pause(evictionPeriod);
|
pause(evictionPeriod+(int)(evictionPeriod*0.5));
|
||||||
|
|
||||||
ds.setNextResult(true);
|
|
||||||
|
|
||||||
request = client.newRequest(url + "?action=test");
|
request = client.newRequest(url + "?action=test");
|
||||||
request.header("Cookie", sessionCookie);
|
request.header("Cookie", sessionCookie);
|
||||||
|
|
Loading…
Reference in New Issue