jetty-9 refactored stats
This commit is contained in:
parent
a7154fcb05
commit
775376ac98
|
@ -1,212 +0,0 @@
|
||||||
package org.eclipse.jetty.io;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.locks.Condition;
|
|
||||||
import java.util.concurrent.locks.Lock;
|
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.util.Callback;
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/** Dispatched IOFuture.
|
|
||||||
* <p>An implementation of IOFuture that can be extended to implement the
|
|
||||||
* {@link #dispatch(Runnable)} method so that callbacks can be dispatched.
|
|
||||||
* By default, the callbacks are called by the thread that called {@link #complete()} or
|
|
||||||
* {@link #fail(Throwable)}
|
|
||||||
*/
|
|
||||||
public class DispatchingIOFuture implements IOFuture
|
|
||||||
{
|
|
||||||
private final Object _lock;
|
|
||||||
private boolean _done;
|
|
||||||
private boolean _complete;
|
|
||||||
private Throwable _cause;
|
|
||||||
private Callback<?> _callback;
|
|
||||||
private Object _context;
|
|
||||||
|
|
||||||
public DispatchingIOFuture()
|
|
||||||
{
|
|
||||||
this(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DispatchingIOFuture(Object lock)
|
|
||||||
{
|
|
||||||
this(false, lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DispatchingIOFuture(boolean ready,Object lock)
|
|
||||||
{
|
|
||||||
_complete=ready;
|
|
||||||
_done=ready;
|
|
||||||
_lock = lock==null?this:lock;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fail(final Throwable cause)
|
|
||||||
{
|
|
||||||
synchronized(_lock)
|
|
||||||
{
|
|
||||||
if (_done)
|
|
||||||
throw new IllegalStateException("complete",cause);
|
|
||||||
|
|
||||||
_cause=cause;
|
|
||||||
_done=true;
|
|
||||||
|
|
||||||
if (_callback!=null)
|
|
||||||
dispatchFailed();
|
|
||||||
_lock.notifyAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void complete()
|
|
||||||
{
|
|
||||||
synchronized(_lock)
|
|
||||||
{
|
|
||||||
if (_done)
|
|
||||||
throw new IllegalStateException();
|
|
||||||
_complete=true;
|
|
||||||
_done=true;
|
|
||||||
|
|
||||||
if (_callback!=null)
|
|
||||||
dispatchCompleted();
|
|
||||||
_lock.notifyAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void cancelled()
|
|
||||||
{
|
|
||||||
synchronized(_lock)
|
|
||||||
{
|
|
||||||
if (_done)
|
|
||||||
throw new IllegalStateException();
|
|
||||||
_complete=false;
|
|
||||||
_done=true;
|
|
||||||
_lock.notifyAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDone()
|
|
||||||
{
|
|
||||||
synchronized(_lock)
|
|
||||||
{
|
|
||||||
return _done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isComplete() throws ExecutionException
|
|
||||||
{
|
|
||||||
synchronized(_lock)
|
|
||||||
{
|
|
||||||
if (_done)
|
|
||||||
{
|
|
||||||
if (_complete)
|
|
||||||
return true;
|
|
||||||
throw new ExecutionException(_cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cancel() throws UnsupportedOperationException
|
|
||||||
{
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void block() throws InterruptedException, ExecutionException
|
|
||||||
{
|
|
||||||
synchronized(_lock)
|
|
||||||
{
|
|
||||||
while (!_done)
|
|
||||||
_lock.wait();
|
|
||||||
isComplete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean block(long timeout, TimeUnit units) throws InterruptedException, ExecutionException
|
|
||||||
{
|
|
||||||
synchronized(_lock)
|
|
||||||
{
|
|
||||||
if (!_done)
|
|
||||||
_lock.wait(units.toMillis(timeout));
|
|
||||||
return isComplete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <C> void setCallback(Callback<C> callback, C context)
|
|
||||||
{
|
|
||||||
synchronized(_lock)
|
|
||||||
{
|
|
||||||
if (_callback!=null)
|
|
||||||
throw new IllegalStateException();
|
|
||||||
_callback=callback;
|
|
||||||
_context=context;
|
|
||||||
|
|
||||||
if (_done)
|
|
||||||
{
|
|
||||||
if (_complete)
|
|
||||||
dispatchCompleted();
|
|
||||||
else
|
|
||||||
dispatchFailed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void dispatch(Runnable callback)
|
|
||||||
{
|
|
||||||
new Thread(callback).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void dispatchCompleted()
|
|
||||||
{
|
|
||||||
final Callback callback=_callback;
|
|
||||||
final Object context=_context;
|
|
||||||
dispatch(new Runnable()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
callback.completed(context);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void dispatchFailed()
|
|
||||||
{
|
|
||||||
final Callback callback=_callback;
|
|
||||||
final Throwable cause=_cause;
|
|
||||||
final Object context=_context;
|
|
||||||
dispatch(new Runnable()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
callback.failed(context, cause);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
return String.format("DIOF@%x{%s,%s}",
|
|
||||||
hashCode(),
|
|
||||||
_done?(_complete?"R":_cause):"-",
|
|
||||||
_callback==null?"-":_callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void rethrow(ExecutionException e) throws IOException
|
|
||||||
{
|
|
||||||
if (e.getCause() instanceof IOException)
|
|
||||||
throw (IOException)e.getCause();
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,93 +0,0 @@
|
||||||
package org.eclipse.jetty.io;
|
|
||||||
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.util.Callback;
|
|
||||||
|
|
||||||
public class DoneIOFuture implements IOFuture
|
|
||||||
{
|
|
||||||
private final boolean _ready;
|
|
||||||
private final Throwable _cause;
|
|
||||||
|
|
||||||
public final static DoneIOFuture COMPLETE=new DoneIOFuture();
|
|
||||||
|
|
||||||
public DoneIOFuture()
|
|
||||||
{
|
|
||||||
this(true,null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DoneIOFuture(Throwable cause)
|
|
||||||
{
|
|
||||||
this(false,cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
private DoneIOFuture(boolean ready, Throwable cause)
|
|
||||||
{
|
|
||||||
_ready=ready;
|
|
||||||
_cause=cause;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isComplete() throws ExecutionException
|
|
||||||
{
|
|
||||||
if (_ready)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
throw new ExecutionException(_cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cancel() throws UnsupportedOperationException
|
|
||||||
{
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void block() throws ExecutionException
|
|
||||||
{
|
|
||||||
isComplete();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean block(long timeout, TimeUnit units) throws ExecutionException
|
|
||||||
{
|
|
||||||
return isComplete();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <C> void setCallback(final Callback<C> callback, final C context)
|
|
||||||
{
|
|
||||||
dispatch(new Runnable()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
if (_ready)
|
|
||||||
callback.completed(context);
|
|
||||||
else
|
|
||||||
callback.failed(context, _cause);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void dispatch(Runnable callback)
|
|
||||||
{
|
|
||||||
callback.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDone()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
return String.format("%s@%x{%s}",
|
|
||||||
getClass().getSimpleName(),
|
|
||||||
hashCode(),
|
|
||||||
_ready?"R":_cause);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,73 +0,0 @@
|
||||||
package org.eclipse.jetty.io;
|
|
||||||
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.util.Callback;
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/** Async IO Future interface.
|
|
||||||
* <p>
|
|
||||||
* This interface make the future status of an IO operation available via
|
|
||||||
* polling ({@link #isComplete()}, blocking ({@link #block()} or callback ({@link #setCallback(Callback, Object)}
|
|
||||||
* <p>
|
|
||||||
* This interface does not directly support a timeout for blocking. If an IO operation times out, then
|
|
||||||
* this will be indicated via this interface by an {@link ExecutionException} containing a
|
|
||||||
* {@link TimeoutException} (or similar).
|
|
||||||
*/
|
|
||||||
public interface IOFuture
|
|
||||||
{
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/** Indicate if this Future is complete.
|
|
||||||
* If this future has completed by becoming ready, excepting or timeout.
|
|
||||||
* @return True if this future has completed by becoming ready or excepting.
|
|
||||||
*/
|
|
||||||
boolean isDone();
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/** Indicate the readyness of the IO system.
|
|
||||||
* For input, ready means that there is data
|
|
||||||
* ready to be consumed. For output ready means that the prior operation
|
|
||||||
* has completed and another may be initiated.
|
|
||||||
* @return True if the IO operation is ready.
|
|
||||||
* @throws ExecutionException If an exception occurs during the IO operation
|
|
||||||
*/
|
|
||||||
boolean isComplete() throws ExecutionException;
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/** Cancel the IO operation.
|
|
||||||
* @throws UnsupportedOperationException If the operation cannot be cancelled.
|
|
||||||
*/
|
|
||||||
void cancel() throws UnsupportedOperationException;
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/** Block until complete.
|
|
||||||
* <p>This call blocks the calling thread until this AsyncIO is ready or
|
|
||||||
* an exception.
|
|
||||||
* @throws InterruptedException if interrupted while blocking
|
|
||||||
* @throws ExecutionException If any exception occurs during the IO operation
|
|
||||||
*/
|
|
||||||
void block() throws InterruptedException, ExecutionException;
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/** Block until complete or timeout
|
|
||||||
* <p>This call blocks the calling thread until this AsyncIO is ready or
|
|
||||||
* an exception or a timeout. In the case of the timeout, the IO operation is not affected
|
|
||||||
* and can still continue to completion and this IOFuture is still usable.
|
|
||||||
* @return true if the IOFuture completed or false if it timedout.
|
|
||||||
* @throws InterruptedException if interrupted while blocking
|
|
||||||
* @throws ExecutionException If any exception occurs during the IO operation
|
|
||||||
*/
|
|
||||||
boolean block(long timeout, TimeUnit units) throws InterruptedException, ExecutionException;
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/** Set an IOCallback.
|
|
||||||
* Set an {@link Callback} instance to be called when the IO operation is ready or if
|
|
||||||
* there is a failure or timeout.
|
|
||||||
* @param callback
|
|
||||||
*/
|
|
||||||
<C> void setCallback(Callback<C> callback, C context);
|
|
||||||
}
|
|
|
@ -0,0 +1,460 @@
|
||||||
|
package org.eclipse.jetty.server;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.http.HttpFields;
|
||||||
|
import org.eclipse.jetty.http.HttpHeader;
|
||||||
|
import org.eclipse.jetty.http.HttpScheme;
|
||||||
|
import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
|
|
||||||
|
|
||||||
|
public abstract class AbstractHttpConnector extends AbstractConnector implements HttpConnector
|
||||||
|
{
|
||||||
|
private String _integralScheme = HttpScheme.HTTPS.toString();
|
||||||
|
private int _integralPort = 0;
|
||||||
|
private String _confidentialScheme = HttpScheme.HTTPS.toString();
|
||||||
|
private int _confidentialPort = 0;
|
||||||
|
private boolean _forwarded;
|
||||||
|
private String _hostHeader;
|
||||||
|
|
||||||
|
private String _forwardedHostHeader = HttpHeader.X_FORWARDED_HOST.toString();
|
||||||
|
private String _forwardedServerHeader = HttpHeader.X_FORWARDED_SERVER.toString();
|
||||||
|
private String _forwardedForHeader = HttpHeader.X_FORWARDED_FOR.toString();
|
||||||
|
private String _forwardedProtoHeader = HttpHeader.X_FORWARDED_PROTO.toString();
|
||||||
|
private String _forwardedCipherSuiteHeader;
|
||||||
|
private String _forwardedSslSessionIdHeader;
|
||||||
|
|
||||||
|
private int _requestHeaderSize;
|
||||||
|
private int _requestBufferSize;
|
||||||
|
private int _responseHeaderSize;
|
||||||
|
private int _responseBufferSize;
|
||||||
|
|
||||||
|
private ByteBufferPool _byteBufferPool;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRequestHeaderSize()
|
||||||
|
{
|
||||||
|
return _requestHeaderSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequestHeaderSize(int requestHeaderSize)
|
||||||
|
{
|
||||||
|
_requestHeaderSize = requestHeaderSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRequestBufferSize()
|
||||||
|
{
|
||||||
|
return _requestBufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequestBufferSize(int requestBufferSize)
|
||||||
|
{
|
||||||
|
_requestBufferSize = requestBufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getResponseHeaderSize()
|
||||||
|
{
|
||||||
|
return _responseHeaderSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResponseHeaderSize(int responseHeaderSize)
|
||||||
|
{
|
||||||
|
_responseHeaderSize = responseHeaderSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getResponseBufferSize()
|
||||||
|
{
|
||||||
|
return _responseBufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResponseBufferSize(int responseBufferSize)
|
||||||
|
{
|
||||||
|
_responseBufferSize = responseBufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBufferPool getByteBufferPool()
|
||||||
|
{
|
||||||
|
return _byteBufferPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setByteBufferPool(ByteBufferPool byteBufferPool)
|
||||||
|
{
|
||||||
|
_byteBufferPool = byteBufferPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
|
public void customize(Request request) throws IOException
|
||||||
|
{
|
||||||
|
if (isForwarded())
|
||||||
|
checkForwardedHeaders(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected void checkForwardedHeaders(Request request) throws IOException
|
||||||
|
{
|
||||||
|
HttpFields httpFields = request.getConnection().getRequestFields();
|
||||||
|
|
||||||
|
// Do SSL first
|
||||||
|
if (getForwardedCipherSuiteHeader()!=null)
|
||||||
|
{
|
||||||
|
String cipher_suite=httpFields.getStringField(getForwardedCipherSuiteHeader());
|
||||||
|
if (cipher_suite!=null)
|
||||||
|
request.setAttribute("javax.servlet.request.cipher_suite",cipher_suite);
|
||||||
|
}
|
||||||
|
if (getForwardedSslSessionIdHeader()!=null)
|
||||||
|
{
|
||||||
|
String ssl_session_id=httpFields.getStringField(getForwardedSslSessionIdHeader());
|
||||||
|
if(ssl_session_id!=null)
|
||||||
|
{
|
||||||
|
request.setAttribute("javax.servlet.request.ssl_session_id", ssl_session_id);
|
||||||
|
request.setScheme(HttpScheme.HTTPS.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieving headers from the request
|
||||||
|
String forwardedHost = getLeftMostFieldValue(httpFields,getForwardedHostHeader());
|
||||||
|
String forwardedServer = getLeftMostFieldValue(httpFields,getForwardedServerHeader());
|
||||||
|
String forwardedFor = getLeftMostFieldValue(httpFields,getForwardedForHeader());
|
||||||
|
String forwardedProto = getLeftMostFieldValue(httpFields,getForwardedProtoHeader());
|
||||||
|
|
||||||
|
if (_hostHeader != null)
|
||||||
|
{
|
||||||
|
// Update host header
|
||||||
|
httpFields.put(HttpHeader.HOST.toString(),_hostHeader);
|
||||||
|
request.setServerName(null);
|
||||||
|
request.setServerPort(-1);
|
||||||
|
request.getServerName();
|
||||||
|
}
|
||||||
|
else if (forwardedHost != null)
|
||||||
|
{
|
||||||
|
// Update host header
|
||||||
|
httpFields.put(HttpHeader.HOST.toString(),forwardedHost);
|
||||||
|
request.setServerName(null);
|
||||||
|
request.setServerPort(-1);
|
||||||
|
request.getServerName();
|
||||||
|
}
|
||||||
|
else if (forwardedServer != null)
|
||||||
|
{
|
||||||
|
// Use provided server name
|
||||||
|
request.setServerName(forwardedServer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (forwardedFor != null)
|
||||||
|
{
|
||||||
|
request.setRemoteAddr(new InetSocketAddress(forwardedFor,request.getRemotePort()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (forwardedProto != null)
|
||||||
|
{
|
||||||
|
request.setScheme(forwardedProto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected String getLeftMostFieldValue(HttpFields fields, String header)
|
||||||
|
{
|
||||||
|
if (header == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
String headerValue = fields.getStringField(header);
|
||||||
|
|
||||||
|
if (headerValue == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
int commaIndex = headerValue.indexOf(',');
|
||||||
|
|
||||||
|
if (commaIndex == -1)
|
||||||
|
{
|
||||||
|
// Single value
|
||||||
|
return headerValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The left-most value is the farthest downstream client
|
||||||
|
return headerValue.substring(0,commaIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jetty.server.Connector#getConfidentialPort()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getConfidentialPort()
|
||||||
|
{
|
||||||
|
return _confidentialPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jetty.server.Connector#getConfidentialScheme()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getConfidentialScheme()
|
||||||
|
{
|
||||||
|
return _confidentialScheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jetty.server.Connector#isConfidential(org.eclipse.jetty.server .Request)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isIntegral(Request request)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jetty.server.Connector#getConfidentialPort()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getIntegralPort()
|
||||||
|
{
|
||||||
|
return _integralPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jetty.server.Connector#getIntegralScheme()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getIntegralScheme()
|
||||||
|
{
|
||||||
|
return _integralScheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jetty.server.Connector#isConfidential(org.eclipse.jetty.server.Request)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isConfidential(Request request)
|
||||||
|
{
|
||||||
|
return _forwarded && request.getScheme().equalsIgnoreCase(HttpScheme.HTTPS.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @param confidentialPort
|
||||||
|
* The confidentialPort to set.
|
||||||
|
*/
|
||||||
|
public void setConfidentialPort(int confidentialPort)
|
||||||
|
{
|
||||||
|
_confidentialPort = confidentialPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @param confidentialScheme
|
||||||
|
* The confidentialScheme to set.
|
||||||
|
*/
|
||||||
|
public void setConfidentialScheme(String confidentialScheme)
|
||||||
|
{
|
||||||
|
_confidentialScheme = confidentialScheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @param integralPort
|
||||||
|
* The integralPort to set.
|
||||||
|
*/
|
||||||
|
public void setIntegralPort(int integralPort)
|
||||||
|
{
|
||||||
|
_integralPort = integralPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @param integralScheme
|
||||||
|
* The integralScheme to set.
|
||||||
|
*/
|
||||||
|
public void setIntegralScheme(String integralScheme)
|
||||||
|
{
|
||||||
|
_integralScheme = integralScheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* Is reverse proxy handling on?
|
||||||
|
*
|
||||||
|
* @return true if this connector is checking the x-forwarded-for/host/server headers
|
||||||
|
*/
|
||||||
|
public boolean isForwarded()
|
||||||
|
{
|
||||||
|
return _forwarded;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* Set reverse proxy handling. If set to true, then the X-Forwarded headers (or the headers set in their place) are looked for to set the request protocol,
|
||||||
|
* host, server and client ip.
|
||||||
|
*
|
||||||
|
* @param check
|
||||||
|
* true if this connector is checking the x-forwarded-for/host/server headers
|
||||||
|
* @set {@link #setForwardedForHeader(String)}
|
||||||
|
* @set {@link #setForwardedHostHeader(String)}
|
||||||
|
* @set {@link #setForwardedProtoHeader(String)}
|
||||||
|
* @set {@link #setForwardedServerHeader(String)}
|
||||||
|
*/
|
||||||
|
public void setForwarded(boolean check)
|
||||||
|
{
|
||||||
|
if (check)
|
||||||
|
LOG.debug("{} is forwarded",this);
|
||||||
|
_forwarded = check;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public String getHostHeader()
|
||||||
|
{
|
||||||
|
return _hostHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* Set a forced valued for the host header to control what is returned by {@link ServletRequest#getServerName()} and {@link ServletRequest#getServerPort()}.
|
||||||
|
* This value is only used if {@link #isForwarded()} is true.
|
||||||
|
*
|
||||||
|
* @param hostHeader
|
||||||
|
* The value of the host header to force.
|
||||||
|
*/
|
||||||
|
public void setHostHeader(String hostHeader)
|
||||||
|
{
|
||||||
|
_hostHeader = hostHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* @see #setForwarded(boolean)
|
||||||
|
*/
|
||||||
|
public String getForwardedHostHeader()
|
||||||
|
{
|
||||||
|
return _forwardedHostHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @param forwardedHostHeader
|
||||||
|
* The header name for forwarded hosts (default x-forwarded-host)
|
||||||
|
* @see #setForwarded(boolean)
|
||||||
|
*/
|
||||||
|
public void setForwardedHostHeader(String forwardedHostHeader)
|
||||||
|
{
|
||||||
|
_forwardedHostHeader = forwardedHostHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @return the header name for forwarded server.
|
||||||
|
* @see #setForwarded(boolean)
|
||||||
|
*/
|
||||||
|
public String getForwardedServerHeader()
|
||||||
|
{
|
||||||
|
return _forwardedServerHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @param forwardedServerHeader
|
||||||
|
* The header name for forwarded server (default x-forwarded-server)
|
||||||
|
* @see #setForwarded(boolean)
|
||||||
|
*/
|
||||||
|
public void setForwardedServerHeader(String forwardedServerHeader)
|
||||||
|
{
|
||||||
|
_forwardedServerHeader = forwardedServerHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @see #setForwarded(boolean)
|
||||||
|
*/
|
||||||
|
public String getForwardedForHeader()
|
||||||
|
{
|
||||||
|
return _forwardedForHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @param forwardedRemoteAddressHeader
|
||||||
|
* The header name for forwarded for (default x-forwarded-for)
|
||||||
|
* @see #setForwarded(boolean)
|
||||||
|
*/
|
||||||
|
public void setForwardedForHeader(String forwardedRemoteAddressHeader)
|
||||||
|
{
|
||||||
|
_forwardedForHeader = forwardedRemoteAddressHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* Get the forwardedProtoHeader.
|
||||||
|
*
|
||||||
|
* @return the forwardedProtoHeader (default X-Forwarded-For)
|
||||||
|
* @see #setForwarded(boolean)
|
||||||
|
*/
|
||||||
|
public String getForwardedProtoHeader()
|
||||||
|
{
|
||||||
|
return _forwardedProtoHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* Set the forwardedProtoHeader.
|
||||||
|
*
|
||||||
|
* @param forwardedProtoHeader
|
||||||
|
* the forwardedProtoHeader to set (default X-Forwarded-For)
|
||||||
|
* @see #setForwarded(boolean)
|
||||||
|
*/
|
||||||
|
public void setForwardedProtoHeader(String forwardedProtoHeader)
|
||||||
|
{
|
||||||
|
_forwardedProtoHeader = forwardedProtoHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @return The header name holding a forwarded cipher suite (default null)
|
||||||
|
*/
|
||||||
|
public String getForwardedCipherSuiteHeader()
|
||||||
|
{
|
||||||
|
return _forwardedCipherSuiteHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @param forwardedCipherSuite
|
||||||
|
* The header name holding a forwarded cipher suite (default null)
|
||||||
|
*/
|
||||||
|
public void setForwardedCipherSuiteHeader(String forwardedCipherSuite)
|
||||||
|
{
|
||||||
|
_forwardedCipherSuiteHeader = forwardedCipherSuite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @return The header name holding a forwarded SSL Session ID (default null)
|
||||||
|
*/
|
||||||
|
public String getForwardedSslSessionIdHeader()
|
||||||
|
{
|
||||||
|
return _forwardedSslSessionIdHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @param forwardedSslSessionId
|
||||||
|
* The header name holding a forwarded SSL Session ID (default null)
|
||||||
|
*/
|
||||||
|
public void setForwardedSslSessionIdHeader(String forwardedSslSessionId)
|
||||||
|
{
|
||||||
|
_forwardedSslSessionIdHeader = forwardedSslSessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,228 @@
|
||||||
|
package org.eclipse.jetty.server;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.server.Connector.Statistics;
|
||||||
|
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||||
|
import org.eclipse.jetty.util.statistic.CounterStatistic;
|
||||||
|
import org.eclipse.jetty.util.statistic.SampleStatistic;
|
||||||
|
|
||||||
|
class ConnectionStatistics extends AbstractLifeCycle implements Statistics
|
||||||
|
{
|
||||||
|
private final AtomicLong _statsStartedAt = new AtomicLong(-1L);
|
||||||
|
private final CounterStatistic _connectionStats = new CounterStatistic();
|
||||||
|
private final SampleStatistic _messagesIn = new SampleStatistic();
|
||||||
|
private final SampleStatistic _messagesOut = new SampleStatistic();
|
||||||
|
private final SampleStatistic _connectionDurationStats = new SampleStatistic();
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
|
public int getBytesIn()
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBytesOut()
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @return Number of connections accepted by the server since statsReset() called. Undefined if setStatsOn(false).
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getConnections()
|
||||||
|
{
|
||||||
|
return (int)_connectionStats.getTotal();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @return Maximum duration in milliseconds of an open connection since statsReset() called. Undefined if setStatsOn(false).
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public long getConnectionsDurationMax()
|
||||||
|
{
|
||||||
|
return _connectionDurationStats.getMax();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @return Mean duration in milliseconds of open connections since statsReset() called. Undefined if setStatsOn(false).
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public double getConnectionsDurationMean()
|
||||||
|
{
|
||||||
|
return _connectionDurationStats.getMean();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @return Standard deviation of duration in milliseconds of open connections since statsReset() called. Undefined if setStatsOn(false).
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public double getConnectionsDurationStdDev()
|
||||||
|
{
|
||||||
|
return _connectionDurationStats.getStdDev();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @return Returns the connectionsDurationTotal.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public long getConnectionsDurationTotal()
|
||||||
|
{
|
||||||
|
return _connectionDurationStats.getTotal();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @return Maximum number of requests per connection since statsReset() called. Undefined if setStatsOn(false).
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getConnectionsMessagesInMax()
|
||||||
|
{
|
||||||
|
return (int)_messagesIn.getMax();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @return Mean number of requests per connection since statsReset() called. Undefined if setStatsOn(false).
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public double getConnectionsMessagesInMean()
|
||||||
|
{
|
||||||
|
return _messagesIn.getMean();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @return Standard deviation of number of requests per connection since statsReset() called. Undefined if setStatsOn(false).
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public double getConnectionsMessagesInStdDev()
|
||||||
|
{
|
||||||
|
return _messagesIn.getStdDev();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @return Number of connections currently open that were opened since statsReset() called. Undefined if setStatsOn(false).
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getConnectionsOpen()
|
||||||
|
{
|
||||||
|
return (int)_connectionStats.getCurrent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @return Maximum number of connections opened simultaneously since statsReset() called. Undefined if setStatsOn(false).
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getConnectionsOpenMax()
|
||||||
|
{
|
||||||
|
return (int)_connectionStats.getMax();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @return Get the number of requests handled by this connector since last call of statsReset(). If setStatsOn(false) then this is undefined.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getMessagesIn()
|
||||||
|
{
|
||||||
|
return (int)_messagesIn.getTotal();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @return Get the number of requests handled by this connector since last call of statsReset(). If setStatsOn(false) then this is undefined.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getMessagesOut()
|
||||||
|
{
|
||||||
|
return (int)_messagesIn.getTotal();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @return True if statistics collection is turned on.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean getStatsOn()
|
||||||
|
{
|
||||||
|
return _statsStartedAt.get() != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @return Timestamp stats were started at.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public long getStatsOnMs()
|
||||||
|
{
|
||||||
|
long start = _statsStartedAt.get();
|
||||||
|
|
||||||
|
return (start != -1)?(System.currentTimeMillis() - start):0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
|
public void doStart()
|
||||||
|
{
|
||||||
|
statsReset();
|
||||||
|
_statsStartedAt.set(System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
|
public void doStop()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* Reset statistics.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void statsReset()
|
||||||
|
{
|
||||||
|
_messagesIn.reset();
|
||||||
|
_connectionStats.reset();
|
||||||
|
_connectionDurationStats.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
|
public void connectionOpened()
|
||||||
|
{
|
||||||
|
if (isStarted())
|
||||||
|
_connectionStats.increment();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
|
public void connectionUpgraded(long duration, int msgIn, int msgOut)
|
||||||
|
{
|
||||||
|
_messagesIn.set(msgIn);
|
||||||
|
_messagesOut.set(msgOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
|
public void connectionClosed(long duration, int msgIn, int msgOut)
|
||||||
|
{
|
||||||
|
_messagesIn.set(msgIn);
|
||||||
|
_messagesOut.set(msgOut);
|
||||||
|
_connectionStats.decrement();
|
||||||
|
_connectionDurationStats.set(duration);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
package org.eclipse.jetty.server;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.io.EndPoint;
|
||||||
|
|
||||||
|
public interface HttpConnector extends Connector
|
||||||
|
{
|
||||||
|
int getRequestHeaderSize();
|
||||||
|
int getRequestBufferSize();
|
||||||
|
int getResponseHeaderSize();
|
||||||
|
int getResponseBufferSize();
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @return The port to use when redirecting a request if a data constraint of integral is
|
||||||
|
* required. See {@link org.eclipse.jetty.util.security.Constraint#getDataConstraint()}
|
||||||
|
*/
|
||||||
|
int getIntegralPort();
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @return The schema to use when redirecting a request if a data constraint of integral is
|
||||||
|
* required. See {@link org.eclipse.jetty.util.security.Constraint#getDataConstraint()}
|
||||||
|
*/
|
||||||
|
String getIntegralScheme();
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @param request A request
|
||||||
|
* @return true if the request is integral. This normally means the https schema has been used.
|
||||||
|
*/
|
||||||
|
boolean isIntegral(Request request);
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @return The port to use when redirecting a request if a data constraint of confidential is
|
||||||
|
* required. See {@link org.eclipse.jetty.util.security.Constraint#getDataConstraint()}
|
||||||
|
*/
|
||||||
|
int getConfidentialPort();
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @return The schema to use when redirecting a request if a data constraint of confidential is
|
||||||
|
* required. See {@link org.eclipse.jetty.util.security.Constraint#getDataConstraint()}
|
||||||
|
*/
|
||||||
|
String getConfidentialScheme();
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @param request A request
|
||||||
|
* @return true if the request is confidential. This normally means the https schema has been used.
|
||||||
|
*/
|
||||||
|
boolean isConfidential(Request request);
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/** Customize a request for an endpoint.
|
||||||
|
* Called on every request to allow customization of the request for
|
||||||
|
* the particular endpoint (eg security properties from a SSL connection).
|
||||||
|
* @param request
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
void customize(Request request) throws IOException;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue