Issue #379 Insufficient information on asyncNotSupported

Converted the boolean for asyncSupported to a String holding the source
of the async not supported.
This commit is contained in:
Greg Wilkins 2016-03-02 14:09:15 +01:00
parent 9c5a8d3f28
commit 3963309f62
4 changed files with 93 additions and 34 deletions

View File

@ -167,7 +167,7 @@ public class Request implements HttpServletRequest
private String _pathInfo;
private boolean _secure;
private boolean _asyncSupported = true;
private String _asyncNotSupportedSource = null;
private boolean _newContext;
private boolean _cookiesExtracted = false;
private boolean _handled = false;
@ -1653,7 +1653,7 @@ public class Request implements HttpServletRequest
@Override
public boolean isAsyncSupported()
{
return _asyncSupported;
return _asyncNotSupportedSource==null;
}
/* ------------------------------------------------------------ */
@ -1828,7 +1828,7 @@ public class Request implements HttpServletRequest
if (_async!=null)
_async.reset();
_async=null;
_asyncSupported = true;
_asyncNotSupportedSource = null;
_handled = false;
if (_attributes != null)
_attributes.clearAttributes();
@ -1898,9 +1898,9 @@ public class Request implements HttpServletRequest
}
/* ------------------------------------------------------------ */
public void setAsyncSupported(boolean supported)
public void setAsyncSupported(boolean supported,String source)
{
_asyncSupported = supported;
_asyncNotSupportedSource = supported?null:(source==null?"unknown":source);
}
/* ------------------------------------------------------------ */
@ -2220,8 +2220,8 @@ public class Request implements HttpServletRequest
@Override
public AsyncContext startAsync() throws IllegalStateException
{
if (!_asyncSupported)
throw new IllegalStateException("!asyncSupported");
if (_asyncNotSupportedSource!=null)
throw new IllegalStateException("!asyncSupported: "+_asyncNotSupportedSource);
HttpChannelState state = getHttpChannelState();
if (_async==null)
_async=new AsyncContextState(state);
@ -2234,8 +2234,8 @@ public class Request implements HttpServletRequest
@Override
public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException
{
if (!_asyncSupported)
throw new IllegalStateException("!asyncSupported");
if (_asyncNotSupportedSource!=null)
throw new IllegalStateException("!asyncSupported: "+_asyncNotSupportedSource);
HttpChannelState state = getHttpChannelState();
if (_async==null)
_async=new AsyncContextState(state);

View File

@ -1660,17 +1660,21 @@ public class ServletHandler extends ScopedHandler
//if the request already does not support async, then the setting for the filter
//is irrelevant. However if the request supports async but this filter does not
//temporarily turn it off for the execution of the filter
boolean requestAsyncSupported = baseRequest.isAsyncSupported();
try
{
if (!_filterHolder.isAsyncSupported() && requestAsyncSupported)
baseRequest.setAsyncSupported(false);
if (baseRequest.isAsyncSupported() && !_filterHolder.isAsyncSupported())
{
try
{
baseRequest.setAsyncSupported(false,_filterHolder.toString());
filter.doFilter(request, response, _next);
}
finally
{
baseRequest.setAsyncSupported(true,null);
}
}
else
filter.doFilter(request, response, _next);
}
finally
{
baseRequest.setAsyncSupported(requestAsyncSupported);
}
return;
}
@ -1733,17 +1737,21 @@ public class ServletHandler extends ScopedHandler
//if the request already does not support async, then the setting for the filter
//is irrelevant. However if the request supports async but this filter does not
//temporarily turn it off for the execution of the filter
boolean requestAsyncSupported = _baseRequest.isAsyncSupported();
try
if (!holder.isAsyncSupported() && _baseRequest.isAsyncSupported())
{
if (!holder.isAsyncSupported() && requestAsyncSupported)
_baseRequest.setAsyncSupported(false);
try
{
_baseRequest.setAsyncSupported(false,holder.toString());
filter.doFilter(request, response, this);
}
finally
{
_baseRequest.setAsyncSupported(true,null);
}
}
else
filter.doFilter(request, response, this);
}
finally
{
_baseRequest.setAsyncSupported(requestAsyncSupported);
}
return;
}

View File

@ -829,10 +829,20 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
if (_identityService!=null)
old_run_as=_identityService.setRunAs(baseRequest.getResolvedUserIdentity(),_runAsToken);
if (!isAsyncSupported())
baseRequest.setAsyncSupported(false);
servlet.service(request,response);
if (baseRequest.isAsyncSupported() && !isAsyncSupported())
{
try
{
baseRequest.setAsyncSupported(false,this.toString());
servlet.service(request,response);
}
finally
{
baseRequest.setAsyncSupported(true,null);
}
}
else
servlet.service(request,response);
servlet_error=false;
}
catch(UnavailableException e)
@ -842,8 +852,6 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
}
finally
{
baseRequest.setAsyncSupported(suspendable);
// pop run-as role
if (_identityService!=null)
_identityService.unsetRunAs(old_run_as);

View File

@ -56,6 +56,7 @@ import org.eclipse.jetty.toolchain.test.AdvancedRunner;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.StdErrLog;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Assert;
@ -63,6 +64,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.eclipse.jetty.util.log.Log.getLogger;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertEquals;
@ -112,6 +114,9 @@ public class AsyncServletTest
_servletHandler.addServletWithMapping(holder,"/path2/*");
_servletHandler.addServletWithMapping(holder,"/p th3/*");
_servletHandler.addServletWithMapping(new ServletHolder(new FwdServlet()),"/fwd/*");
ServletHolder holder2=new ServletHolder("NoAsync",_servlet);
holder2.setAsyncSupported(false);
_servletHandler.addServletWithMapping(holder2,"/noasync/*");
_server.start();
_port=_connector.getLocalPort();
__history.clear();
@ -163,7 +168,45 @@ public class AsyncServletTest
assertContains("NORMAL",response);
}
@Test
public void testAsyncNotSupportedNoAsync() throws Exception
{
_expectedCode="200 ";
String response=process("noasync","",null);
Assert.assertThat(response,Matchers.startsWith("HTTP/1.1 200 OK"));
assertThat(__history,contains(
"REQUEST /ctx/noasync/info",
"initial"
));
assertContains("NORMAL",response);
}
@Test
public void testAsyncNotSupportedAsync() throws Exception
{
((StdErrLog)getLogger(ServletHandler.class)).setHideStacks(true);
try
{
_expectedCode="500 ";
String response=process("noasync","start=200",null);
Assert.assertThat(response,Matchers.startsWith("HTTP/1.1 500 "));
assertThat(__history,contains(
"REQUEST /ctx/noasync/info",
"initial"
));
assertContains("HTTP ERROR: 500",response);
assertContains("!asyncSupported",response);
assertContains("AsyncServletTest$AsyncServlet",response);
}
finally
{
((StdErrLog)getLogger(ServletHandler.class)).setHideStacks(false);
}
}
@Test
public void testStart() throws Exception
{