Improved toString().

This commit is contained in:
Simone Bordet 2015-09-28 19:23:50 +02:00
parent 77fdfb8754
commit fd5c5b5779
5 changed files with 142 additions and 110 deletions

View File

@ -40,7 +40,7 @@ import org.eclipse.jetty.util.thread.NonBlockingThread;
public abstract class AbstractConnection implements Connection
{
private static final Logger LOG = Log.getLogger(AbstractConnection.class);
public static final boolean EXECUTE_ONFILLABLE=true;
private final List<Listener> listeners = new CopyOnWriteArrayList<>();
@ -56,7 +56,7 @@ public abstract class AbstractConnection implements Connection
{
this(endp,executor,EXECUTE_ONFILLABLE);
}
protected AbstractConnection(EndPoint endp, Executor executor, final boolean executeOnfillable)
{
if (executor == null)
@ -88,7 +88,7 @@ public abstract class AbstractConnection implements Connection
{
return _executor;
}
protected void failedCallback(final Callback callback, final Throwable x)
{
if (NonBlockingThread.isNonBlockingThread())
@ -115,7 +115,7 @@ public abstract class AbstractConnection implements Connection
callback.failed(x);
}
}
/**
* <p>Utility method to be called to register read interest.</p>
* <p>After a call to this method, {@link #onFillable()} or {@link #onFillInterestedFailed(Throwable)}
@ -126,7 +126,7 @@ public abstract class AbstractConnection implements Connection
{
if (LOG.isDebugEnabled())
LOG.debug("fillInterested {}",this);
while(true)
{
State state=_state.get();
@ -134,7 +134,7 @@ public abstract class AbstractConnection implements Connection
break;
}
}
public void fillInterested(Callback callback)
{
if (LOG.isDebugEnabled())
@ -151,7 +151,7 @@ public abstract class AbstractConnection implements Connection
break;
}
}
/**
* <p>Callback method invoked when the endpoint is ready to be read.</p>
* @see #fillInterested()
@ -181,7 +181,7 @@ public abstract class AbstractConnection implements Connection
}
if (_endPoint.isOpen())
fillInterested();
fillInterested();
}
/**
@ -258,9 +258,13 @@ public abstract class AbstractConnection implements Connection
@Override
public String toString()
{
return String.format("%s@%x{%s}", getClass().getSimpleName(), hashCode(), _state.get());
return String.format("%s@%x[%s,%s]",
getClass().getSimpleName(),
hashCode(),
_state.get(),
_endPoint);
}
public boolean next(State state, State next)
{
if (next==null)
@ -275,7 +279,7 @@ public abstract class AbstractConnection implements Connection
}
return false;
}
private static final class IdleState extends State
{
private IdleState()
@ -408,11 +412,11 @@ public abstract class AbstractConnection implements Connection
{
return _name;
}
void onEnter(AbstractConnection connection)
{
}
State fillInterested()
{
throw new IllegalStateException(this.toString());
@ -427,28 +431,28 @@ public abstract class AbstractConnection implements Connection
{
throw new IllegalStateException(this.toString());
}
State onFailed()
{
throw new IllegalStateException(this.toString());
}
}
public static final State IDLE=new IdleState();
public static final State FILL_INTERESTED=new FillInterestedState();
public static final State FILLING=new FillingState();
public static final State REFILLING=new RefillingState();
public static final State FILLING_FILL_INTERESTED=new FillingFillInterestedState("FILLING_FILL_INTERESTED");
public class NestedState extends State
{
private final State _nested;
NestedState(State nested)
{
super("NESTED("+nested+")");
@ -471,19 +475,19 @@ public abstract class AbstractConnection implements Connection
{
return new NestedState(_nested.onFillable());
}
@Override
State onFilled()
{
return new NestedState(_nested.onFilled());
}
}
public class FillingInterestedCallback extends NestedState
{
private final Callback _callback;
FillingInterestedCallback(Callback callback,State nested)
{
super("FILLING_INTERESTED_CALLBACK",nested==FILLING?REFILLING:nested);
@ -523,13 +527,13 @@ public abstract class AbstractConnection implements Connection
break;
}
_callback.failed(x);
}
}
};
connection.getEndPoint().fillInterested(callback);
}
}
private final Runnable _runOnFillable = new Runnable()
{
@Override
@ -550,10 +554,10 @@ public abstract class AbstractConnection implements Connection
}
}
};
private class ReadCallback implements Callback
{
{
@Override
public void succeeded()
{
@ -583,7 +587,7 @@ public abstract class AbstractConnection implements Connection
}
});
}
@Override
public String toString()
{

View File

@ -26,6 +26,7 @@ import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import javax.servlet.DispatcherType;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
@ -117,7 +118,7 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable, H
input.init(_state);
_request = new Request(this, input);
_response = new Response(this, new HttpOutput(this));
if (LOG.isDebugEnabled())
LOG.debug("new {} -> {},{},{}",this,_endPoint,_endPoint.getConnection(),_state);
}
@ -168,7 +169,7 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable, H
{
_endPoint.setIdleTimeout(timeoutMs);
}
public ByteBufferPool getByteBufferPool()
{
return _connector.getByteBufferPool();
@ -335,8 +336,8 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable, H
_response.setStatusWithReason(500,reason);
ErrorHandler eh = ErrorHandler.getErrorHandler(getServer(),_state.getContextHandler());
ErrorHandler eh = ErrorHandler.getErrorHandler(getServer(),_state.getContextHandler());
if (eh instanceof ErrorHandler.ErrorPageMapper)
{
String error_page=((ErrorHandler.ErrorPageMapper)eh).getErrorPage((HttpServletRequest)_state.getAsyncContextEvent().getSuppliedRequest());
@ -366,7 +367,7 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable, H
else
_response.getHttpOutput().run();
break;
}
}
default:
break loop;
@ -512,8 +513,7 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable, H
_requests,
_committed.get(),
_state.getState(),
_state.getState()==HttpChannelState.State.IDLE?"-":_request.getRequestURI()
);
_uri);
}
@Override
@ -524,7 +524,7 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable, H
_request.setServerPort(dPort);
_request.setRemoteAddr(InetSocketAddress.createUnresolved(sAddr,sPort));
}
@Override
public boolean startRequest(HttpMethod httpMethod, String method, ByteBuffer uri, HttpVersion version)
{
@ -552,7 +552,7 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable, H
LOG.ignore(e);
path = _uri.getDecodedPath(StandardCharsets.ISO_8859_1);
}
String info = URIUtil.canonicalPath(path);
if (info == null)
@ -741,7 +741,7 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable, H
{
if (_state.unhandle()==Action.COMPLETE)
_state.completed();
else
else
throw new IllegalStateException();
}
}

View File

@ -67,8 +67,8 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
/* ------------------------------------------------------------ */
/** Get the current connection that this thread is dispatched to.
* Note that a thread may be processing a request asynchronously and
* thus not be dispatched to the connection.
* Note that a thread may be processing a request asynchronously and
* thus not be dispatched to the connection.
* @see Request#getAttribute(String) for a more general way to access the HttpConnection
* @return the current HttpConnection or null
*/
@ -110,17 +110,17 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
{
return new HttpGenerator(_config.getSendServerVersion(),_config.getSendXPoweredBy());
}
protected HttpInput<ByteBuffer> newHttpInput()
{
return new HttpInputOverHTTP(this);
}
protected HttpChannelOverHttp newHttpChannel(HttpInput<ByteBuffer> httpInput)
{
return new HttpChannelOverHttp(_connector, _config, getEndPoint(), this, httpInput);
}
protected HttpParser newHttpParser()
{
return new HttpParser(newRequestHandler(), getHttpConfiguration().getRequestHeaderSize());
@ -184,7 +184,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
_bufferPool.release(buffer);
}
}
public ByteBuffer getRequestBuffer()
{
if (_requestBuffer == null)
@ -217,10 +217,10 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
// Do we need some data to parse
if (BufferUtil.isEmpty(_requestBuffer))
{
// If the previous iteration filled 0 bytes or saw a close, then break here
// If the previous iteration filled 0 bytes or saw a close, then break here
if (filled<=0)
break;
// Can we fill?
if(getEndPoint().isInputShutdown())
{
@ -239,13 +239,13 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
filled = getEndPoint().fill(_requestBuffer);
if (filled==0) // Do a retry on fill 0 (optimization for SSL connections)
filled = getEndPoint().fill(_requestBuffer);
// tell parser
if (filled < 0)
_parser.atEOF();
}
}
// Parse the buffer
if (_parser.parseNext(_requestBuffer==null?BufferUtil.EMPTY_BUFFER:_requestBuffer))
{
@ -278,7 +278,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
close();
}
finally
{
{
setCurrentConnection(last);
if (!suspended && getEndPoint().isOpen() && getEndPoint().getConnection()==this)
{
@ -295,7 +295,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
{
// Not in a race here for the request buffer with #onFillable because an async consumer of
// content would only be started after onFillable has given up control.
// In a little bit of a race with #completed, but then not sure if it is legal to be doing
// In a little bit of a race with #completed, but then not sure if it is legal to be doing
// async calls to IO and have a completed call at the same time.
ByteBuffer requestBuffer = getRequestBuffer();
@ -315,7 +315,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
if (parsed)
break;
// OK lets read some data
int filled=getEndPoint().fill(requestBuffer);
if (LOG.isDebugEnabled()) // Avoid boxing of variable 'filled'
@ -331,7 +331,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
}
}
}
@Override
public void completed()
{
@ -350,7 +350,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
return;
}
}
// Finish consuming the request
// If we are still expecting
if (_channel.isExpecting100Continue())
@ -383,7 +383,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
_parser.reset();
else
_parser.close();
// Not in a race here with onFillable, because it has given up control before calling handle.
// in a slight race with #completed, but not sure what to do with that anyway.
releaseRequestBuffer();
@ -426,7 +426,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
getEndPoint().close();
}
}
// else the parser must be closed, so seek the EOF if we are still open
// else the parser must be closed, so seek the EOF if we are still open
else if (getEndPoint().isOpen())
fillInterested();
}
@ -466,7 +466,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
if (info!=null && _channel.isExpecting100Continue())
// then we can't be persistent
_generator.setPersistent(false);
if(_sendCallback.reset(info,content,lastContent,callback))
_sendCallback.iterate();
}
@ -479,14 +479,32 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
else if (_sendCallback.reset(null,content,lastContent,callback))
_sendCallback.iterate();
}
@Override
public void abort()
{
// Do a direct close of the output, as this may indicate to a client that the
// response is bad either with RST or by abnormal completion of chunked response.
getEndPoint().close();
}
@Override
public String toString()
{
return String.format("%s[p=%s,g=%s,c=%s]",
super.toString(),
_parser,
_generator,
_channel);
}
protected class HttpChannelOverHttp extends HttpChannel<ByteBuffer>
{
{
public HttpChannelOverHttp(Connector connector, HttpConfiguration config, EndPoint endPoint, HttpTransport transport, HttpInput<ByteBuffer> input)
{
super(connector,config,endPoint,transport,input);
}
@Override
public void earlyEOF()
{
@ -559,7 +577,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
if (!super.headerComplete())
return false;
// Should we delay dispatch until we have some content?
// We should not delay if there is no content expect or client is expecting 100 or the response is already committed or the request buffer already has something in it to parse
if (getHttpConfiguration().isDelayDispatchUntilContent() && _parser.getContentLength() > 0 &&
@ -617,7 +635,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
_shutdownOut = false;
return true;
}
if (isClosed())
callback.failed(new EofException());
else
@ -630,7 +648,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
{
if (_callback==null)
throw new IllegalStateException();
ByteBuffer chunk = _chunk;
while (true)
{
@ -648,7 +666,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
{
case NEED_HEADER:
{
_header = _bufferPool.acquire(_config.getResponseHeaderSize(), HEADER_BUFFER_DIRECT);
_header = _bufferPool.acquire(_config.getResponseHeaderSize(), HEADER_BUFFER_DIRECT);
continue;
}
case NEED_CHUNK:
@ -723,7 +741,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
if (h!=null)
_bufferPool.release(h);
}
@Override
protected void onCompleteSuccess()
{
@ -741,21 +759,11 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
if (_shutdownOut)
getEndPoint().shutdownOutput();
}
@Override
public String toString()
{
return String.format("%s[i=%s,cb=%s]",super.toString(),_info,_callback);
}
}
@Override
public void abort()
{
// Do a direct close of the output, as this may indicate to a client that the
// response is bad either with RST or by abnormal completion of chunked response.
getEndPoint().close();
}
}

View File

@ -20,6 +20,7 @@ package org.eclipse.jetty.server;
import java.io.IOException;
import java.util.Objects;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
@ -256,7 +257,7 @@ public abstract class HttpInput<T> extends ServletInputStream implements Runnabl
return _contentState==EARLY_EOF;
}
}
/**
* This method should be called to signal that all the expected
* content arrived.
@ -312,7 +313,7 @@ public abstract class HttpInput<T> extends ServletInputStream implements Runnabl
return _contentState==ASYNC;
}
}
/**
* @return whether an EOF has been detected, even though there may be content to consume.
*/
@ -332,7 +333,7 @@ public abstract class HttpInput<T> extends ServletInputStream implements Runnabl
return _contentState.isEOF();
}
}
@Override
public boolean isReady()
@ -376,9 +377,9 @@ public abstract class HttpInput<T> extends ServletInputStream implements Runnabl
_contentState = ASYNC;
_listener = readListener;
_notReady = true;
content = getNextContent()!=null || isEOF();
}
if (content)
_channelState.onReadPossible();
@ -451,6 +452,18 @@ public abstract class HttpInput<T> extends ServletInputStream implements Runnabl
}
}
@Override
public String toString()
{
return String.format("%s@%x[r=%d,s=%s,e=%s,f=%s]",
getClass().getSimpleName(),
hashCode(),
_contentRead,
_contentState,
_eofState,
_onError);
}
protected static abstract class State
{
public void waitForContent(HttpInput<?> in) throws IOException

View File

@ -40,6 +40,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.servlet.AsyncContext;
import javax.servlet.AsyncListener;
import javax.servlet.DispatcherType;
@ -130,7 +131,7 @@ public class Request implements HttpServletRequest
private final HttpFields _fields=new HttpFields();
private final List<ServletRequestAttributeListener> _requestAttributeListeners=new ArrayList<>();
private final HttpInput<?> _input;
public static class MultiPartCleanerListener implements ServletRequestListener
{
@Override
@ -162,10 +163,10 @@ public class Request implements HttpServletRequest
{
//nothing to do, multipart config set up by ServletHolder.handle()
}
}
private boolean _secure;
private boolean _asyncSupported = true;
@ -208,7 +209,7 @@ public class Request implements HttpServletRequest
private HttpURI _uri;
private MultiPartInputStreamParser _multiPartInputStream; //if the request is a multi-part mime
private AsyncContextState _async;
/* ------------------------------------------------------------ */
public Request(HttpChannel<?> channel, HttpInput<?> input)
{
@ -398,7 +399,7 @@ public class Request implements HttpServletRequest
HttpChannelState state = getHttpChannelState();
if (_async==null || !state.isAsyncStarted())
throw new IllegalStateException(state.getStatusString());
return _async;
}
@ -531,7 +532,7 @@ public class Request implements HttpServletRequest
{
return _input.getContentRead();
}
/* ------------------------------------------------------------ */
/*
* @see javax.servlet.ServletRequest#getContentType()
@ -572,7 +573,7 @@ public class Request implements HttpServletRequest
{
if (_cookies == null || _cookies.getCookies().length == 0)
return null;
return _cookies.getCookies();
}
@ -596,7 +597,7 @@ public class Request implements HttpServletRequest
//Javadoc for Request.getCookies() stipulates null for no cookies
if (_cookies == null || _cookies.getCookies().length == 0)
return null;
return _cookies.getCookies();
}
@ -1016,7 +1017,7 @@ public class Request implements HttpServletRequest
/* ------------------------------------------------------------ */
/**
* Access the underlying Remote {@link InetSocketAddress} for this request.
*
*
* @return the remote {@link InetSocketAddress} for this request, or null if the request has no remote (see {@link ServletRequest#getRemoteAddr()} for
* conditions that result in no remote address)
*/
@ -1039,14 +1040,14 @@ public class Request implements HttpServletRequest
InetSocketAddress remote=_remote;
if (remote==null)
remote=_channel.getRemoteAddress();
if (remote==null)
return "";
InetAddress address = remote.getAddress();
if (address==null)
return remote.getHostString();
return address.getHostAddress();
}
@ -1207,7 +1208,7 @@ public class Request implements HttpServletRequest
// Return host from header field
String hostPort = _fields.getStringField(HttpHeader.HOST);
_port=0;
if (hostPort != null)
{
@ -1238,7 +1239,7 @@ public class Request implements HttpServletRequest
}
if (hostPort.charAt(0)=='[')
{
if (hostPort.charAt(len-1)!=']')
if (hostPort.charAt(len-1)!=']')
{
LOG.warn("Bad IPv6 "+hostPort);
_serverName=hostPort;
@ -1394,7 +1395,7 @@ public class Request implements HttpServletRequest
if (!create)
return null;
if (getResponse().isCommitted())
throw new IllegalStateException("Response is committed");
@ -1482,7 +1483,7 @@ public class Request implements HttpServletRequest
UserIdentity user = ((Authentication.User)_authentication).getUserIdentity();
return user.getUserPrincipal();
}
return null;
}
@ -1595,7 +1596,7 @@ public class Request implements HttpServletRequest
{
if (_context != null)
throw new IllegalStateException("Request in context!");
if (_inputState == __READER)
{
try
@ -1718,7 +1719,7 @@ public class Request implements HttpServletRequest
setQueryEncoding(value == null?null:value.toString());
else if ("org.eclipse.jetty.server.sendContent".equals(name))
LOG.warn("Deprecated: org.eclipse.jetty.server.sendContent");
if (_attributes == null)
_attributes = new AttributesMap();
_attributes.setAttribute(name,value);
@ -1937,7 +1938,7 @@ public class Request implements HttpServletRequest
{
_remote = addr;
}
/* ------------------------------------------------------------ */
/**
* @param requestedSessionId
@ -2084,7 +2085,13 @@ public class Request implements HttpServletRequest
@Override
public String toString()
{
return (_handled?"[":"(") + getMethod() + " " + _uri + (_handled?"]@":")@") + hashCode() + " " + super.toString();
return String.format("%s%s%s %s%s@%x",
getClass().getSimpleName(),
_handled ? "[" : "(",
getMethod(),
_uri,
_handled ? "]" : ")",
hashCode());
}
/* ------------------------------------------------------------ */
@ -2126,14 +2133,14 @@ public class Request implements HttpServletRequest
if (_multiPartInputStream == null)
{
MultipartConfigElement config = (MultipartConfigElement)getAttribute(__MULTIPART_CONFIG_ELEMENT);
if (config == null)
throw new IllegalStateException("No multipart config for servlet");
_multiPartInputStream = new MultiPartInputStreamParser(getInputStream(),
getContentType(), config,
getContentType(), config,
(_context != null?(File)_context.getAttribute("javax.servlet.context.tempdir"):null));
setAttribute(__MULTIPART_INPUT_STREAM, _multiPartInputStream);
setAttribute(__MULTIPART_CONTEXT, _context);
Collection<Part> parts = _multiPartInputStream.getParts(); //causes parsing
@ -2245,9 +2252,9 @@ public class Request implements HttpServletRequest
{
//Instantiate an instance and inject it
T h = getContext().createInstance(handlerClass);
//TODO handle the rest of the upgrade process
return h;
}
catch (Exception e)