Merge branch 'master' into release
This commit is contained in:
commit
3318b0d116
|
@ -15,3 +15,5 @@ dependencies.
|
|||
The tests do a lot of stress testing, and on some machines it is
|
||||
necessary to set the file descriptor limit to greater than 2048
|
||||
for the tests to all pass successfully.
|
||||
|
||||
Bypass tests by building with -Dmaven.test.skip=true but note that this will not produce some test jars that are leveraged in other places in the build.
|
||||
|
|
|
@ -50,10 +50,10 @@ public class LikeJettyXml
|
|||
|
||||
// Setup JMX
|
||||
MBeanContainer mbContainer=new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
|
||||
mbContainer.start();
|
||||
server.getContainer().addEventListener(mbContainer);
|
||||
server.addBean(mbContainer);
|
||||
mbContainer.addBean(Log.getRootLogger());
|
||||
|
||||
server.addBean(mbContainer,true);
|
||||
mbContainer.addBean(new Log());
|
||||
|
||||
// Setup Threadpool
|
||||
QueuedThreadPool threadPool = new QueuedThreadPool();
|
||||
|
|
|
@ -33,10 +33,10 @@ public class ManyServletContexts
|
|||
|
||||
// Setup JMX
|
||||
MBeanContainer mbContainer=new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
|
||||
mbContainer.start();
|
||||
server.getContainer().addEventListener(mbContainer);
|
||||
server.addBean(mbContainer);
|
||||
mbContainer.addBean(Log.getLog());
|
||||
|
||||
server.addBean(mbContainer,true);
|
||||
|
||||
ContextHandlerCollection contexts = new ContextHandlerCollection();
|
||||
server.setHandler(contexts);
|
||||
|
||||
|
|
|
@ -180,20 +180,23 @@ public abstract class AbstractHttpConnection extends AbstractConnection implemen
|
|||
|
||||
String method=_exchange.getMethod();
|
||||
String uri = _exchange.getRequestURI();
|
||||
if (_destination.isProxied() && !HttpMethods.CONNECT.equals(method) && uri.startsWith("/"))
|
||||
if (_destination.isProxied())
|
||||
{
|
||||
boolean secure = _destination.isSecure();
|
||||
String host = _destination.getAddress().getHost();
|
||||
int port = _destination.getAddress().getPort();
|
||||
StringBuilder absoluteURI = new StringBuilder();
|
||||
absoluteURI.append(secure ? HttpSchemes.HTTPS : HttpSchemes.HTTP);
|
||||
absoluteURI.append("://");
|
||||
absoluteURI.append(host);
|
||||
// Avoid adding default ports
|
||||
if (!(secure && port == 443 || !secure && port == 80))
|
||||
absoluteURI.append(":").append(port);
|
||||
absoluteURI.append(uri);
|
||||
uri = absoluteURI.toString();
|
||||
if (!HttpMethods.CONNECT.equals(method) && uri.startsWith("/"))
|
||||
{
|
||||
boolean secure = _destination.isSecure();
|
||||
String host = _destination.getAddress().getHost();
|
||||
int port = _destination.getAddress().getPort();
|
||||
StringBuilder absoluteURI = new StringBuilder();
|
||||
absoluteURI.append(secure ? HttpSchemes.HTTPS : HttpSchemes.HTTP);
|
||||
absoluteURI.append("://");
|
||||
absoluteURI.append(host);
|
||||
// Avoid adding default ports
|
||||
if (!(secure && port == 443 || !secure && port == 80))
|
||||
absoluteURI.append(":").append(port);
|
||||
absoluteURI.append(uri);
|
||||
uri = absoluteURI.toString();
|
||||
}
|
||||
Authentication auth = _destination.getProxyAuthentication();
|
||||
if (auth != null)
|
||||
auth.setCredentials(_exchange);
|
||||
|
|
|
@ -16,20 +16,20 @@ package org.eclipse.jetty.client;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import org.eclipse.jetty.client.security.Authentication;
|
||||
import org.eclipse.jetty.client.security.RealmResolver;
|
||||
import org.eclipse.jetty.client.security.SecurityListener;
|
||||
import org.eclipse.jetty.http.HttpBuffers;
|
||||
import org.eclipse.jetty.http.HttpBuffersImpl;
|
||||
import org.eclipse.jetty.http.HttpSchemes;
|
||||
import org.eclipse.jetty.io.Buffers;
|
||||
import org.eclipse.jetty.io.Buffers.Type;
|
||||
import org.eclipse.jetty.util.Attributes;
|
||||
import org.eclipse.jetty.util.AttributesMap;
|
||||
|
@ -66,7 +66,7 @@ import org.eclipse.jetty.util.thread.Timeout;
|
|||
* @see HttpExchange
|
||||
* @see HttpDestination
|
||||
*/
|
||||
public class HttpClient extends HttpBuffers implements Attributes, Dumpable
|
||||
public class HttpClient extends AggregateLifeCycle implements HttpBuffers, Attributes, Dumpable
|
||||
{
|
||||
public static final int CONNECTOR_SOCKET = 0;
|
||||
public static final int CONNECTOR_SELECT_CHANNEL = 2;
|
||||
|
@ -91,44 +91,46 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable
|
|||
private int _maxRedirects = 20;
|
||||
private LinkedList<String> _registeredListeners;
|
||||
|
||||
private SslContextFactory _sslContextFactory;
|
||||
private final SslContextFactory _sslContextFactory;
|
||||
|
||||
private RealmResolver _realmResolver;
|
||||
|
||||
private AttributesMap _attributes=new AttributesMap();
|
||||
|
||||
private final HttpBuffersImpl _buffers= new HttpBuffersImpl();
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
private void setBufferTypes()
|
||||
{
|
||||
if (_connectorType==CONNECTOR_SOCKET)
|
||||
{
|
||||
setRequestBufferType(Type.BYTE_ARRAY);
|
||||
setRequestHeaderType(Type.BYTE_ARRAY);
|
||||
setResponseBufferType(Type.BYTE_ARRAY);
|
||||
setResponseHeaderType(Type.BYTE_ARRAY);
|
||||
_buffers.setRequestBufferType(Type.BYTE_ARRAY);
|
||||
_buffers.setRequestHeaderType(Type.BYTE_ARRAY);
|
||||
_buffers.setResponseBufferType(Type.BYTE_ARRAY);
|
||||
_buffers.setResponseHeaderType(Type.BYTE_ARRAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
setRequestBufferType(Type.DIRECT);
|
||||
setRequestHeaderType(_useDirectBuffers?Type.DIRECT:Type.INDIRECT);
|
||||
setResponseBufferType(Type.DIRECT);
|
||||
setResponseHeaderType(_useDirectBuffers?Type.DIRECT:Type.INDIRECT);
|
||||
_buffers.setRequestBufferType(Type.DIRECT);
|
||||
_buffers.setRequestHeaderType(_useDirectBuffers?Type.DIRECT:Type.INDIRECT);
|
||||
_buffers.setResponseBufferType(Type.DIRECT);
|
||||
_buffers.setResponseHeaderType(_useDirectBuffers?Type.DIRECT:Type.INDIRECT);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
public HttpClient()
|
||||
{
|
||||
this(new SslContextFactory());
|
||||
setBufferTypes();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
public HttpClient(SslContextFactory sslContextFactory)
|
||||
{
|
||||
_sslContextFactory = sslContextFactory;
|
||||
setBufferTypes();
|
||||
addBean(_sslContextFactory);
|
||||
addBean(_buffers);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
|
@ -149,25 +151,6 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable
|
|||
_connectBlocking = connectBlocking;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.util.component.Dumpable#dump()
|
||||
*/
|
||||
public String dump()
|
||||
{
|
||||
return AggregateLifeCycle.dump(this);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.util.component.Dumpable#dump(java.lang.Appendable, java.lang.String)
|
||||
*/
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
out.append(String.valueOf(this)).append("\n");
|
||||
AggregateLifeCycle.dump(out,indent,Arrays.asList(_threadPool,_connector),_destinations.values());
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
public void send(HttpExchange exchange) throws IOException
|
||||
{
|
||||
|
@ -183,25 +166,20 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable
|
|||
*/
|
||||
public ThreadPool getThreadPool()
|
||||
{
|
||||
if (_threadPool==null)
|
||||
{
|
||||
QueuedThreadPool pool = new QueuedThreadPool();
|
||||
pool.setMaxThreads(16);
|
||||
pool.setDaemon(true);
|
||||
pool.setName("HttpClient");
|
||||
_threadPool = pool;
|
||||
}
|
||||
|
||||
return _threadPool;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
/** Set the ThreadPool.
|
||||
* The threadpool passed is added via {@link #addBean(Object)} so that
|
||||
* it's lifecycle may be managed as a {@link AggregateLifeCycle}.
|
||||
* @param threadPool the threadPool to set
|
||||
*/
|
||||
public void setThreadPool(ThreadPool threadPool)
|
||||
{
|
||||
removeBean(_threadPool);
|
||||
_threadPool = threadPool;
|
||||
addBean(_threadPool);
|
||||
}
|
||||
|
||||
|
||||
|
@ -338,6 +316,7 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable
|
|||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Registers a listener that can listen to the stream of execution between the client and the
|
||||
* server and influence events. Sequential calls to the method wrapper sequentially wrap the preceding
|
||||
|
@ -422,33 +401,26 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable
|
|||
protected void doStart() throws Exception
|
||||
{
|
||||
setBufferTypes();
|
||||
super.doStart();
|
||||
|
||||
_timeoutQ.setDuration(_timeout);
|
||||
_timeoutQ.setNow();
|
||||
_idleTimeoutQ.setDuration(_idleTimeout);
|
||||
_idleTimeoutQ.setNow();
|
||||
|
||||
if (_threadPool == null)
|
||||
getThreadPool();
|
||||
|
||||
if (_threadPool instanceof LifeCycle)
|
||||
if (_threadPool==null)
|
||||
{
|
||||
((LifeCycle)_threadPool).start();
|
||||
QueuedThreadPool pool = new LocalQueuedThreadPool();
|
||||
pool.setMaxThreads(16);
|
||||
pool.setDaemon(true);
|
||||
pool.setName("HttpClient");
|
||||
_threadPool = pool;
|
||||
addBean(_threadPool,true);
|
||||
}
|
||||
|
||||
_sslContextFactory.start();
|
||||
_connector=(_connectorType == CONNECTOR_SELECT_CHANNEL)?new SelectConnector(this):new SocketConnector(this);
|
||||
addBean(_connector,true);
|
||||
|
||||
if (_connectorType == CONNECTOR_SELECT_CHANNEL)
|
||||
{
|
||||
|
||||
_connector = new SelectConnector(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
_connector = new SocketConnector(this);
|
||||
}
|
||||
_connector.start();
|
||||
super.doStart();
|
||||
|
||||
_threadPool.dispatch(new Runnable()
|
||||
{
|
||||
|
@ -462,7 +434,7 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable
|
|||
{
|
||||
Thread.sleep(200);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
catch (InterruptedException ignored)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -470,32 +442,25 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable
|
|||
});
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
long getNow()
|
||||
{
|
||||
return _timeoutQ.getNow();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
_connector.stop();
|
||||
_connector = null;
|
||||
_sslContextFactory.stop();
|
||||
|
||||
if (_threadPool instanceof LifeCycle)
|
||||
{
|
||||
((LifeCycle)_threadPool).stop();
|
||||
}
|
||||
for (HttpDestination destination : _destinations.values())
|
||||
{
|
||||
destination.close();
|
||||
}
|
||||
|
||||
_timeoutQ.cancelAll();
|
||||
_idleTimeoutQ.cancelAll();
|
||||
|
||||
super.doStop();
|
||||
|
||||
if (_threadPool instanceof LocalQueuedThreadPool)
|
||||
{
|
||||
removeBean(_threadPool);
|
||||
_threadPool = null;
|
||||
}
|
||||
|
||||
removeBean(_connector);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -667,6 +632,96 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable
|
|||
_maxRedirects = redirects;
|
||||
}
|
||||
|
||||
public int getRequestBufferSize()
|
||||
{
|
||||
return _buffers.getRequestBufferSize();
|
||||
}
|
||||
|
||||
public void setRequestBufferSize(int requestBufferSize)
|
||||
{
|
||||
_buffers.setRequestBufferSize(requestBufferSize);
|
||||
}
|
||||
|
||||
public int getRequestHeaderSize()
|
||||
{
|
||||
return _buffers.getRequestHeaderSize();
|
||||
}
|
||||
|
||||
public void setRequestHeaderSize(int requestHeaderSize)
|
||||
{
|
||||
_buffers.setRequestHeaderSize(requestHeaderSize);
|
||||
}
|
||||
|
||||
public int getResponseBufferSize()
|
||||
{
|
||||
return _buffers.getResponseBufferSize();
|
||||
}
|
||||
|
||||
public void setResponseBufferSize(int responseBufferSize)
|
||||
{
|
||||
_buffers.setResponseBufferSize(responseBufferSize);
|
||||
}
|
||||
|
||||
public int getResponseHeaderSize()
|
||||
{
|
||||
return _buffers.getResponseHeaderSize();
|
||||
}
|
||||
|
||||
public void setResponseHeaderSize(int responseHeaderSize)
|
||||
{
|
||||
_buffers.setResponseHeaderSize(responseHeaderSize);
|
||||
}
|
||||
|
||||
public Type getRequestBufferType()
|
||||
{
|
||||
return _buffers.getRequestBufferType();
|
||||
}
|
||||
|
||||
public Type getRequestHeaderType()
|
||||
{
|
||||
return _buffers.getRequestHeaderType();
|
||||
}
|
||||
|
||||
public Type getResponseBufferType()
|
||||
{
|
||||
return _buffers.getResponseBufferType();
|
||||
}
|
||||
|
||||
public Type getResponseHeaderType()
|
||||
{
|
||||
return _buffers.getResponseHeaderType();
|
||||
}
|
||||
|
||||
public void setRequestBuffers(Buffers requestBuffers)
|
||||
{
|
||||
_buffers.setRequestBuffers(requestBuffers);
|
||||
}
|
||||
|
||||
public void setResponseBuffers(Buffers responseBuffers)
|
||||
{
|
||||
_buffers.setResponseBuffers(responseBuffers);
|
||||
}
|
||||
|
||||
public Buffers getRequestBuffers()
|
||||
{
|
||||
return _buffers.getRequestBuffers();
|
||||
}
|
||||
|
||||
public Buffers getResponseBuffers()
|
||||
{
|
||||
return _buffers.getResponseBuffers();
|
||||
}
|
||||
|
||||
public void setMaxBuffers(int maxBuffers)
|
||||
{
|
||||
_buffers.setMaxBuffers(maxBuffers);
|
||||
}
|
||||
|
||||
public int getMaxBuffers()
|
||||
{
|
||||
return _buffers.getMaxBuffers();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Deprecated
|
||||
public String getTrustStoreLocation()
|
||||
|
@ -839,4 +894,8 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable
|
|||
{
|
||||
_sslContextFactory.setSecureRandomAlgorithm(secureRandomAlgorithm);
|
||||
}
|
||||
|
||||
private static class LocalQueuedThreadPool extends QueuedThreadPool
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,10 +18,8 @@ import java.net.SocketTimeoutException;
|
|||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.nio.channels.UnresolvedAddressException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.net.ssl.SSLEngine;
|
||||
|
||||
import org.eclipse.jetty.io.AsyncEndPoint;
|
||||
|
@ -32,7 +30,6 @@ import org.eclipse.jetty.io.nio.AsyncConnection;
|
|||
import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
|
||||
import org.eclipse.jetty.io.nio.SelectorManager;
|
||||
import org.eclipse.jetty.io.nio.SslConnection;
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.util.component.AggregateLifeCycle;
|
||||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
|
@ -41,7 +38,7 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
|
|||
import org.eclipse.jetty.util.thread.Timeout;
|
||||
import org.eclipse.jetty.util.thread.Timeout.Task;
|
||||
|
||||
class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector, Dumpable
|
||||
class SelectConnector extends AggregateLifeCycle implements HttpClient.Connector, Dumpable
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(SelectConnector.class);
|
||||
|
||||
|
@ -49,39 +46,16 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector,
|
|||
private final Manager _selectorManager=new Manager();
|
||||
private final Map<SocketChannel, Timeout.Task> _connectingChannels = new ConcurrentHashMap<SocketChannel, Timeout.Task>();
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param httpClient the HttpClient this connector is associated to
|
||||
* @param httpClient the HttpClient this connector is associated to. It is
|
||||
* added via the {@link #addBean(Object, boolean)} as an unmanaged bean.
|
||||
*/
|
||||
SelectConnector(HttpClient httpClient)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
super.doStart();
|
||||
|
||||
_selectorManager.start();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
_selectorManager.stop();
|
||||
}
|
||||
|
||||
public String dump()
|
||||
{
|
||||
return AggregateLifeCycle.dump(this);
|
||||
}
|
||||
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
out.append(String.valueOf(this)).append("\n");
|
||||
AggregateLifeCycle.dump(out, indent, Arrays.asList(_selectorManager));
|
||||
addBean(_httpClient,false);
|
||||
addBean(_selectorManager,true);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -97,9 +71,9 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector,
|
|||
|
||||
if (_httpClient.isConnectBlocking())
|
||||
{
|
||||
channel.socket().connect(address.toSocketAddress(), _httpClient.getConnectTimeout());
|
||||
channel.configureBlocking(false);
|
||||
_selectorManager.register( channel, destination );
|
||||
channel.socket().connect(address.toSocketAddress(), _httpClient.getConnectTimeout());
|
||||
channel.configureBlocking(false);
|
||||
_selectorManager.register( channel, destination );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -451,11 +425,10 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector,
|
|||
{
|
||||
return _endp.isCheckForIdle();
|
||||
}
|
||||
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "Upgradable:"+_endp.toString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009-2009 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.client.security.Authentication;
|
||||
import org.eclipse.jetty.client.security.BasicAuthentication;
|
||||
import org.eclipse.jetty.client.security.Realm;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.ConnectHandler;
|
||||
import org.eclipse.jetty.server.nio.SelectChannelConnector;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class HttpsProxyAuthenticationTest
|
||||
{
|
||||
private Server _proxy = new Server();
|
||||
private HttpClient _client = new HttpClient();
|
||||
private boolean authHandlerSend;
|
||||
|
||||
@Before
|
||||
public void init() throws Exception
|
||||
{
|
||||
SelectChannelConnector connector = new SelectChannelConnector();
|
||||
_proxy.addConnector(connector);
|
||||
_proxy.setHandler(new ConnectHandler()
|
||||
{
|
||||
@Override
|
||||
protected boolean handleAuthentication(HttpServletRequest request, HttpServletResponse response, String address) throws ServletException, IOException
|
||||
{
|
||||
String authHeader = request.getHeader("Authorization");
|
||||
if (authHeader != null && authHeader.length() > 0)
|
||||
authHandlerSend = true;
|
||||
return super.handleAuthentication(request,response,address);
|
||||
}
|
||||
});
|
||||
_proxy.start();
|
||||
int proxyPort = connector.getLocalPort();
|
||||
|
||||
Authentication authentication = new BasicAuthentication(new Realm()
|
||||
{
|
||||
public String getId()
|
||||
{
|
||||
return "MyRealm";
|
||||
}
|
||||
|
||||
public String getPrincipal()
|
||||
{
|
||||
return "jetty";
|
||||
}
|
||||
|
||||
public String getCredentials()
|
||||
{
|
||||
return "jetty";
|
||||
}
|
||||
});
|
||||
|
||||
_client.setProxy(new Address("localhost", proxyPort));
|
||||
_client.setProxyAuthentication(authentication);
|
||||
_client.start();
|
||||
}
|
||||
|
||||
@After
|
||||
public void destroy() throws Exception
|
||||
{
|
||||
_client.stop();
|
||||
_proxy.stop();
|
||||
_proxy.join();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void httpsViaProxyThatReturns504ErrorTest() throws Exception
|
||||
{
|
||||
// Assume that we can connect to google
|
||||
String host = "google.com";
|
||||
int port = 443;
|
||||
Socket socket = new Socket();
|
||||
try
|
||||
{
|
||||
socket.connect(new InetSocketAddress(host, port), 1000);
|
||||
}
|
||||
catch (IOException x)
|
||||
{
|
||||
Assume.assumeNoException(x);
|
||||
}
|
||||
finally
|
||||
{
|
||||
socket.close();
|
||||
}
|
||||
|
||||
HttpExchange exchange = new ContentExchange();
|
||||
exchange.setURL("https://" + host + ":" + port);
|
||||
exchange.addRequestHeader("behaviour", "google");
|
||||
_client.send(exchange);
|
||||
Assert.assertEquals(HttpExchange.STATUS_COMPLETED, exchange.waitForDone());
|
||||
Assert.assertTrue("Authorization header not set!", authHandlerSend);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.EOFException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
@ -34,6 +35,7 @@ import org.eclipse.jetty.io.Connection;
|
|||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.io.nio.AsyncConnection;
|
||||
import org.eclipse.jetty.io.nio.SslConnection;
|
||||
import org.eclipse.jetty.server.AsyncHttpConnection;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
|
@ -45,7 +47,6 @@ import org.junit.After;
|
|||
import org.junit.Assert;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
|
@ -103,7 +104,7 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
@Override
|
||||
protected AsyncConnection newPlainConnection(SocketChannel channel, AsyncEndPoint endPoint)
|
||||
{
|
||||
return new org.eclipse.jetty.server.AsyncHttpConnection(this, endPoint, getServer())
|
||||
return new AsyncHttpConnection(this, endPoint, getServer())
|
||||
{
|
||||
@Override
|
||||
protected HttpParser newHttpParser(Buffers requestBuffers, EndPoint endPoint, HttpParser.EventHandler requestHandler)
|
||||
|
@ -136,21 +137,32 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
{
|
||||
public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
|
||||
{
|
||||
request.setHandled(true);
|
||||
String contentLength = request.getHeader("Content-Length");
|
||||
if (contentLength != null)
|
||||
try
|
||||
{
|
||||
int length = Integer.parseInt(contentLength);
|
||||
ServletInputStream input = httpRequest.getInputStream();
|
||||
ServletOutputStream output = httpResponse.getOutputStream();
|
||||
byte[] buffer = new byte[32 * 1024];
|
||||
for (int i = 0; i < length; ++i)
|
||||
request.setHandled(true);
|
||||
String contentLength = request.getHeader("Content-Length");
|
||||
if (contentLength != null)
|
||||
{
|
||||
int read = input.read(buffer);
|
||||
if ("/echo".equals(target))
|
||||
output.write(buffer, 0, read);
|
||||
int length = Integer.parseInt(contentLength);
|
||||
ServletInputStream input = httpRequest.getInputStream();
|
||||
ServletOutputStream output = httpResponse.getOutputStream();
|
||||
byte[] buffer = new byte[32 * 1024];
|
||||
while (length > 0)
|
||||
{
|
||||
int read = input.read(buffer);
|
||||
if (read < 0)
|
||||
throw new EOFException();
|
||||
length -= read;
|
||||
if (target.startsWith("/echo"))
|
||||
output.write(buffer, 0, read);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException x)
|
||||
{
|
||||
if (!(target.endsWith("suppress_exception")))
|
||||
throw x;
|
||||
}
|
||||
}
|
||||
});
|
||||
server.start();
|
||||
|
@ -226,6 +238,7 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
Assert.assertNull(handshake.get(5, TimeUnit.SECONDS));
|
||||
|
||||
// Check that we did not spin
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
Assert.assertThat(sslHandles.get(), lessThan(20));
|
||||
Assert.assertThat(sslFlushes.get(), lessThan(20));
|
||||
Assert.assertThat(httpParses.get(), lessThan(50));
|
||||
|
@ -304,6 +317,7 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
Assert.assertNull(handshake.get(5, TimeUnit.SECONDS));
|
||||
|
||||
// Check that we did not spin
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
Assert.assertThat(sslHandles.get(), lessThan(20));
|
||||
Assert.assertThat(sslFlushes.get(), lessThan(20));
|
||||
Assert.assertThat(httpParses.get(), lessThan(50));
|
||||
|
@ -333,6 +347,129 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
proxy.flushToClient(record);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClientHelloIncompleteThenReset() throws Exception
|
||||
{
|
||||
final SSLSocket client = newClient();
|
||||
|
||||
threadPool.submit(new Callable<Object>()
|
||||
{
|
||||
public Object call() throws Exception
|
||||
{
|
||||
client.startHandshake();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
// Client Hello
|
||||
TLSRecord record = proxy.readFromClient();
|
||||
byte[] bytes = record.getBytes();
|
||||
byte[] chunk1 = new byte[2 * bytes.length / 3];
|
||||
System.arraycopy(bytes, 0, chunk1, 0, chunk1.length);
|
||||
proxy.flushToServer(100, chunk1);
|
||||
|
||||
proxy.sendRSTToServer();
|
||||
|
||||
// Wait a while to detect spinning
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
Assert.assertThat(sslHandles.get(), lessThan(20));
|
||||
Assert.assertThat(sslFlushes.get(), lessThan(20));
|
||||
Assert.assertThat(httpParses.get(), lessThan(50));
|
||||
|
||||
client.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClientHelloThenReset() throws Exception
|
||||
{
|
||||
final SSLSocket client = newClient();
|
||||
|
||||
threadPool.submit(new Callable<Object>()
|
||||
{
|
||||
public Object call() throws Exception
|
||||
{
|
||||
client.startHandshake();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
// Client Hello
|
||||
TLSRecord record = proxy.readFromClient();
|
||||
Assert.assertNotNull(record);
|
||||
proxy.flushToServer(record);
|
||||
|
||||
proxy.sendRSTToServer();
|
||||
|
||||
// Wait a while to detect spinning
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
Assert.assertThat(sslHandles.get(), lessThan(20));
|
||||
Assert.assertThat(sslFlushes.get(), lessThan(20));
|
||||
Assert.assertThat(httpParses.get(), lessThan(50));
|
||||
|
||||
client.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandshakeThenReset() throws Exception
|
||||
{
|
||||
final SSLSocket client = newClient();
|
||||
|
||||
SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
|
||||
client.startHandshake();
|
||||
Assert.assertTrue(automaticProxyFlow.stop(5, TimeUnit.SECONDS));
|
||||
|
||||
proxy.sendRSTToServer();
|
||||
|
||||
// Wait a while to detect spinning
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
Assert.assertThat(sslHandles.get(), lessThan(20));
|
||||
Assert.assertThat(sslFlushes.get(), lessThan(20));
|
||||
Assert.assertThat(httpParses.get(), lessThan(50));
|
||||
|
||||
client.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestIncompleteThenReset() throws Exception
|
||||
{
|
||||
final SSLSocket client = newClient();
|
||||
|
||||
SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
|
||||
client.startHandshake();
|
||||
Assert.assertTrue(automaticProxyFlow.stop(5, TimeUnit.SECONDS));
|
||||
|
||||
threadPool.submit(new Callable<Object>()
|
||||
{
|
||||
public Object call() throws Exception
|
||||
{
|
||||
OutputStream clientOutput = client.getOutputStream();
|
||||
clientOutput.write(("" +
|
||||
"GET / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"\r\n").getBytes("UTF-8"));
|
||||
clientOutput.flush();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
// Application data
|
||||
TLSRecord record = proxy.readFromClient();
|
||||
byte[] bytes = record.getBytes();
|
||||
byte[] chunk1 = new byte[2 * bytes.length / 3];
|
||||
System.arraycopy(bytes, 0, chunk1, 0, chunk1.length);
|
||||
proxy.flushToServer(100, chunk1);
|
||||
|
||||
proxy.sendRSTToServer();
|
||||
|
||||
// Wait a while to detect spinning
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
Assert.assertThat(sslHandles.get(), lessThan(20));
|
||||
Assert.assertThat(sslFlushes.get(), lessThan(20));
|
||||
Assert.assertThat(httpParses.get(), lessThan(50));
|
||||
|
||||
client.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestResponse() throws Exception
|
||||
{
|
||||
|
@ -377,6 +514,7 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
}
|
||||
|
||||
// Check that we did not spin
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
Assert.assertThat(sslHandles.get(), lessThan(20));
|
||||
Assert.assertThat(sslFlushes.get(), lessThan(20));
|
||||
Assert.assertThat(httpParses.get(), lessThan(50));
|
||||
|
@ -468,6 +606,7 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
}
|
||||
|
||||
// Check that we did not spin
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
Assert.assertThat(sslHandles.get(), lessThan(750));
|
||||
Assert.assertThat(sslFlushes.get(), lessThan(750));
|
||||
Assert.assertThat(httpParses.get(), lessThan(150));
|
||||
|
@ -492,20 +631,12 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
proxy.flushToClient(record);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* Currently this test does not pass.
|
||||
* The problem is a mix of Java not being able to perform SSL half closes
|
||||
* (but SSL supporting it), and the current implementation in Jetty.
|
||||
* See the test below, that passes and whose only difference is that we
|
||||
* delay the output shutdown from the client.
|
||||
*
|
||||
* @throws Exception if the test fails
|
||||
*/
|
||||
@Ignore
|
||||
@Test
|
||||
public void testRequestWithCloseAlertAndShutdown() throws Exception
|
||||
{
|
||||
// See next test on why we only run in Linux
|
||||
Assume.assumeTrue(OS.IS_LINUX);
|
||||
|
||||
final SSLSocket client = newClient();
|
||||
|
||||
SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
|
||||
|
@ -555,10 +686,11 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
Assert.assertEquals(TLSRecord.Type.ALERT, record.getType());
|
||||
// We can't forward to the client, its socket is already closed
|
||||
|
||||
// Socket close
|
||||
record = proxy.readFromClient();
|
||||
Assert.assertNull(String.valueOf(record), record);
|
||||
proxy.flushToServer(record);
|
||||
// Check that we did not spin
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
Assert.assertThat(sslHandles.get(), lessThan(20));
|
||||
Assert.assertThat(sslFlushes.get(), lessThan(20));
|
||||
Assert.assertThat(httpParses.get(), lessThan(50));
|
||||
|
||||
// Socket close
|
||||
record = proxy.readFromServer();
|
||||
|
@ -569,21 +701,16 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
@Test
|
||||
public void testRequestWithCloseAlert() throws Exception
|
||||
{
|
||||
if ( !OS.IS_LINUX )
|
||||
{
|
||||
// currently we are ignoring this test on anything other then linux
|
||||
|
||||
//http://tools.ietf.org/html/rfc2246#section-7.2.1
|
||||
// Currently we are ignoring this test on anything other then linux
|
||||
// http://tools.ietf.org/html/rfc2246#section-7.2.1
|
||||
|
||||
// TODO (react to this portion which seems to allow win/mac behavior)
|
||||
// It is required that the other party respond with a close_notify alert of its own
|
||||
// and close down the connection immediately, discarding any pending writes. It is not
|
||||
// required for the initiator of the close to wait for the responding
|
||||
// close_notify alert before closing the read side of the connection.
|
||||
Assume.assumeTrue(OS.IS_LINUX);
|
||||
|
||||
// TODO (react to this portion which seems to allow win/mac behavior)
|
||||
//It is required that the other party respond with a close_notify alert of its own
|
||||
//and close down the connection immediately, discarding any pending writes. It is not
|
||||
//required for the initiator of the close to wait for the responding
|
||||
//close_notify alert before closing the read side of the connection.
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
final SSLSocket client = newClient();
|
||||
|
||||
SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
|
||||
|
@ -634,6 +761,7 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
// We can't forward to the client, its socket is already closed
|
||||
|
||||
// Check that we did not spin
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
Assert.assertThat(sslHandles.get(), lessThan(20));
|
||||
Assert.assertThat(sslFlushes.get(), lessThan(20));
|
||||
Assert.assertThat(httpParses.get(), lessThan(50));
|
||||
|
@ -692,6 +820,7 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
proxy.flushToClient(record);
|
||||
|
||||
// Check that we did not spin
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
Assert.assertThat(sslHandles.get(), lessThan(20));
|
||||
Assert.assertThat(sslFlushes.get(), lessThan(20));
|
||||
Assert.assertThat(httpParses.get(), lessThan(50));
|
||||
|
@ -700,7 +829,7 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testRequestWithBigContentWriteBlockedAndResetException() throws Exception
|
||||
public void testRequestWithBigContentWriteBlockedThenReset() throws Exception
|
||||
{
|
||||
final SSLSocket client = newClient();
|
||||
|
||||
|
@ -744,11 +873,63 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
// connection, and this will cause an exception in the
|
||||
// server that is trying to write the data
|
||||
|
||||
proxy.resetServer();
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
proxy.sendRSTToServer();
|
||||
|
||||
// Wait a while to detect spinning
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
Assert.assertThat(sslHandles.get(), lessThan(20));
|
||||
Assert.assertThat(sslFlushes.get(), lessThan(20));
|
||||
Assert.assertThat(httpParses.get(), lessThan(50));
|
||||
|
||||
client.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestWithBigContentReadBlockedThenReset() throws Exception
|
||||
{
|
||||
final SSLSocket client = newClient();
|
||||
|
||||
SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
|
||||
client.startHandshake();
|
||||
Assert.assertTrue(automaticProxyFlow.stop(5, TimeUnit.SECONDS));
|
||||
|
||||
byte[] data = new byte[128 * 1024];
|
||||
Arrays.fill(data, (byte)'X');
|
||||
final String content = new String(data, "UTF-8");
|
||||
Future<Object> request = threadPool.submit(new Callable<Object>()
|
||||
{
|
||||
public Object call() throws Exception
|
||||
{
|
||||
OutputStream clientOutput = client.getOutputStream();
|
||||
clientOutput.write(("" +
|
||||
"GET /echo_suppress_exception HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Content-Length: " + content.length() + "\r\n" +
|
||||
"\r\n" +
|
||||
content).getBytes("UTF-8"));
|
||||
clientOutput.flush();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
// Nine TLSRecords will be generated for the request,
|
||||
// but we write only 5 of them, so the server goes in read blocked state
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
// Application data
|
||||
TLSRecord record = proxy.readFromClient();
|
||||
Assert.assertEquals(TLSRecord.Type.APPLICATION, record.getType());
|
||||
proxy.flushToServer(record, 0);
|
||||
}
|
||||
Assert.assertNull(request.get(5, TimeUnit.SECONDS));
|
||||
|
||||
// The server should be read blocked, and we send a RST
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
proxy.sendRSTToServer();
|
||||
|
||||
// Wait a while to detect spinning
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
Assert.assertThat(sslHandles.get(), lessThan(20));
|
||||
Assert.assertThat(sslFlushes.get(), lessThan(20));
|
||||
Assert.assertThat(httpParses.get(), lessThan(50));
|
||||
|
@ -762,17 +943,17 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
if ( !OS.IS_LINUX )
|
||||
{
|
||||
// currently we are ignoring this test on anything other then linux
|
||||
|
||||
|
||||
//http://tools.ietf.org/html/rfc2246#section-7.2.1
|
||||
|
||||
// TODO (react to this portion which seems to allow win/mac behavior)
|
||||
//It is required that the other party respond with a close_notify alert of its own
|
||||
// TODO (react to this portion which seems to allow win/mac behavior)
|
||||
//It is required that the other party respond with a close_notify alert of its own
|
||||
//and close down the connection immediately, discarding any pending writes. It is not
|
||||
//required for the initiator of the close to wait for the responding
|
||||
//close_notify alert before closing the read side of the connection.
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
final SSLSocket client = newClient();
|
||||
|
||||
SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
|
||||
|
@ -831,6 +1012,7 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
// We can't forward to the client, its socket is already closed
|
||||
|
||||
// Check that we did not spin
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
Assert.assertThat(sslHandles.get(), lessThan(20));
|
||||
Assert.assertThat(sslFlushes.get(), lessThan(20));
|
||||
Assert.assertThat(httpParses.get(), lessThan(50));
|
||||
|
@ -900,6 +1082,7 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
}
|
||||
|
||||
// Check that we did not spin
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
Assert.assertThat(sslHandles.get(), lessThan(20));
|
||||
Assert.assertThat(sslFlushes.get(), lessThan(20));
|
||||
Assert.assertThat(httpParses.get(), lessThan(50));
|
||||
|
@ -953,6 +1136,7 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
}
|
||||
|
||||
// Check that we did not spin
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
Assert.assertThat(sslHandles.get(), lessThan(20));
|
||||
Assert.assertThat(sslFlushes.get(), lessThan(20));
|
||||
Assert.assertThat(httpParses.get(), lessThan(150));
|
||||
|
@ -974,6 +1158,7 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
}
|
||||
|
||||
// Check that we did not spin
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
Assert.assertThat(sslHandles.get(), lessThan(20));
|
||||
Assert.assertThat(sslFlushes.get(), lessThan(20));
|
||||
Assert.assertThat(httpParses.get(), lessThan(150));
|
||||
|
@ -1105,6 +1290,7 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
}
|
||||
|
||||
// Check that we did not spin
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
Assert.assertThat(sslHandles.get(), lessThan(20));
|
||||
Assert.assertThat(sslFlushes.get(), lessThan(20));
|
||||
Assert.assertThat(httpParses.get(), lessThan(50));
|
||||
|
@ -1264,6 +1450,7 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
}
|
||||
|
||||
// Check that we did not spin
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
Assert.assertThat(sslHandles.get(), lessThan(20));
|
||||
Assert.assertThat(sslFlushes.get(), lessThan(20));
|
||||
Assert.assertThat(httpParses.get(), lessThan(100));
|
||||
|
@ -1312,7 +1499,7 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
// Client should close the socket, but let's hold it open.
|
||||
|
||||
// Check that we did not spin
|
||||
TimeUnit.MILLISECONDS.sleep(100);
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
Assert.assertThat(sslHandles.get(), lessThan(20));
|
||||
Assert.assertThat(sslFlushes.get(), lessThan(20));
|
||||
Assert.assertThat(httpParses.get(), lessThan(50));
|
||||
|
|
|
@ -320,7 +320,7 @@ public abstract class SslBytesTest
|
|||
return latch.await(time, unit);
|
||||
}
|
||||
|
||||
public void resetServer() throws IOException
|
||||
public void sendRSTToServer() throws IOException
|
||||
{
|
||||
// Calling setSoLinger(true, 0) causes close()
|
||||
// to send a RST instead of a FIN, causing an
|
||||
|
|
|
@ -139,6 +139,12 @@ public class DeploymentManager extends AggregateLifeCycle
|
|||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Set the AppProviders.
|
||||
* The providers passed are added via {@link #addBean(Object)} so that
|
||||
* their lifecycles may be managed as a {@link AggregateLifeCycle}.
|
||||
* @param providers
|
||||
*/
|
||||
public void setAppProviders(Collection<AppProvider> providers)
|
||||
{
|
||||
if (isRunning())
|
||||
|
|
|
@ -5,6 +5,6 @@ contexts:MMBean: Deployed Contexts
|
|||
appProviders:MMBean: Application Providers
|
||||
getApps(java.lang.String):MBean:ACTION: List apps that are located at specified App LifeCycle node
|
||||
getApps(java.lang.String)[0]:nodeName: Name of the App LifeCycle node
|
||||
requestAppGoal(java.lang.String,java.lang.String) ACTION: Request the app to be moved to the specified App LifeCycle node
|
||||
requestAppGoal(java.lang.String,java.lang.String):ACTION: Request the app to be moved to the specified App LifeCycle node
|
||||
requestAppGoal(java.lang.String,java.lang.String)[0]:appId:App identifier
|
||||
requestAppGoal(java.lang.String,java.lang.String)[1]:nodeName:Name of the App LifeCycle node
|
||||
requestAppGoal(java.lang.String,java.lang.String)[1]:nodeName:Name of the App LifeCycle node
|
||||
|
|
|
@ -31,6 +31,14 @@
|
|||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
<verbose>false</verbose>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
<version>7.6.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-http</artifactId>
|
||||
<name>Jetty :: Http Utility</name>
|
||||
<properties>
|
||||
|
|
|
@ -19,211 +19,85 @@ import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
|||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Abstract Buffer pool.
|
||||
* simple unbounded pool of buffers for header, request and response sizes.
|
||||
*
|
||||
*/
|
||||
public class HttpBuffers extends AbstractLifeCycle
|
||||
public interface HttpBuffers
|
||||
{
|
||||
private int _requestBufferSize=16*1024;
|
||||
private int _requestHeaderSize=6*1024;
|
||||
private int _responseBufferSize=32*1024;
|
||||
private int _responseHeaderSize=6*1024;
|
||||
private int _maxBuffers=1024;
|
||||
|
||||
private Buffers.Type _requestBufferType=Buffers.Type.BYTE_ARRAY;
|
||||
private Buffers.Type _requestHeaderType=Buffers.Type.BYTE_ARRAY;
|
||||
private Buffers.Type _responseBufferType=Buffers.Type.BYTE_ARRAY;
|
||||
private Buffers.Type _responseHeaderType=Buffers.Type.BYTE_ARRAY;
|
||||
|
||||
private Buffers _requestBuffers;
|
||||
private Buffers _responseBuffers;
|
||||
|
||||
|
||||
public HttpBuffers()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the requestBufferSize
|
||||
*/
|
||||
public int getRequestBufferSize()
|
||||
{
|
||||
return _requestBufferSize;
|
||||
}
|
||||
public int getRequestBufferSize();
|
||||
|
||||
/**
|
||||
* @param requestBufferSize the requestBufferSize to set
|
||||
*/
|
||||
public void setRequestBufferSize(int requestBufferSize)
|
||||
{
|
||||
_requestBufferSize = requestBufferSize;
|
||||
}
|
||||
public void setRequestBufferSize(int requestBufferSize);
|
||||
|
||||
/**
|
||||
* @return the requestHeaderSize
|
||||
*/
|
||||
public int getRequestHeaderSize()
|
||||
{
|
||||
return _requestHeaderSize;
|
||||
}
|
||||
public int getRequestHeaderSize();
|
||||
|
||||
/**
|
||||
* @param requestHeaderSize the requestHeaderSize to set
|
||||
*/
|
||||
public void setRequestHeaderSize(int requestHeaderSize)
|
||||
{
|
||||
_requestHeaderSize = requestHeaderSize;
|
||||
}
|
||||
public void setRequestHeaderSize(int requestHeaderSize);
|
||||
|
||||
/**
|
||||
* @return the responseBufferSize
|
||||
*/
|
||||
public int getResponseBufferSize()
|
||||
{
|
||||
return _responseBufferSize;
|
||||
}
|
||||
public int getResponseBufferSize();
|
||||
|
||||
/**
|
||||
* @param responseBufferSize the responseBufferSize to set
|
||||
*/
|
||||
public void setResponseBufferSize(int responseBufferSize)
|
||||
{
|
||||
_responseBufferSize = responseBufferSize;
|
||||
}
|
||||
public void setResponseBufferSize(int responseBufferSize);
|
||||
|
||||
/**
|
||||
* @return the responseHeaderSize
|
||||
*/
|
||||
public int getResponseHeaderSize()
|
||||
{
|
||||
return _responseHeaderSize;
|
||||
}
|
||||
public int getResponseHeaderSize();
|
||||
|
||||
/**
|
||||
* @param responseHeaderSize the responseHeaderSize to set
|
||||
*/
|
||||
public void setResponseHeaderSize(int responseHeaderSize)
|
||||
{
|
||||
_responseHeaderSize = responseHeaderSize;
|
||||
}
|
||||
public void setResponseHeaderSize(int responseHeaderSize);
|
||||
|
||||
/**
|
||||
* @return the requestBufferType
|
||||
*/
|
||||
public Buffers.Type getRequestBufferType()
|
||||
{
|
||||
return _requestBufferType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param requestBufferType the requestBufferType to set
|
||||
*/
|
||||
protected void setRequestBufferType(Buffers.Type requestBufferType)
|
||||
{
|
||||
_requestBufferType = requestBufferType;
|
||||
}
|
||||
public Buffers.Type getRequestBufferType();
|
||||
|
||||
/**
|
||||
* @return the requestHeaderType
|
||||
*/
|
||||
public Buffers.Type getRequestHeaderType()
|
||||
{
|
||||
return _requestHeaderType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param requestHeaderType the requestHeaderType to set
|
||||
*/
|
||||
protected void setRequestHeaderType(Buffers.Type requestHeaderType)
|
||||
{
|
||||
_requestHeaderType = requestHeaderType;
|
||||
}
|
||||
public Buffers.Type getRequestHeaderType();
|
||||
|
||||
/**
|
||||
* @return the responseBufferType
|
||||
*/
|
||||
public Buffers.Type getResponseBufferType()
|
||||
{
|
||||
return _responseBufferType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param responseBufferType the responseBufferType to set
|
||||
*/
|
||||
protected void setResponseBufferType(Buffers.Type responseBufferType)
|
||||
{
|
||||
_responseBufferType = responseBufferType;
|
||||
}
|
||||
public Buffers.Type getResponseBufferType();
|
||||
|
||||
/**
|
||||
* @return the responseHeaderType
|
||||
*/
|
||||
public Buffers.Type getResponseHeaderType()
|
||||
{
|
||||
return _responseHeaderType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param responseHeaderType the responseHeaderType to set
|
||||
*/
|
||||
protected void setResponseHeaderType(Buffers.Type responseHeaderType)
|
||||
{
|
||||
_responseHeaderType = responseHeaderType;
|
||||
}
|
||||
public Buffers.Type getResponseHeaderType();
|
||||
|
||||
/**
|
||||
* @param requestBuffers the requestBuffers to set
|
||||
*/
|
||||
public void setRequestBuffers(Buffers requestBuffers)
|
||||
{
|
||||
_requestBuffers = requestBuffers;
|
||||
}
|
||||
public void setRequestBuffers(Buffers requestBuffers);
|
||||
|
||||
/**
|
||||
* @param responseBuffers the responseBuffers to set
|
||||
*/
|
||||
public void setResponseBuffers(Buffers responseBuffers)
|
||||
{
|
||||
_responseBuffers = responseBuffers;
|
||||
}
|
||||
public void setResponseBuffers(Buffers responseBuffers);
|
||||
|
||||
@Override
|
||||
protected void doStart()
|
||||
throws Exception
|
||||
{
|
||||
_requestBuffers=BuffersFactory.newBuffers(_requestHeaderType,_requestHeaderSize,_requestBufferType,_requestBufferSize,_requestBufferType,getMaxBuffers());
|
||||
_responseBuffers=BuffersFactory.newBuffers(_responseHeaderType,_responseHeaderSize,_responseBufferType,_responseBufferSize,_responseBufferType,getMaxBuffers());
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStop()
|
||||
throws Exception
|
||||
{
|
||||
_requestBuffers=null;
|
||||
_responseBuffers=null;
|
||||
}
|
||||
public Buffers getRequestBuffers();
|
||||
|
||||
public Buffers getRequestBuffers()
|
||||
{
|
||||
return _requestBuffers;
|
||||
}
|
||||
|
||||
public Buffers getResponseBuffers();
|
||||
|
||||
public Buffers getResponseBuffers()
|
||||
{
|
||||
return _responseBuffers;
|
||||
}
|
||||
public void setMaxBuffers(int maxBuffers);
|
||||
|
||||
public void setMaxBuffers(int maxBuffers)
|
||||
{
|
||||
_maxBuffers = maxBuffers;
|
||||
}
|
||||
|
||||
public int getMaxBuffers()
|
||||
{
|
||||
return _maxBuffers;
|
||||
}
|
||||
public int getMaxBuffers();
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,233 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
|
||||
package org.eclipse.jetty.http;
|
||||
|
||||
import org.eclipse.jetty.io.Buffers;
|
||||
import org.eclipse.jetty.io.BuffersFactory;
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Abstract Buffer pool.
|
||||
* simple unbounded pool of buffers for header, request and response sizes.
|
||||
*
|
||||
*/
|
||||
public class HttpBuffersImpl extends AbstractLifeCycle implements HttpBuffers
|
||||
{
|
||||
private int _requestBufferSize=16*1024;
|
||||
private int _requestHeaderSize=6*1024;
|
||||
private int _responseBufferSize=32*1024;
|
||||
private int _responseHeaderSize=6*1024;
|
||||
private int _maxBuffers=1024;
|
||||
|
||||
private Buffers.Type _requestBufferType=Buffers.Type.BYTE_ARRAY;
|
||||
private Buffers.Type _requestHeaderType=Buffers.Type.BYTE_ARRAY;
|
||||
private Buffers.Type _responseBufferType=Buffers.Type.BYTE_ARRAY;
|
||||
private Buffers.Type _responseHeaderType=Buffers.Type.BYTE_ARRAY;
|
||||
|
||||
private Buffers _requestBuffers;
|
||||
private Buffers _responseBuffers;
|
||||
|
||||
|
||||
public HttpBuffersImpl()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the requestBufferSize
|
||||
*/
|
||||
public int getRequestBufferSize()
|
||||
{
|
||||
return _requestBufferSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param requestBufferSize the requestBufferSize to set
|
||||
*/
|
||||
public void setRequestBufferSize(int requestBufferSize)
|
||||
{
|
||||
_requestBufferSize = requestBufferSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the requestHeaderSize
|
||||
*/
|
||||
public int getRequestHeaderSize()
|
||||
{
|
||||
return _requestHeaderSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param requestHeaderSize the requestHeaderSize to set
|
||||
*/
|
||||
public void setRequestHeaderSize(int requestHeaderSize)
|
||||
{
|
||||
_requestHeaderSize = requestHeaderSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the responseBufferSize
|
||||
*/
|
||||
public int getResponseBufferSize()
|
||||
{
|
||||
return _responseBufferSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param responseBufferSize the responseBufferSize to set
|
||||
*/
|
||||
public void setResponseBufferSize(int responseBufferSize)
|
||||
{
|
||||
_responseBufferSize = responseBufferSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the responseHeaderSize
|
||||
*/
|
||||
public int getResponseHeaderSize()
|
||||
{
|
||||
return _responseHeaderSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param responseHeaderSize the responseHeaderSize to set
|
||||
*/
|
||||
public void setResponseHeaderSize(int responseHeaderSize)
|
||||
{
|
||||
_responseHeaderSize = responseHeaderSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the requestBufferType
|
||||
*/
|
||||
public Buffers.Type getRequestBufferType()
|
||||
{
|
||||
return _requestBufferType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param requestBufferType the requestBufferType to set
|
||||
*/
|
||||
public void setRequestBufferType(Buffers.Type requestBufferType)
|
||||
{
|
||||
_requestBufferType = requestBufferType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the requestHeaderType
|
||||
*/
|
||||
public Buffers.Type getRequestHeaderType()
|
||||
{
|
||||
return _requestHeaderType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param requestHeaderType the requestHeaderType to set
|
||||
*/
|
||||
public void setRequestHeaderType(Buffers.Type requestHeaderType)
|
||||
{
|
||||
_requestHeaderType = requestHeaderType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the responseBufferType
|
||||
*/
|
||||
public Buffers.Type getResponseBufferType()
|
||||
{
|
||||
return _responseBufferType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param responseBufferType the responseBufferType to set
|
||||
*/
|
||||
public void setResponseBufferType(Buffers.Type responseBufferType)
|
||||
{
|
||||
_responseBufferType = responseBufferType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the responseHeaderType
|
||||
*/
|
||||
public Buffers.Type getResponseHeaderType()
|
||||
{
|
||||
return _responseHeaderType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param responseHeaderType the responseHeaderType to set
|
||||
*/
|
||||
public void setResponseHeaderType(Buffers.Type responseHeaderType)
|
||||
{
|
||||
_responseHeaderType = responseHeaderType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param requestBuffers the requestBuffers to set
|
||||
*/
|
||||
public void setRequestBuffers(Buffers requestBuffers)
|
||||
{
|
||||
_requestBuffers = requestBuffers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param responseBuffers the responseBuffers to set
|
||||
*/
|
||||
public void setResponseBuffers(Buffers responseBuffers)
|
||||
{
|
||||
_responseBuffers = responseBuffers;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStart()
|
||||
throws Exception
|
||||
{
|
||||
_requestBuffers=BuffersFactory.newBuffers(_requestHeaderType,_requestHeaderSize,_requestBufferType,_requestBufferSize,_requestBufferType,getMaxBuffers());
|
||||
_responseBuffers=BuffersFactory.newBuffers(_responseHeaderType,_responseHeaderSize,_responseBufferType,_responseBufferSize,_responseBufferType,getMaxBuffers());
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStop()
|
||||
throws Exception
|
||||
{
|
||||
_requestBuffers=null;
|
||||
_responseBuffers=null;
|
||||
}
|
||||
|
||||
public Buffers getRequestBuffers()
|
||||
{
|
||||
return _requestBuffers;
|
||||
}
|
||||
|
||||
|
||||
public Buffers getResponseBuffers()
|
||||
{
|
||||
return _responseBuffers;
|
||||
}
|
||||
|
||||
public void setMaxBuffers(int maxBuffers)
|
||||
{
|
||||
_maxBuffers = maxBuffers;
|
||||
}
|
||||
|
||||
public int getMaxBuffers()
|
||||
{
|
||||
return _maxBuffers;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return _requestBuffers+"/"+_responseBuffers;
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@
|
|||
<version>7.6.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-io</artifactId>
|
||||
<name>Jetty :: IO Utility</name>
|
||||
<properties>
|
||||
|
|
|
@ -58,7 +58,7 @@ public abstract class AbstractBuffers implements Buffers
|
|||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Create a new content Buffer
|
||||
|
@ -77,7 +77,7 @@ public abstract class AbstractBuffers implements Buffers
|
|||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Create a new content Buffer
|
||||
|
@ -142,4 +142,9 @@ public abstract class AbstractBuffers implements Buffers
|
|||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
/* ------------------------------------------------------------ */
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%s [%d,%d]", getClass().getSimpleName(), _headerSize, _bufferSize);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ public class PooledBuffers extends AbstractBuffers
|
|||
_otherBuffers=bufferType==otherType;
|
||||
_maxSize=maxSize;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public Buffer getHeader()
|
||||
{
|
||||
|
@ -55,17 +55,17 @@ public class PooledBuffers extends AbstractBuffers
|
|||
return getHeader();
|
||||
if (_otherBuffers && size==getBufferSize())
|
||||
return getBuffer();
|
||||
|
||||
|
||||
// Look for an other buffer
|
||||
Buffer buffer = _others.poll();
|
||||
|
||||
|
||||
// consume all other buffers until one of the right size is found
|
||||
while (buffer!=null && buffer.capacity()!=size)
|
||||
{
|
||||
_size.decrementAndGet();
|
||||
buffer = _others.poll();
|
||||
}
|
||||
|
||||
|
||||
if (buffer==null)
|
||||
buffer=newBuffer(size);
|
||||
else
|
||||
|
@ -89,7 +89,16 @@ public class PooledBuffers extends AbstractBuffers
|
|||
else if (isBuffer(buffer))
|
||||
_buffers.add(buffer);
|
||||
else
|
||||
_others.add(buffer);
|
||||
_others.add(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%s [%d/%d@%d,%d/%d@%d,%d/%d@-]",
|
||||
getClass().getSimpleName(),
|
||||
_headers.size(),_maxSize,_headerSize,
|
||||
_buffers.size(),_maxSize,_bufferSize,
|
||||
_others.size(),_maxSize);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -246,8 +246,7 @@ public class ChannelEndPoint implements EndPoint
|
|||
}
|
||||
catch (IOException x)
|
||||
{
|
||||
LOG.debug(x.toString());
|
||||
LOG.ignore(x);
|
||||
LOG.debug("Exception while filling", x);
|
||||
try
|
||||
{
|
||||
if (_channel.isOpen())
|
||||
|
|
|
@ -260,7 +260,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
|
|||
for (int i=0;i<getSelectSets();i++)
|
||||
{
|
||||
final int id=i;
|
||||
dispatch(new Runnable()
|
||||
boolean selecting=dispatch(new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
|
@ -303,6 +303,9 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
|
|||
}
|
||||
|
||||
});
|
||||
|
||||
if (!selecting)
|
||||
throw new IllegalStateException("!Selecting");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -957,6 +960,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
|
|||
{
|
||||
LOG.ignore(e);
|
||||
}
|
||||
|
||||
AggregateLifeCycle.dump(out,indent,dump);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -541,6 +541,8 @@ public class SslConnection extends AbstractConnection implements AsyncConnection
|
|||
switch(result.getStatus())
|
||||
{
|
||||
case BUFFER_UNDERFLOW:
|
||||
if (_endp.isInputShutdown())
|
||||
_inbound.clear();
|
||||
break;
|
||||
|
||||
case BUFFER_OVERFLOW:
|
||||
|
@ -598,7 +600,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection
|
|||
{
|
||||
return _engine;
|
||||
}
|
||||
|
||||
|
||||
public AsyncEndPoint getEndpoint()
|
||||
{
|
||||
return _aEndp;
|
||||
|
|
|
@ -81,13 +81,6 @@ public class JaspiAuthenticator implements Authenticator
|
|||
|
||||
public Authentication validateRequest(ServletRequest request, ServletResponse response, boolean mandatory) throws ServerAuthException
|
||||
{
|
||||
System.err.println("\nJaspiAuthenticator.validateRequest, uri=" + ((javax.servlet.http.HttpServletRequest) request).getRequestURI()
|
||||
+ " lazy="
|
||||
+ _allowLazyAuthentication
|
||||
+ " mandatory="
|
||||
+ mandatory);
|
||||
new Throwable().printStackTrace();
|
||||
|
||||
JaspiMessageInfo info = new JaspiMessageInfo(request, response, mandatory);
|
||||
request.setAttribute("org.eclipse.jetty.security.jaspi.info", info);
|
||||
|
||||
|
@ -96,16 +89,12 @@ public class JaspiAuthenticator implements Authenticator
|
|||
//if its not mandatory to authenticate, and the authenticator returned UNAUTHENTICATED, we treat it as authentication deferred
|
||||
if (_allowLazyAuthentication && !info.isAuthMandatory() && a == Authentication.UNAUTHENTICATED)
|
||||
a =_deferred;
|
||||
|
||||
System.err.println("JaspiAuthenticator.validateRequest returning "+a);
|
||||
return a;
|
||||
}
|
||||
|
||||
// most likely validatedUser is not needed here.
|
||||
public boolean secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, User validatedUser) throws ServerAuthException
|
||||
{
|
||||
System.err.println("JaspiAuthenticator.secureResponse uri=" + ((javax.servlet.http.HttpServletRequest) req).getRequestURI());
|
||||
|
||||
JaspiMessageInfo info = (JaspiMessageInfo) req.getAttribute("org.eclipse.jetty.security.jaspi.info");
|
||||
if (info == null) throw new NullPointerException("MessageInfo from request missing: " + req);
|
||||
return secureResponse(info, validatedUser);
|
||||
|
@ -116,14 +105,11 @@ public class JaspiAuthenticator implements Authenticator
|
|||
{
|
||||
try
|
||||
{
|
||||
System.err.println("jaspAuthenticator.validateRequest(info)");
|
||||
String authContextId = _authConfig.getAuthContextID(messageInfo);
|
||||
ServerAuthContext authContext = _authConfig.getAuthContext(authContextId, _serviceSubject, _authProperties);
|
||||
Subject clientSubject = new Subject();
|
||||
|
||||
AuthStatus authStatus = authContext.validateRequest(messageInfo, clientSubject, _serviceSubject);
|
||||
// String authMethod =
|
||||
// (String)messageInfo.getMap().get(JaspiMessageInfo.AUTH_METHOD_KEY);
|
||||
|
||||
if (authStatus == AuthStatus.SEND_CONTINUE) return Authentication.SEND_CONTINUE;
|
||||
if (authStatus == AuthStatus.SEND_FAILURE) return Authentication.SEND_FAILURE;
|
||||
|
@ -188,8 +174,6 @@ public class JaspiAuthenticator implements Authenticator
|
|||
}
|
||||
catch (AuthException e)
|
||||
{
|
||||
System.err.println("Error in JaspiAuthenticator.secureResponse");
|
||||
e.printStackTrace();
|
||||
throw new ServerAuthException(e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,14 +97,10 @@ public class JaspiAuthenticatorFactory extends DefaultAuthenticatorFactory
|
|||
|
||||
Subject serviceSubject=findServiceSubject(server);
|
||||
String serverName=findServerName(server,serviceSubject);
|
||||
|
||||
System.err.println("authconfigfactory="+authConfigFactory+" serviceSubject="+serviceSubject+" serverName="+serverName);
|
||||
|
||||
String appContext = serverName + " " + context.getContextPath();
|
||||
|
||||
System.err.println("appcontext="+appContext);
|
||||
AuthConfigProvider authConfigProvider = authConfigFactory.getConfigProvider(MESSAGE_LAYER,appContext,listener);
|
||||
System.err.println("authconfigProvider="+authConfigProvider);
|
||||
|
||||
if (authConfigProvider != null)
|
||||
{
|
||||
ServletCallbackHandler servletCallbackHandler = new ServletCallbackHandler(loginService);
|
||||
|
|
|
@ -131,7 +131,6 @@ public class BaseAuthModule implements ServerAuthModule, ServerAuthContext
|
|||
if (credValidationCallback.getResult())
|
||||
{
|
||||
Set<LoginCallbackImpl> loginCallbacks = clientSubject.getPrivateCredentials(LoginCallbackImpl.class);
|
||||
System.err.println("LoginCallbackImpls.isEmpty="+loginCallbacks.isEmpty());
|
||||
if (!loginCallbacks.isEmpty())
|
||||
{
|
||||
LoginCallbackImpl loginCallback = loginCallbacks.iterator().next();
|
||||
|
|
|
@ -158,8 +158,6 @@ public class FormAuthModule extends BaseAuthModule
|
|||
boolean mandatory = isMandatory(messageInfo);
|
||||
mandatory |= isJSecurityCheck(uri);
|
||||
HttpSession session = request.getSession(mandatory);
|
||||
|
||||
System.err.println("FormAuthModule.validateRequest(info,subject,serviceSubject) for uri="+uri+" mandatory="+mandatory+" isLoginOrError="+isLoginOrErrorPage(URIUtil.addPaths(request.getServletPath(),request.getPathInfo())));
|
||||
|
||||
// not mandatory or its the login or login error page don't authenticate
|
||||
if (!mandatory || isLoginOrErrorPage(URIUtil.addPaths(request.getServletPath(),request.getPathInfo()))) return AuthStatus.SUCCESS;
|
||||
|
@ -171,7 +169,7 @@ public class FormAuthModule extends BaseAuthModule
|
|||
{
|
||||
final String username = request.getParameter(__J_USERNAME);
|
||||
final String password = request.getParameter(__J_PASSWORD);
|
||||
System.err.println("Try login username="+username+" password="+password);
|
||||
|
||||
boolean success = tryLogin(messageInfo, clientSubject, response, session, username, new Password(password));
|
||||
if (success)
|
||||
{
|
||||
|
@ -189,7 +187,6 @@ public class FormAuthModule extends BaseAuthModule
|
|||
nuri = URIUtil.SLASH;
|
||||
}
|
||||
|
||||
System.err.println("FormAuthModule succesful login, sending redirect to "+nuri);
|
||||
response.setContentLength(0);
|
||||
response.sendRedirect(response.encodeRedirectURL(nuri));
|
||||
return AuthStatus.SEND_CONTINUE;
|
||||
|
@ -215,8 +212,6 @@ public class FormAuthModule extends BaseAuthModule
|
|||
FormCredential form_cred = (FormCredential) session.getAttribute(__J_AUTHENTICATED);
|
||||
if (form_cred != null)
|
||||
{
|
||||
System.err.println("Form cred: form.username="+form_cred._jUserName+" form.pwd="+new String(form_cred._jPassword));
|
||||
|
||||
//TODO: we would like the form auth module to be able to invoke the loginservice.validate() method to check the previously authed user
|
||||
|
||||
boolean success = tryLogin(messageInfo, clientSubject, response, session, form_cred._jUserName, new Password(new String(form_cred._jPassword)));
|
||||
|
@ -249,7 +244,6 @@ public class FormAuthModule extends BaseAuthModule
|
|||
session.setAttribute(__J_URI, buf.toString());
|
||||
}
|
||||
|
||||
System.err.println("Redirecting to login page "+_formLoginPage+" and remembering juri="+buf.toString());
|
||||
response.setContentLength(0);
|
||||
response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths(request.getContextPath(), _formLoginPage)));
|
||||
return AuthStatus.SEND_CONTINUE;
|
||||
|
@ -288,12 +282,11 @@ public class FormAuthModule extends BaseAuthModule
|
|||
{
|
||||
char[] pwdChars = password.toString().toCharArray();
|
||||
Set<LoginCallbackImpl> loginCallbacks = clientSubject.getPrivateCredentials(LoginCallbackImpl.class);
|
||||
System.err.println("FormAuthModule, LoginCallbackImpl.isEmpty="+loginCallbacks.isEmpty());
|
||||
|
||||
if (!loginCallbacks.isEmpty())
|
||||
{
|
||||
LoginCallbackImpl loginCallback = loginCallbacks.iterator().next();
|
||||
FormCredential form_cred = new FormCredential(username, pwdChars, loginCallback.getUserPrincipal(), loginCallback.getSubject());
|
||||
|
||||
session.setAttribute(__J_AUTHENTICATED, form_cred);
|
||||
}
|
||||
|
||||
|
@ -310,7 +303,6 @@ public class FormAuthModule extends BaseAuthModule
|
|||
|
||||
public boolean isLoginOrErrorPage(String pathInContext)
|
||||
{
|
||||
System.err.println("ISLOGINORERRORPAGE? "+pathInContext+" error: "+_formErrorPath+" login:"+_formLoginPath);
|
||||
return pathInContext != null && (pathInContext.equals(_formErrorPath) || pathInContext.equals(_formLoginPath));
|
||||
}
|
||||
|
||||
|
|
|
@ -30,34 +30,28 @@
|
|||
<!-- Initialize the Jetty MBean container -->
|
||||
<!-- =========================================================== -->
|
||||
<New id="MBeanContainer" class="org.eclipse.jetty.jmx.MBeanContainer">
|
||||
<Arg>
|
||||
<Ref id="MBeanServer" />
|
||||
</Arg>
|
||||
<Arg><Ref id="MBeanServer" /></Arg>
|
||||
<Call name="start"/>
|
||||
</New>
|
||||
|
||||
<!-- Add to the Server to listen for object events -->
|
||||
<Get id="Container" name="container">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<Ref id="MBeanContainer" />
|
||||
</Arg>
|
||||
<Arg><Ref id="MBeanContainer" /></Arg>
|
||||
</Call>
|
||||
</Get>
|
||||
|
||||
<!-- Add to the Server as a lifecycle -->
|
||||
<!-- Only do this if you know you will only have a single jetty server -->
|
||||
<!-- Add to the Server as a managed lifecycle -->
|
||||
<Call name="addBean">
|
||||
<Arg>
|
||||
<Ref id="MBeanContainer" />
|
||||
</Arg>
|
||||
<Arg><Ref id="MBeanContainer"/></Arg>
|
||||
<Arg type="boolean">true</Arg>
|
||||
</Call>
|
||||
|
||||
<!-- Add the static log -->
|
||||
<Get id="Logger" class="org.eclipse.jetty.util.log.Log" name="log" />
|
||||
<Ref id="MBeanContainer">
|
||||
<Call name="addBean">
|
||||
<Arg>
|
||||
<Ref id="Logger" />
|
||||
<New class="org.eclipse.jetty.util.log.Log"/>
|
||||
</Arg>
|
||||
</Call>
|
||||
</Ref>
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.eclipse.jetty.util.component.Container.Relationship;
|
|||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.log.StdErrLog;
|
||||
import org.eclipse.jetty.util.thread.ShutdownThread;
|
||||
|
||||
/**
|
||||
|
@ -86,15 +87,6 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
|
|||
public MBeanContainer(MBeanServer server)
|
||||
{
|
||||
_server = server;
|
||||
|
||||
try
|
||||
{
|
||||
start();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.ignore(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009-2009 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
|
||||
package org.eclipse.jetty.util.log.jmx;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.jmx.ObjectMBean;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
*/
|
||||
public class LogMBean extends ObjectMBean
|
||||
{
|
||||
|
||||
public LogMBean(Object managedObject)
|
||||
{
|
||||
super(managedObject);
|
||||
}
|
||||
|
||||
public List<String> getLoggers()
|
||||
{
|
||||
List<String> keySet = new ArrayList<String>(Log.getLoggers().keySet());
|
||||
return keySet;
|
||||
}
|
||||
|
||||
public boolean isDebugEnabled(String logger)
|
||||
{
|
||||
return Log.getLogger(logger).isDebugEnabled();
|
||||
}
|
||||
|
||||
public void setDebugEnabled(String logger, Boolean enabled)
|
||||
{
|
||||
Log.getLogger(logger).setDebugEnabled(enabled);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
Log: Jetty Logging implementaton
|
||||
loggers:MBean: List of all instantiated loggers
|
||||
debugEnabled:RW: True if debug enabled for root logger Log.LOG
|
||||
isDebugEnabled(java.lang.String):MBean:INFO: True if debug is enabled for the given logger
|
||||
isDebugEnabled(java.lang.String)[0]:loggerName: Name of the logger to return isDebugEnabled for
|
||||
setDebugEnabled(java.lang.String,java.lang.Boolean):MBean:ACTION: Set debug enabled for the given logger
|
||||
setDebugEnabled(java.lang.String,java.lang.Boolean)[0]:loggerName: Name of the logger to set debug enabled
|
||||
setDebugEnabled(java.lang.String,java.lang.Boolean)[1]:enabled: true to enable debug, false otherwise
|
|
@ -1,3 +0,0 @@
|
|||
Logger: Jetty Logging implementaton
|
||||
debugEnabled: True if debug enabled
|
||||
name: Logger name
|
|
@ -1 +0,0 @@
|
|||
Slf4jLog: SL4J log adapter
|
|
@ -1 +0,0 @@
|
|||
StdErrLog: Log adapter that logs to stderr
|
|
@ -66,7 +66,6 @@
|
|||
<dependency>
|
||||
<groupId>javax.mail</groupId>
|
||||
<artifactId>mail</artifactId>
|
||||
<version>${javax-mail-version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>javax.activation</groupId>
|
||||
|
|
|
@ -457,10 +457,12 @@ public class localContextRoot implements Context
|
|||
{
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (final Exception e)
|
||||
{
|
||||
__log.warn("",e);
|
||||
throw new NamingException (e.getMessage());
|
||||
throw new NamingException (e.getMessage())
|
||||
{
|
||||
{ initCause(e);}
|
||||
};
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
ThreadMonitor: Detect and report spinning and deadlocked threads
|
||||
|
||||
|
|
|
@ -4,17 +4,15 @@
|
|||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
|
||||
package org.eclipse.jetty.monitor;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
@ -22,7 +20,6 @@ import java.lang.management.ManagementFactory;
|
|||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import javax.management.MBeanServer;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
@ -35,13 +32,12 @@ import org.eclipse.jetty.client.security.SimpleRealmResolver;
|
|||
import org.eclipse.jetty.http.HttpMethods;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.jmx.MBeanContainer;
|
||||
import org.eclipse.jetty.monitor.JMXMonitor;
|
||||
import org.eclipse.jetty.monitor.jmx.ConsoleNotifier;
|
||||
import org.eclipse.jetty.monitor.jmx.EventNotifier;
|
||||
import org.eclipse.jetty.monitor.jmx.EventState;
|
||||
import org.eclipse.jetty.monitor.jmx.EventState.TriggerState;
|
||||
import org.eclipse.jetty.monitor.jmx.EventTrigger;
|
||||
import org.eclipse.jetty.monitor.jmx.MonitorAction;
|
||||
import org.eclipse.jetty.monitor.jmx.EventState.TriggerState;
|
||||
import org.eclipse.jetty.monitor.triggers.AndEventTrigger;
|
||||
import org.eclipse.jetty.monitor.triggers.AttrEventTrigger;
|
||||
import org.eclipse.jetty.monitor.triggers.EqualToAttrEventTrigger;
|
||||
|
@ -61,6 +57,8 @@ import org.junit.After;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
|
@ -81,93 +79,93 @@ public class AttrEventTriggerTest
|
|||
File docRoot = new File("target/test-output/docroot/");
|
||||
docRoot.mkdirs();
|
||||
docRoot.deleteOnExit();
|
||||
|
||||
|
||||
System.setProperty("org.eclipse.jetty.util.log.DEBUG","");
|
||||
_server = new Server();
|
||||
|
||||
|
||||
SelectChannelConnector connector = new SelectChannelConnector();
|
||||
_server.addConnector(connector);
|
||||
|
||||
|
||||
_handler = new TestHandler();
|
||||
_server.setHandler(_handler);
|
||||
|
||||
|
||||
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
|
||||
MBeanContainer mBeanContainer = new MBeanContainer(mBeanServer);
|
||||
mBeanContainer.addBean(Log.getLog());
|
||||
|
||||
_counter = _handler.getRequestCounter();
|
||||
mBeanContainer.addBean(_counter);
|
||||
|
||||
_server.addBean(mBeanContainer);
|
||||
_server.getContainer().addEventListener(mBeanContainer);
|
||||
|
||||
_server.addBean(mBeanContainer, true);
|
||||
_server.getContainer().addEventListener(mBeanContainer);
|
||||
_server.start();
|
||||
|
||||
|
||||
startClient(null);
|
||||
|
||||
|
||||
_monitor = new JMXMonitor();
|
||||
|
||||
int port = _server.getConnectors()[0].getLocalPort();
|
||||
|
||||
int port = connector.getLocalPort();
|
||||
_requestUrl = "http://localhost:"+port+ "/";
|
||||
}
|
||||
|
||||
|
||||
@After
|
||||
public void tearDown()
|
||||
throws Exception
|
||||
{
|
||||
stopClient();
|
||||
|
||||
|
||||
if (_server != null)
|
||||
{
|
||||
_server.stop();
|
||||
_server = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testNoCondition()
|
||||
throws Exception
|
||||
{
|
||||
long requestCount = 10;
|
||||
|
||||
AttrEventTrigger<Long> trigger =
|
||||
|
||||
AttrEventTrigger<Long> trigger =
|
||||
new AttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter");
|
||||
|
||||
EventNotifier notifier = new ConsoleNotifier("%s");
|
||||
CounterAction action = new CounterAction(trigger, notifier, 500, 100);
|
||||
|
||||
|
||||
performTest(action, requestCount, 1000);
|
||||
|
||||
|
||||
ResultSet result = new ResultSet(1,requestCount);
|
||||
assertEquals(result, action.getHits());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testEqual_TRUE()
|
||||
throws Exception
|
||||
{
|
||||
long requestCount = 10;
|
||||
long testValue = 5;
|
||||
|
||||
EqualToAttrEventTrigger<Long> trigger =
|
||||
|
||||
EqualToAttrEventTrigger<Long> trigger =
|
||||
new EqualToAttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",testValue);
|
||||
|
||||
EventNotifier notifier = new ConsoleNotifier("%s");
|
||||
CounterAction action = new CounterAction(trigger, notifier, 500, 100);
|
||||
|
||||
performTest(action, requestCount, 1000);
|
||||
|
||||
|
||||
ResultSet result = new ResultSet(testValue);
|
||||
assertEquals(result, action.getHits());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testEqual_FALSE()
|
||||
throws Exception
|
||||
{
|
||||
long requestCount = 10;
|
||||
long testValue = 11;
|
||||
|
||||
EqualToAttrEventTrigger<Long> trigger =
|
||||
|
||||
EqualToAttrEventTrigger<Long> trigger =
|
||||
new EqualToAttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",
|
||||
testValue);
|
||||
|
||||
|
@ -175,19 +173,19 @@ public class AttrEventTriggerTest
|
|||
CounterAction action = new CounterAction(trigger, notifier, 500, 100);
|
||||
|
||||
performTest(action, requestCount, 1000);
|
||||
|
||||
|
||||
ResultSet result = new ResultSet();
|
||||
assertEquals(result, action.getHits());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLowerLimit()
|
||||
throws Exception
|
||||
{
|
||||
long requestCount = 10;
|
||||
long testRangeLow = 5;
|
||||
|
||||
GreaterThanAttrEventTrigger<Long> trigger =
|
||||
|
||||
GreaterThanAttrEventTrigger<Long> trigger =
|
||||
new GreaterThanAttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",
|
||||
testRangeLow);
|
||||
|
||||
|
@ -195,27 +193,27 @@ public class AttrEventTriggerTest
|
|||
CounterAction action = new CounterAction(trigger, notifier, 500, 100);
|
||||
|
||||
performTest(action, requestCount, 1000);
|
||||
|
||||
|
||||
ResultSet result = new ResultSet(6,10);
|
||||
assertEquals(result, action.getHits());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLowerLimitIncl()
|
||||
throws Exception
|
||||
{
|
||||
long requestCount = 10;
|
||||
long testRangeLow = 5;
|
||||
|
||||
GreaterThanOrEqualToAttrEventTrigger<Long> trigger =
|
||||
|
||||
GreaterThanOrEqualToAttrEventTrigger<Long> trigger =
|
||||
new GreaterThanOrEqualToAttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",
|
||||
testRangeLow);
|
||||
|
||||
|
||||
EventNotifier notifier = new ConsoleNotifier("%s");
|
||||
CounterAction action = new CounterAction(trigger, notifier, 500, 100);
|
||||
|
||||
|
||||
performTest(action, requestCount, 1000);
|
||||
|
||||
|
||||
ResultSet result = new ResultSet(5,10);
|
||||
assertEquals(result, action.getHits());
|
||||
}
|
||||
|
@ -226,8 +224,8 @@ public class AttrEventTriggerTest
|
|||
{
|
||||
long requestCount = 10;
|
||||
long testRangeHigh = 5;
|
||||
|
||||
LessThanAttrEventTrigger<Long> trigger =
|
||||
|
||||
LessThanAttrEventTrigger<Long> trigger =
|
||||
new LessThanAttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",
|
||||
testRangeHigh);
|
||||
|
||||
|
@ -235,11 +233,11 @@ public class AttrEventTriggerTest
|
|||
CounterAction action = new CounterAction(trigger, notifier, 500, 100);
|
||||
|
||||
performTest(action, requestCount, 1000);
|
||||
|
||||
|
||||
ResultSet result = new ResultSet(1,4);
|
||||
assertEquals(result, action.getHits());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testUpperLimitIncl()
|
||||
|
@ -247,8 +245,8 @@ public class AttrEventTriggerTest
|
|||
{
|
||||
long requestCount = 10;
|
||||
long testRangeHigh = 5;
|
||||
|
||||
LessThanOrEqualToAttrEventTrigger<Long> trigger =
|
||||
|
||||
LessThanOrEqualToAttrEventTrigger<Long> trigger =
|
||||
new LessThanOrEqualToAttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",
|
||||
testRangeHigh);
|
||||
|
||||
|
@ -256,11 +254,11 @@ public class AttrEventTriggerTest
|
|||
CounterAction action = new CounterAction(trigger, notifier, 500, 100);
|
||||
|
||||
performTest(action, requestCount, 1000);
|
||||
|
||||
|
||||
ResultSet result = new ResultSet(1,5);
|
||||
assertEquals(result, action.getHits());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRangeInclusive()
|
||||
throws Exception
|
||||
|
@ -268,20 +266,20 @@ public class AttrEventTriggerTest
|
|||
long requestCount = 10;
|
||||
long testRangeLow = 3;
|
||||
long testRangeHigh = 8;
|
||||
|
||||
RangeInclAttrEventTrigger<Long> trigger =
|
||||
|
||||
RangeInclAttrEventTrigger<Long> trigger =
|
||||
new RangeInclAttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",
|
||||
testRangeLow, testRangeHigh);
|
||||
|
||||
|
||||
EventNotifier notifier = new ConsoleNotifier("%s");
|
||||
CounterAction action = new CounterAction(trigger, notifier, 500, 100);
|
||||
|
||||
|
||||
performTest(action, requestCount, 1000);
|
||||
|
||||
|
||||
ResultSet result = new ResultSet(testRangeLow,testRangeHigh);
|
||||
assertEquals(result, action.getHits());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testInsideRangeExclusive()
|
||||
throws Exception
|
||||
|
@ -289,20 +287,20 @@ public class AttrEventTriggerTest
|
|||
long requestCount = 10;
|
||||
long testRangeLow = 3;
|
||||
long testRangeHigh = 8;
|
||||
|
||||
RangeAttrEventTrigger<Long> trigger =
|
||||
|
||||
RangeAttrEventTrigger<Long> trigger =
|
||||
new RangeAttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",
|
||||
testRangeLow, testRangeHigh);
|
||||
|
||||
|
||||
EventNotifier notifier = new ConsoleNotifier("%s");
|
||||
CounterAction action = new CounterAction(trigger, notifier, 500, 100);
|
||||
|
||||
|
||||
performTest(action, requestCount, 1000);
|
||||
|
||||
|
||||
ResultSet result = new ResultSet(testRangeLow+1,testRangeHigh-1);
|
||||
assertEquals(result, action.getHits());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRangeComposite()
|
||||
throws Exception
|
||||
|
@ -310,23 +308,23 @@ public class AttrEventTriggerTest
|
|||
long requestCount = 10;
|
||||
long testRangeLow = 4;
|
||||
long testRangeHigh = 7;
|
||||
|
||||
GreaterThanAttrEventTrigger<Long> trigger1 =
|
||||
|
||||
GreaterThanAttrEventTrigger<Long> trigger1 =
|
||||
new GreaterThanAttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",
|
||||
testRangeLow);
|
||||
LessThanOrEqualToAttrEventTrigger<Long> trigger2 =
|
||||
LessThanOrEqualToAttrEventTrigger<Long> trigger2 =
|
||||
new LessThanOrEqualToAttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",
|
||||
testRangeHigh);
|
||||
AndEventTrigger trigger = new AndEventTrigger(trigger1, trigger2);
|
||||
EventNotifier notifier = new ConsoleNotifier("%s");
|
||||
CounterAction action = new CounterAction(trigger, notifier, 500, 100);
|
||||
|
||||
|
||||
performTest(action, requestCount, 1000);
|
||||
|
||||
|
||||
ResultSet result = new ResultSet(testRangeLow+1,testRangeHigh);
|
||||
assertEquals(result, action.getHits());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRangeOuter()
|
||||
throws Exception
|
||||
|
@ -334,23 +332,23 @@ public class AttrEventTriggerTest
|
|||
long requestCount = 10;
|
||||
long testRangeLow = 4;
|
||||
long testRangeHigh = 7;
|
||||
|
||||
LessThanOrEqualToAttrEventTrigger<Long> trigger1 =
|
||||
|
||||
LessThanOrEqualToAttrEventTrigger<Long> trigger1 =
|
||||
new LessThanOrEqualToAttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",
|
||||
testRangeLow);
|
||||
GreaterThanAttrEventTrigger<Long> trigger2 =
|
||||
GreaterThanAttrEventTrigger<Long> trigger2 =
|
||||
new GreaterThanAttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",
|
||||
testRangeHigh);
|
||||
OrEventTrigger trigger = new OrEventTrigger(trigger1, trigger2);
|
||||
EventNotifier notifier = new ConsoleNotifier("%s");
|
||||
CounterAction action = new CounterAction(trigger, notifier, 500, 100);
|
||||
|
||||
|
||||
performTest(action, requestCount, 1000);
|
||||
|
||||
|
||||
ResultSet result = new ResultSet(1,testRangeLow,testRangeHigh+1, requestCount);
|
||||
assertEquals(result, action.getHits());
|
||||
}
|
||||
|
||||
|
||||
protected void performTest(MonitorAction action, long count, long interval)
|
||||
throws Exception
|
||||
{
|
||||
|
@ -363,17 +361,17 @@ public class AttrEventTriggerTest
|
|||
ContentExchange getExchange = new ContentExchange();
|
||||
getExchange.setURL(_requestUrl);
|
||||
getExchange.setMethod(HttpMethods.GET);
|
||||
|
||||
|
||||
_client.send(getExchange);
|
||||
int state = getExchange.waitForDone();
|
||||
|
||||
|
||||
String content = "";
|
||||
int responseStatus = getExchange.getResponseStatus();
|
||||
if (responseStatus == HttpStatus.OK_200)
|
||||
{
|
||||
content = getExchange.getResponseContent();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
assertEquals(HttpStatus.OK_200,responseStatus);
|
||||
Thread.sleep(interval);
|
||||
}
|
||||
|
@ -382,12 +380,12 @@ public class AttrEventTriggerTest
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Thread.sleep(interval);
|
||||
|
||||
_monitor.removeActions(action);
|
||||
}
|
||||
|
||||
|
||||
protected void startClient(Realm realm)
|
||||
throws Exception
|
||||
{
|
||||
|
@ -397,7 +395,7 @@ public class AttrEventTriggerTest
|
|||
_client.setRealmResolver(new SimpleRealmResolver(realm));
|
||||
_client.start();
|
||||
}
|
||||
|
||||
|
||||
protected void stopClient()
|
||||
throws Exception
|
||||
{
|
||||
|
@ -412,7 +410,7 @@ public class AttrEventTriggerTest
|
|||
extends AbstractHandler
|
||||
{
|
||||
private RequestCounter _counter = new RequestCounter();
|
||||
|
||||
|
||||
public void handle(String target, Request baseRequest,
|
||||
HttpServletRequest request, HttpServletResponse response)
|
||||
throws IOException, ServletException
|
||||
|
@ -421,40 +419,40 @@ public class AttrEventTriggerTest
|
|||
return;
|
||||
}
|
||||
_counter.increment();
|
||||
|
||||
|
||||
response.setContentType("text/plain");
|
||||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
PrintWriter writer = response.getWriter();
|
||||
writer.println("===TEST RESPONSE===");
|
||||
baseRequest.setHandled(true);
|
||||
}
|
||||
|
||||
|
||||
public RequestCounter getRequestCounter()
|
||||
{
|
||||
return _counter;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected static class ResultSet extends TreeSet<Long>
|
||||
{
|
||||
{
|
||||
public ResultSet() {}
|
||||
|
||||
|
||||
public ResultSet(long value)
|
||||
{
|
||||
add(value);
|
||||
}
|
||||
|
||||
|
||||
public ResultSet(long start, long end)
|
||||
{
|
||||
addEntries(start, end);
|
||||
}
|
||||
|
||||
|
||||
public ResultSet(long start, long pause, long resume, long end)
|
||||
{
|
||||
addEntries(start, pause);
|
||||
addEntries(resume, end);
|
||||
}
|
||||
|
||||
|
||||
public void addEntries(long start, long stop)
|
||||
{
|
||||
if (start > 0 && stop > 0)
|
||||
|
@ -471,23 +469,23 @@ public class AttrEventTriggerTest
|
|||
return (this.size() == set.size()) && containsAll(set);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected static class CounterAction
|
||||
extends MonitorAction
|
||||
{
|
||||
private ResultSet _hits = new ResultSet();
|
||||
|
||||
|
||||
public CounterAction(EventTrigger trigger, EventNotifier notifier, long interval, long delay)
|
||||
{
|
||||
super(trigger, notifier, interval, delay);
|
||||
}
|
||||
|
||||
|
||||
public void execute(EventTrigger trigger, EventState<?> state, long timestamp)
|
||||
{
|
||||
if (trigger != null && state != null)
|
||||
{
|
||||
Collection<?> values = state.values();
|
||||
|
||||
|
||||
Iterator<?> it = values.iterator();
|
||||
while(it.hasNext())
|
||||
{
|
||||
|
@ -500,7 +498,7 @@ public class AttrEventTriggerTest
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public ResultSet getHits()
|
||||
{
|
||||
return _hits;
|
||||
|
|
|
@ -68,7 +68,6 @@
|
|||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit4-version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
|
|
@ -79,7 +79,7 @@ public class NoSqlSession extends AbstractSession
|
|||
__log.debug("NoSqlSession:access:active "+_active);
|
||||
if (_active.incrementAndGet()==1)
|
||||
{
|
||||
int period=_manager.getStalePeriod()*1000;
|
||||
long period=_manager.getStalePeriod()*1000L;
|
||||
if (period==0)
|
||||
refresh();
|
||||
else if (period>0)
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-boot-jsp</artifactId>
|
||||
<name>Jetty :: OSGi :: Boot JSP</name>
|
||||
<description>Jetty OSGi Boot JSP bundle</description>
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-boot-logback</artifactId>
|
||||
<name>Jetty :: OSGi :: Boot Logback</name>
|
||||
<description>Jetty OSGi Boot Logback bundle</description>
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-boot-warurl</artifactId>
|
||||
<name>Jetty :: OSGi :: Boot :: Warurl</name>
|
||||
<description>Jetty OSGi Boot-Warurl bundle</description>
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-boot</artifactId>
|
||||
<name>Jetty :: OSGi :: Boot</name>
|
||||
<description>Jetty OSGi Boot bundle</description>
|
||||
|
|
|
@ -10,27 +10,20 @@
|
|||
<name>Jetty :: OSGi :: Example Equinox Tools</name>
|
||||
<description>Jetty OSGi Example Equinox Tools</description>
|
||||
<properties>
|
||||
<forceContextQualifier>v20110513</forceContextQualifier>
|
||||
<jetty-version>7.4.1.v20110513</jetty-version>
|
||||
<osgi-version>3.6.0.v20100517</osgi-version>
|
||||
<osgi-services-version>3.2.100.v20100503</osgi-services-version>
|
||||
<bundle-symbolic-name>${project.groupId}.equinoxtools</bundle-symbolic-name>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-webapp</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-continuation</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-websocket</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
|
@ -39,12 +32,10 @@
|
|||
<dependency>
|
||||
<groupId>org.eclipse.osgi</groupId>
|
||||
<artifactId>org.eclipse.osgi</artifactId>
|
||||
<version>${osgi-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.osgi</groupId>
|
||||
<artifactId>org.eclipse.osgi.services</artifactId>
|
||||
<version>${osgi-services-version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-httpservice</artifactId>
|
||||
<name>Jetty :: OSGi :: HttpService</name>
|
||||
<description>Jetty OSGi HttpService bundle</description>
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>test-jetty-osgi</artifactId>
|
||||
<name>Jetty :: OSGi :: Test</name>
|
||||
<description>Jetty OSGi Integration test</description>
|
||||
|
@ -49,13 +48,11 @@
|
|||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-webapp</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-deploy</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -67,7 +64,6 @@
|
|||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlet</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -79,13 +75,11 @@
|
|||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-jmx</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-util</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -97,7 +91,6 @@
|
|||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-websocket</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<!-- can't use javax.servlet:servlet-api:2.5 it is not a bundle.
|
||||
|
@ -112,13 +105,11 @@
|
|||
<dependency>
|
||||
<groupId>org.eclipse.osgi</groupId>
|
||||
<artifactId>org.eclipse.osgi</artifactId>
|
||||
<version>${osgi-version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.osgi</groupId>
|
||||
<artifactId>org.eclipse.osgi.services</artifactId>
|
||||
<version>${osgi-services-version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -129,7 +120,6 @@
|
|||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlets</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
|
@ -192,7 +182,6 @@
|
|||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<version>1.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>generate-resources</phase>
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-policy</artifactId>
|
||||
<name>Jetty :: Policy Tool</name>
|
||||
<packaging>jar</packaging>
|
||||
|
|
|
@ -55,7 +55,7 @@ public class ProxyRule extends PatternRule
|
|||
private String _hostHeader;
|
||||
private String _proxyTo;
|
||||
|
||||
private int _connectorType = 2;
|
||||
private int _connectorType = HttpClient.CONNECTOR_SELECT_CHANNEL;
|
||||
private String _maxThreads;
|
||||
private String _maxConnections;
|
||||
private String _timeout;
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
package org.eclipse.jetty.rewrite.handler;
|
||||
|
||||
//========================================================================
|
||||
//Copyright (c) 2006-2009 Mort Bay Consulting Pty. Ltd.
|
||||
//------------------------------------------------------------------------
|
||||
|
@ -12,12 +10,10 @@ package org.eclipse.jetty.rewrite.handler;
|
|||
//http://www.opensource.org/licenses/apache2.0.php
|
||||
//You may elect to redistribute this code under either of these licenses.
|
||||
//========================================================================
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
package org.eclipse.jetty.rewrite.handler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
@ -35,6 +31,8 @@ import org.junit.AfterClass;
|
|||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class ProxyRuleTest
|
||||
{
|
||||
private static ProxyRule _rule;
|
||||
|
|
|
@ -318,13 +318,11 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti
|
|||
if (!_loginServiceShared && _loginService instanceof LifeCycle)
|
||||
((LifeCycle)_loginService).start();
|
||||
|
||||
System.err.println("authenticator="+_authenticator+" authenticatorFactory="+_authenticatorFactory+" identityService="+_identityService);
|
||||
if (_authenticator==null && _authenticatorFactory!=null && _identityService!=null)
|
||||
{
|
||||
_authenticator=_authenticatorFactory.getAuthenticator(getServer(),ContextHandler.getCurrentContext(),this, _identityService, _loginService);
|
||||
if (_authenticator!=null)
|
||||
_authMethod=_authenticator.getAuthMethod();
|
||||
System.err.println("Called auth factory, authenticator="+_authenticator);
|
||||
}
|
||||
|
||||
if (_authenticator==null)
|
||||
|
@ -479,7 +477,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti
|
|||
deferred.setIdentityService(_identityService);
|
||||
deferred.setLoginService(_loginService);
|
||||
baseRequest.setAuthentication(authentication);
|
||||
System.err.println("uri="+baseRequest.getUri()+" Auth is deferred");
|
||||
|
||||
try
|
||||
{
|
||||
handler.handle(pathInContext, baseRequest, request, response);
|
||||
|
@ -489,7 +487,7 @@ System.err.println("uri="+baseRequest.getUri()+" Auth is deferred");
|
|||
previousIdentity = deferred.getPreviousAssociation();
|
||||
deferred.setIdentityService(null);
|
||||
}
|
||||
System.err.println("Securityhandler calling secureResponse, for Authentication.User");
|
||||
|
||||
Authentication auth=baseRequest.getAuthentication();
|
||||
if (auth instanceof Authentication.User)
|
||||
{
|
||||
|
|
|
@ -835,11 +835,7 @@ public class ConstraintTest
|
|||
assertTrue(response.startsWith("HTTP/1.1 200 "));
|
||||
|
||||
response = _connector.getResponses("GET /ctx/forbid/post HTTP/1.0\r\n\r\n");
|
||||
System.err.println(response);
|
||||
assertTrue(response.startsWith("HTTP/1.1 200 ")); // This is so stupid, but it is the S P E C
|
||||
|
||||
|
||||
|
||||
}
|
||||
private class RequestHandler extends AbstractHandler
|
||||
{
|
||||
|
|
|
@ -110,7 +110,6 @@
|
|||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>1.8.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
|
|
@ -18,20 +18,21 @@ import java.net.InetAddress;
|
|||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
|
||||
import org.eclipse.jetty.http.HttpBuffers;
|
||||
import org.eclipse.jetty.http.HttpBuffersImpl;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpHeaders;
|
||||
import org.eclipse.jetty.http.HttpSchemes;
|
||||
import org.eclipse.jetty.io.Buffers;
|
||||
import org.eclipse.jetty.io.Buffers.Type;
|
||||
import org.eclipse.jetty.io.Connection;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.io.EofException;
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.util.component.AggregateLifeCycle;
|
||||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.statistic.CounterStatistic;
|
||||
|
@ -51,7 +52,7 @@ import org.eclipse.jetty.util.thread.ThreadPool;
|
|||
*
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractConnector extends HttpBuffers implements Connector, Dumpable
|
||||
public abstract class AbstractConnector extends AggregateLifeCycle implements HttpBuffers, Connector, Dumpable
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(AbstractConnector.class);
|
||||
|
||||
|
@ -84,7 +85,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
|
|||
protected int _lowResourceMaxIdleTime = -1;
|
||||
protected int _soLingerTime = -1;
|
||||
|
||||
private transient Thread[] _acceptorThread;
|
||||
private transient Thread[] _acceptorThreads;
|
||||
|
||||
private final AtomicLong _statsStartedAt = new AtomicLong(-1L);
|
||||
|
||||
|
@ -95,11 +96,14 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
|
|||
/** duration of a connection */
|
||||
private final SampleStatistic _connectionDurationStats = new SampleStatistic();
|
||||
|
||||
protected final HttpBuffersImpl _buffers = new HttpBuffersImpl();
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
*/
|
||||
public AbstractConnector()
|
||||
{
|
||||
addBean(_buffers);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -123,9 +127,16 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
|
|||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Set the ThreadPool.
|
||||
* The threadpool passed is added via {@link #addBean(Object)} so that
|
||||
* it's lifecycle may be managed as a {@link AggregateLifeCycle}.
|
||||
* @param threadPool the threadPool to set
|
||||
*/
|
||||
public void setThreadPool(ThreadPool pool)
|
||||
{
|
||||
removeBean(_threadPool);
|
||||
_threadPool = pool;
|
||||
addBean(_threadPool);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -299,20 +310,22 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
|
|||
// open listener port
|
||||
open();
|
||||
|
||||
super.doStart();
|
||||
|
||||
if (_threadPool == null)
|
||||
{
|
||||
_threadPool = _server.getThreadPool();
|
||||
if (_threadPool != _server.getThreadPool() && (_threadPool instanceof LifeCycle))
|
||||
((LifeCycle)_threadPool).start();
|
||||
addBean(_threadPool,false);
|
||||
}
|
||||
|
||||
super.doStart();
|
||||
|
||||
// Start selector thread
|
||||
synchronized (this)
|
||||
{
|
||||
_acceptorThread = new Thread[getAcceptors()];
|
||||
_acceptorThreads = new Thread[getAcceptors()];
|
||||
|
||||
for (int i = 0; i < _acceptorThread.length; i++)
|
||||
_threadPool.dispatch(new Acceptor(i));
|
||||
for (int i = 0; i < _acceptorThreads.length; i++)
|
||||
if (!_threadPool.dispatch(new Acceptor(i)))
|
||||
throw new IllegalStateException("!accepting");
|
||||
if (_threadPool.isLowOnThreads())
|
||||
LOG.warn("insufficient threads configured for {}",this);
|
||||
}
|
||||
|
@ -333,22 +346,18 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
|
|||
LOG.warn(e);
|
||||
}
|
||||
|
||||
if (_threadPool != _server.getThreadPool() && _threadPool instanceof LifeCycle)
|
||||
((LifeCycle)_threadPool).stop();
|
||||
|
||||
super.doStop();
|
||||
|
||||
Thread[] acceptors = null;
|
||||
Thread[] acceptors;
|
||||
synchronized (this)
|
||||
{
|
||||
acceptors = _acceptorThread;
|
||||
_acceptorThread = null;
|
||||
acceptors = _acceptorThreads;
|
||||
_acceptorThreads = null;
|
||||
}
|
||||
if (acceptors != null)
|
||||
{
|
||||
for (int i = 0; i < acceptors.length; i++)
|
||||
for (Thread thread : acceptors)
|
||||
{
|
||||
Thread thread = acceptors[i];
|
||||
if (thread != null)
|
||||
thread.interrupt();
|
||||
}
|
||||
|
@ -361,12 +370,12 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
|
|||
Thread[] threads;
|
||||
synchronized(this)
|
||||
{
|
||||
threads= _acceptorThread;
|
||||
threads=_acceptorThreads;
|
||||
}
|
||||
if (threads != null)
|
||||
for (int i = 0; i < threads.length; i++)
|
||||
if (threads[i] != null)
|
||||
threads[i].join();
|
||||
for (Thread thread : threads)
|
||||
if (thread != null)
|
||||
thread.join();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -786,17 +795,105 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
|
|||
_forwardedSslSessionIdHeader = forwardedSslSessionId;
|
||||
}
|
||||
|
||||
public int getRequestBufferSize()
|
||||
{
|
||||
return _buffers.getRequestBufferSize();
|
||||
}
|
||||
|
||||
public void setRequestBufferSize(int requestBufferSize)
|
||||
{
|
||||
_buffers.setRequestBufferSize(requestBufferSize);
|
||||
}
|
||||
|
||||
public int getRequestHeaderSize()
|
||||
{
|
||||
return _buffers.getRequestHeaderSize();
|
||||
}
|
||||
|
||||
public void setRequestHeaderSize(int requestHeaderSize)
|
||||
{
|
||||
_buffers.setRequestHeaderSize(requestHeaderSize);
|
||||
}
|
||||
|
||||
public int getResponseBufferSize()
|
||||
{
|
||||
return _buffers.getResponseBufferSize();
|
||||
}
|
||||
|
||||
public void setResponseBufferSize(int responseBufferSize)
|
||||
{
|
||||
_buffers.setResponseBufferSize(responseBufferSize);
|
||||
}
|
||||
|
||||
public int getResponseHeaderSize()
|
||||
{
|
||||
return _buffers.getResponseHeaderSize();
|
||||
}
|
||||
|
||||
public void setResponseHeaderSize(int responseHeaderSize)
|
||||
{
|
||||
_buffers.setResponseHeaderSize(responseHeaderSize);
|
||||
}
|
||||
|
||||
public Type getRequestBufferType()
|
||||
{
|
||||
return _buffers.getRequestBufferType();
|
||||
}
|
||||
|
||||
public Type getRequestHeaderType()
|
||||
{
|
||||
return _buffers.getRequestHeaderType();
|
||||
}
|
||||
|
||||
public Type getResponseBufferType()
|
||||
{
|
||||
return _buffers.getResponseBufferType();
|
||||
}
|
||||
|
||||
public Type getResponseHeaderType()
|
||||
{
|
||||
return _buffers.getResponseHeaderType();
|
||||
}
|
||||
|
||||
public void setRequestBuffers(Buffers requestBuffers)
|
||||
{
|
||||
_buffers.setRequestBuffers(requestBuffers);
|
||||
}
|
||||
|
||||
public void setResponseBuffers(Buffers responseBuffers)
|
||||
{
|
||||
_buffers.setResponseBuffers(responseBuffers);
|
||||
}
|
||||
|
||||
public Buffers getRequestBuffers()
|
||||
{
|
||||
return _buffers.getRequestBuffers();
|
||||
}
|
||||
|
||||
public Buffers getResponseBuffers()
|
||||
{
|
||||
return _buffers.getResponseBuffers();
|
||||
}
|
||||
|
||||
public void setMaxBuffers(int maxBuffers)
|
||||
{
|
||||
_buffers.setMaxBuffers(maxBuffers);
|
||||
}
|
||||
|
||||
public int getMaxBuffers()
|
||||
{
|
||||
return _buffers.getMaxBuffers();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
String name = this.getClass().getName();
|
||||
int dot = name.lastIndexOf('.');
|
||||
if (dot > 0)
|
||||
name = name.substring(dot + 1);
|
||||
|
||||
return name + "@" + (getHost() == null?"0.0.0.0":getHost()) + ":" + (getLocalPort() <= 0?getPort():getLocalPort()) + " "
|
||||
+ AbstractLifeCycle.getState(this);
|
||||
return String.format("%s@%s:%d %s",
|
||||
getClass().getSimpleName(),
|
||||
getHost()==null?"0.0.0.0":getHost(),
|
||||
getLocalPort()<=0?getPort():getLocalPort(),
|
||||
AbstractLifeCycle.getState(this));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -818,11 +915,11 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
|
|||
String name;
|
||||
synchronized (AbstractConnector.this)
|
||||
{
|
||||
if (_acceptorThread == null)
|
||||
if (_acceptorThreads == null)
|
||||
return;
|
||||
|
||||
_acceptorThread[_acceptor] = current;
|
||||
name = _acceptorThread[_acceptor].getName();
|
||||
_acceptorThreads[_acceptor] = current;
|
||||
name = _acceptorThreads[_acceptor].getName();
|
||||
current.setName(name + " Acceptor" + _acceptor + " " + AbstractConnector.this);
|
||||
}
|
||||
int old_priority = current.getPriority();
|
||||
|
@ -862,8 +959,8 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
|
|||
|
||||
synchronized (AbstractConnector.this)
|
||||
{
|
||||
if (_acceptorThread != null)
|
||||
_acceptorThread[_acceptor] = null;
|
||||
if (_acceptorThreads != null)
|
||||
_acceptorThreads[_acceptor] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1118,17 +1215,4 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
|
|||
oldValue = valueHolder.get();
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public String dump()
|
||||
{
|
||||
return AggregateLifeCycle.dump(this);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
out.append(String.valueOf(this)).append("\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -185,9 +185,6 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* (non-Javadoc)
|
||||
* @see javax.servlet.ServletRequest#isSuspended()
|
||||
*/
|
||||
public boolean isSuspending()
|
||||
{
|
||||
synchronized(this)
|
||||
|
|
|
@ -45,6 +45,7 @@ public class AsyncHttpConnection extends AbstractHttpConnection implements Async
|
|||
_asyncEndp=(AsyncEndPoint)endpoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection handle() throws IOException
|
||||
{
|
||||
Connection connection = this;
|
||||
|
@ -54,10 +55,10 @@ public class AsyncHttpConnection extends AbstractHttpConnection implements Async
|
|||
try
|
||||
{
|
||||
setCurrentConnection(this);
|
||||
|
||||
|
||||
// don't check for idle while dispatched (unless blocking IO is done).
|
||||
_asyncEndp.setCheckForIdle(false);
|
||||
|
||||
|
||||
|
||||
// While progress and the connection has not changed
|
||||
while (progress && connection==this)
|
||||
|
@ -67,7 +68,7 @@ public class AsyncHttpConnection extends AbstractHttpConnection implements Async
|
|||
{
|
||||
// Handle resumed request
|
||||
if (_request._async.isAsync())
|
||||
{
|
||||
{
|
||||
if (_request._async.isDispatchable())
|
||||
handleRequest();
|
||||
}
|
||||
|
@ -126,10 +127,10 @@ public class AsyncHttpConnection extends AbstractHttpConnection implements Async
|
|||
}
|
||||
else if (_request.getAsyncContinuation().isAsyncStarted())
|
||||
{
|
||||
// The request is suspended, so even though progress has been made, break the while loop
|
||||
// The request is suspended, so even though progress has been made,
|
||||
// exit the while loop by setting progress to false
|
||||
LOG.debug("suspended {}",this);
|
||||
// TODO: breaking inside finally blocks is bad: rethink how we should exit from here
|
||||
break;
|
||||
progress=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -137,20 +138,18 @@ public class AsyncHttpConnection extends AbstractHttpConnection implements Async
|
|||
finally
|
||||
{
|
||||
setCurrentConnection(null);
|
||||
|
||||
|
||||
// If we are not suspended
|
||||
if (!_request.getAsyncContinuation().isAsyncStarted())
|
||||
{
|
||||
// return buffers
|
||||
_parser.returnBuffers();
|
||||
_generator.returnBuffers();
|
||||
}
|
||||
|
||||
if (_request.getAsyncContinuation().isComplete() || _request.getAsyncContinuation().isInitial())
|
||||
{
|
||||
|
||||
// reenable idle checking unless request is suspended
|
||||
_asyncEndp.setCheckForIdle(true);
|
||||
}
|
||||
|
||||
|
||||
// Safety net to catch spinning
|
||||
if (some_progress)
|
||||
_total_no_progress=0;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -466,7 +466,6 @@ public class Response implements HttpServletResponse
|
|||
}
|
||||
}
|
||||
|
||||
location=encodeRedirectURL(location);
|
||||
resetBuffer();
|
||||
setHeader(HttpHeaders.LOCATION,location);
|
||||
setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
|
||||
|
|
|
@ -75,7 +75,10 @@ import org.eclipse.jetty.util.resource.Resource;
|
|||
* <p>
|
||||
* If the context init parameter "org.eclipse.jetty.server.context.ManagedAttributes" is set to a comma separated list of names, then they are treated as
|
||||
* context attribute names, which if set as attributes are passed to the servers Container so that they may be managed with JMX.
|
||||
*
|
||||
* <p>
|
||||
* The maximum size of a form that can be processed by this context is controlled by the system properties org.eclipse.jetty.server.Request.maxFormKeys
|
||||
* and org.eclipse.jetty.server.Request.maxFormContentSize. These can also be configured with {@link #setMaxFormContentSize(int)} and {@link #setMaxFormKeys(int)}
|
||||
*
|
||||
* @org.apache.xbean.XBean description="Creates a basic HTTP context"
|
||||
*/
|
||||
public class ContextHandler extends ScopedHandler implements Attributes, Server.Graceful
|
||||
|
|
|
@ -50,7 +50,7 @@ public class DefaultHandler extends AbstractHandler
|
|||
{
|
||||
private static final Logger LOG = Log.getLogger(DefaultHandler.class);
|
||||
|
||||
final long _faviconModified=(System.currentTimeMillis()/1000)*1000;
|
||||
final long _faviconModified=(System.currentTimeMillis()/1000)*1000L;
|
||||
byte[] _favicon;
|
||||
boolean _serveIcon=true;
|
||||
boolean _showContexts=true;
|
||||
|
|
|
@ -4,35 +4,31 @@
|
|||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
package org.eclipse.jetty.server.nio;
|
||||
|
||||
import org.eclipse.jetty.io.Buffers.Type;
|
||||
import org.eclipse.jetty.server.AbstractConnector;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractNIOConnector extends AbstractConnector implements NIOConnector
|
||||
{
|
||||
public AbstractNIOConnector()
|
||||
{
|
||||
setRequestBufferType(Type.DIRECT);
|
||||
setRequestHeaderType(Type.INDIRECT);
|
||||
setResponseBufferType(Type.DIRECT);
|
||||
setResponseHeaderType(Type.INDIRECT);
|
||||
_buffers.setRequestBufferType(Type.DIRECT);
|
||||
_buffers.setRequestHeaderType(Type.INDIRECT);
|
||||
_buffers.setResponseBufferType(Type.DIRECT);
|
||||
_buffers.setResponseHeaderType(Type.INDIRECT);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
public boolean getUseDirectBuffers()
|
||||
{
|
||||
|
@ -46,8 +42,7 @@ public abstract class AbstractNIOConnector extends AbstractConnector implements
|
|||
*/
|
||||
public void setUseDirectBuffers(boolean direct)
|
||||
{
|
||||
setRequestBufferType(direct?Type.DIRECT:Type.INDIRECT);
|
||||
setResponseBufferType(direct?Type.DIRECT:Type.INDIRECT);
|
||||
_buffers.setRequestBufferType(direct?Type.DIRECT:Type.INDIRECT);
|
||||
_buffers.setResponseBufferType(direct?Type.DIRECT:Type.INDIRECT);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ import java.net.Socket;
|
|||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.ServerSocketChannel;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.eclipse.jetty.continuation.Continuation;
|
||||
import org.eclipse.jetty.io.AsyncEndPoint;
|
||||
|
@ -32,9 +31,6 @@ import org.eclipse.jetty.io.nio.SelectorManager;
|
|||
import org.eclipse.jetty.io.nio.SelectorManager.SelectSet;
|
||||
import org.eclipse.jetty.server.AsyncHttpConnection;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.util.component.AggregateLifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.thread.ThreadPool;
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
|
@ -65,8 +61,6 @@ import org.eclipse.jetty.util.thread.ThreadPool;
|
|||
*/
|
||||
public class SelectChannelConnector extends AbstractNIOConnector
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(SelectChannelConnector.class);
|
||||
|
||||
protected ServerSocketChannel _acceptChannel;
|
||||
private int _lowResourcesConnections;
|
||||
private int _lowResourcesMaxIdleTime;
|
||||
|
@ -82,6 +76,7 @@ public class SelectChannelConnector extends AbstractNIOConnector
|
|||
public SelectChannelConnector()
|
||||
{
|
||||
_manager.setMaxIdleTime(getMaxIdleTime());
|
||||
addBean(_manager,true);
|
||||
setAcceptors(Math.max(1,(Runtime.getRuntime().availableProcessors()+3)/4));
|
||||
}
|
||||
|
||||
|
@ -111,7 +106,11 @@ public class SelectChannelConnector extends AbstractNIOConnector
|
|||
synchronized(this)
|
||||
{
|
||||
if (_acceptChannel != null)
|
||||
_acceptChannel.close();
|
||||
{
|
||||
removeBean(_acceptChannel);
|
||||
if (_acceptChannel.isOpen())
|
||||
_acceptChannel.close();
|
||||
}
|
||||
_acceptChannel = null;
|
||||
_localPort=-2;
|
||||
}
|
||||
|
@ -121,7 +120,6 @@ public class SelectChannelConnector extends AbstractNIOConnector
|
|||
@Override
|
||||
public void customize(EndPoint endpoint, Request request) throws IOException
|
||||
{
|
||||
AsyncEndPoint aEndp = ((AsyncEndPoint)endpoint);
|
||||
request.setTimeStamp(System.currentTimeMillis());
|
||||
endpoint.setMaxIdleTime(_maxIdleTime);
|
||||
super.customize(endpoint, request);
|
||||
|
@ -178,6 +176,7 @@ public class SelectChannelConnector extends AbstractNIOConnector
|
|||
if (_localPort<=0)
|
||||
throw new IOException("Server channel not bound");
|
||||
|
||||
addBean(_acceptChannel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -250,31 +249,6 @@ public class SelectChannelConnector extends AbstractNIOConnector
|
|||
_manager.setLowResourcesMaxIdleTime(getLowResourcesMaxIdleTime());
|
||||
|
||||
super.doStart();
|
||||
_manager.start();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
* @see org.eclipse.jetty.server.server.AbstractConnector#doStop()
|
||||
*/
|
||||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
synchronized(this)
|
||||
{
|
||||
if(_manager.isRunning())
|
||||
{
|
||||
try
|
||||
{
|
||||
_manager.stop();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
super.doStop();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -297,20 +271,6 @@ public class SelectChannelConnector extends AbstractNIOConnector
|
|||
return new AsyncHttpConnection(SelectChannelConnector.this,endpoint,getServer());
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
super.dump(out, indent);
|
||||
ServerSocketChannel channel;
|
||||
synchronized (this)
|
||||
{
|
||||
channel=_acceptChannel;
|
||||
}
|
||||
if (channel==null)
|
||||
AggregateLifeCycle.dump(out,indent,Arrays.asList(null,"CLOSED",_manager));
|
||||
else
|
||||
AggregateLifeCycle.dump(out,indent,Arrays.asList(channel,channel.isOpen()?"OPEN":"CLOSED",_manager));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -357,5 +317,4 @@ public class SelectChannelConnector extends AbstractNIOConnector
|
|||
return SelectChannelConnector.this.newEndPoint(channel,selectSet,sKey);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ public abstract class AbstractSession implements AbstractSessionManager.SessionI
|
|||
_accessed=_created;
|
||||
_lastAccessed=_created;
|
||||
_requests=1;
|
||||
_maxIdleMs=_manager._dftMaxIdleSecs>0?_manager._dftMaxIdleSecs*1000:-1;
|
||||
_maxIdleMs=_manager._dftMaxIdleSecs>0?_manager._dftMaxIdleSecs*1000L:-1;
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("new session & id "+_nodeId+" "+_clusterId);
|
||||
}
|
||||
|
@ -430,7 +430,7 @@ public abstract class AbstractSession implements AbstractSessionManager.SessionI
|
|||
/* ------------------------------------------------------------- */
|
||||
public void setMaxInactiveInterval(int secs)
|
||||
{
|
||||
_maxIdleMs=(long)secs*1000;
|
||||
_maxIdleMs=(long)secs*1000L;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
|
|
@ -53,9 +53,9 @@ public class HashSessionManager extends AbstractSessionManager
|
|||
private Timer _timer;
|
||||
private boolean _timerStop=false;
|
||||
private TimerTask _task;
|
||||
int _scavengePeriodMs=30000;
|
||||
int _savePeriodMs=0; //don't do period saves by default
|
||||
int _idleSavePeriodMs = 0; // don't idle save sessions by default.
|
||||
long _scavengePeriodMs=30000;
|
||||
long _savePeriodMs=0; //don't do period saves by default
|
||||
long _idleSavePeriodMs = 0; // don't idle save sessions by default.
|
||||
private TimerTask _saveTask;
|
||||
File _storeDir;
|
||||
private boolean _lazyLoad=false;
|
||||
|
@ -134,7 +134,7 @@ public class HashSessionManager extends AbstractSessionManager
|
|||
*/
|
||||
public int getScavengePeriod()
|
||||
{
|
||||
return _scavengePeriodMs/1000;
|
||||
return (int)(_scavengePeriodMs/1000);
|
||||
}
|
||||
|
||||
|
||||
|
@ -160,7 +160,7 @@ public class HashSessionManager extends AbstractSessionManager
|
|||
if (_idleSavePeriodMs <= 0)
|
||||
return 0;
|
||||
|
||||
return _idleSavePeriodMs / 1000;
|
||||
return (int)(_idleSavePeriodMs / 1000);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -174,7 +174,7 @@ public class HashSessionManager extends AbstractSessionManager
|
|||
*/
|
||||
public void setIdleSavePeriod(int seconds)
|
||||
{
|
||||
_idleSavePeriodMs = seconds * 1000;
|
||||
_idleSavePeriodMs = seconds * 1000L;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -182,7 +182,7 @@ public class HashSessionManager extends AbstractSessionManager
|
|||
public void setMaxInactiveInterval(int seconds)
|
||||
{
|
||||
super.setMaxInactiveInterval(seconds);
|
||||
if (_dftMaxIdleSecs>0&&_scavengePeriodMs>_dftMaxIdleSecs*1000)
|
||||
if (_dftMaxIdleSecs>0&&_scavengePeriodMs>_dftMaxIdleSecs*1000L)
|
||||
setScavengePeriod((_dftMaxIdleSecs+9)/10);
|
||||
}
|
||||
|
||||
|
@ -192,7 +192,7 @@ public class HashSessionManager extends AbstractSessionManager
|
|||
*/
|
||||
public void setSavePeriod (int seconds)
|
||||
{
|
||||
int period = (seconds * 1000);
|
||||
long period = (seconds * 1000L);
|
||||
if (period < 0)
|
||||
period=0;
|
||||
_savePeriodMs=period;
|
||||
|
@ -235,7 +235,7 @@ public class HashSessionManager extends AbstractSessionManager
|
|||
if (_savePeriodMs<=0)
|
||||
return 0;
|
||||
|
||||
return _savePeriodMs/1000;
|
||||
return (int)(_savePeriodMs/1000);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -247,8 +247,8 @@ public class HashSessionManager extends AbstractSessionManager
|
|||
if (seconds==0)
|
||||
seconds=60;
|
||||
|
||||
int old_period=_scavengePeriodMs;
|
||||
int period=seconds*1000;
|
||||
long old_period=_scavengePeriodMs;
|
||||
long period=seconds*1000L;
|
||||
if (period>60000)
|
||||
period=60000;
|
||||
if (period<1000)
|
||||
|
@ -297,7 +297,7 @@ public class HashSessionManager extends AbstractSessionManager
|
|||
for (Iterator<HashedSession> i=_sessions.values().iterator(); i.hasNext();)
|
||||
{
|
||||
HashedSession session=i.next();
|
||||
long idleTime=session.getMaxInactiveInterval()*1000;
|
||||
long idleTime=session.getMaxInactiveInterval()*1000L;
|
||||
if (idleTime>0&&session.getAccessed()+idleTime<now)
|
||||
{
|
||||
// Found a stale session, add it to the list
|
||||
|
|
|
@ -60,7 +60,7 @@ public class HashedSession extends AbstractSession
|
|||
public void setMaxInactiveInterval(int secs)
|
||||
{
|
||||
super.setMaxInactiveInterval(secs);
|
||||
if (getMaxInactiveInterval()>0&&(getMaxInactiveInterval()*1000/10)<_hashSessionManager._scavengePeriodMs)
|
||||
if (getMaxInactiveInterval()>0&&(getMaxInactiveInterval()*1000L/10)<_hashSessionManager._scavengePeriodMs)
|
||||
_hashSessionManager.setScavengePeriod((secs+9)/10);
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
|
|||
protected Timer _timer; //scavenge timer
|
||||
protected TimerTask _task; //scavenge task
|
||||
protected long _lastScavengeTime;
|
||||
protected long _scavengeIntervalMs = 1000 * 60 * 10; //10mins
|
||||
protected long _scavengeIntervalMs = 1000L * 60 * 10; //10mins
|
||||
protected String _blobType; //if not set, is deduced from the type of the database at runtime
|
||||
|
||||
protected String _createSessionIdTable;
|
||||
|
@ -245,7 +245,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
|
|||
sec=60;
|
||||
|
||||
long old_period=_scavengeIntervalMs;
|
||||
long period=sec*1000;
|
||||
long period=sec*1000L;
|
||||
|
||||
_scavengeIntervalMs=period;
|
||||
|
||||
|
|
|
@ -277,11 +277,11 @@ public class JDBCSessionManager extends AbstractSessionManager
|
|||
super(JDBCSessionManager.this,request);
|
||||
_data = new SessionData(getClusterId(),_jdbcAttributes);
|
||||
if (_dftMaxIdleSecs>0)
|
||||
_data.setMaxIdleMs(_dftMaxIdleSecs*1000);
|
||||
_data.setMaxIdleMs(_dftMaxIdleSecs*1000L);
|
||||
_data.setCanonicalContext(canonicalize(_context.getContextPath()));
|
||||
_data.setVirtualHost(getVirtualHost(_context));
|
||||
int maxInterval=getMaxInactiveInterval();
|
||||
_data.setExpiryTime(maxInterval <= 0 ? 0 : (System.currentTimeMillis() + maxInterval*1000));
|
||||
_data.setExpiryTime(maxInterval <= 0 ? 0 : (System.currentTimeMillis() + maxInterval*1000L));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -293,7 +293,7 @@ public class JDBCSessionManager extends AbstractSessionManager
|
|||
super(JDBCSessionManager.this,data.getCreated(), accessed, data.getId());
|
||||
_data=data;
|
||||
if (_dftMaxIdleSecs>0)
|
||||
_data.setMaxIdleMs(_dftMaxIdleSecs*1000);
|
||||
_data.setMaxIdleMs(_dftMaxIdleSecs*1000L);
|
||||
_jdbcAttributes.putAll(_data.getAttributeMap());
|
||||
_data.setAttributeMap(_jdbcAttributes);
|
||||
}
|
||||
|
@ -333,7 +333,7 @@ public class JDBCSessionManager extends AbstractSessionManager
|
|||
_data.setAccessed(time);
|
||||
|
||||
int maxInterval=getMaxInactiveInterval();
|
||||
_data.setExpiryTime(maxInterval <= 0 ? 0 : (time + maxInterval*1000));
|
||||
_data.setExpiryTime(maxInterval <= 0 ? 0 : (time + maxInterval*1000L));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -357,7 +357,7 @@ public class JDBCSessionManager extends AbstractSessionManager
|
|||
updateSession(_data);
|
||||
didActivate();
|
||||
}
|
||||
else if ((_data._accessed - _data._lastSaved) >= (getSaveInterval() * 1000))
|
||||
else if ((_data._accessed - _data._lastSaved) >= (getSaveInterval() * 1000L))
|
||||
{
|
||||
updateSessionAccessTime(_data);
|
||||
}
|
||||
|
@ -506,23 +506,23 @@ public class JDBCSessionManager extends AbstractSessionManager
|
|||
LOG.debug("getSession("+idInCluster+"): not in session map,"+
|
||||
" now="+now+
|
||||
" lastSaved="+(session==null?0:session._data._lastSaved)+
|
||||
" interval="+(_saveIntervalSec * 1000));
|
||||
" interval="+(_saveIntervalSec * 1000L));
|
||||
else
|
||||
LOG.debug("getSession("+idInCluster+"): in session map, "+
|
||||
" now="+now+
|
||||
" lastSaved="+(session==null?0:session._data._lastSaved)+
|
||||
" interval="+(_saveIntervalSec * 1000)+
|
||||
" interval="+(_saveIntervalSec * 1000L)+
|
||||
" lastNode="+session._data.getLastNode()+
|
||||
" thisNode="+getSessionIdManager().getWorkerName()+
|
||||
" difference="+(now - session._data._lastSaved));
|
||||
}
|
||||
|
||||
if (session==null || ((now - session._data._lastSaved) >= (_saveIntervalSec * 1000)))
|
||||
if (session==null || ((now - session._data._lastSaved) >= (_saveIntervalSec * 1000L)))
|
||||
{
|
||||
LOG.debug("getSession("+idInCluster+"): no session in session map or stale session. Reloading session data from db.");
|
||||
data = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context));
|
||||
}
|
||||
else if ((now - session._data._lastSaved) >= (_saveIntervalSec * 1000))
|
||||
else if ((now - session._data._lastSaved) >= (_saveIntervalSec * 1000L))
|
||||
{
|
||||
LOG.debug("getSession("+idInCluster+"): stale session. Reloading session data from db.");
|
||||
data = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context));
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.eclipse.jetty.io.nio.AsyncConnection;
|
|||
import org.eclipse.jetty.io.nio.SslConnection;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.nio.SelectChannelConnector;
|
||||
import org.eclipse.jetty.util.component.AggregateLifeCycle;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -54,9 +55,15 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements
|
|||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Construct with explicit SslContextFactory.
|
||||
* The SslContextFactory passed is added via {@link #addBean(Object)} so that
|
||||
* it's lifecycle may be managed with {@link AggregateLifeCycle}.
|
||||
* @param sslContextFactory
|
||||
*/
|
||||
public SslSelectChannelConnector(SslContextFactory sslContextFactory)
|
||||
{
|
||||
_sslContextFactory = sslContextFactory;
|
||||
addBean(_sslContextFactory);
|
||||
setUseDirectBuffers(false);
|
||||
setSoLingerTime(30000);
|
||||
}
|
||||
|
@ -597,7 +604,6 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements
|
|||
protected void doStart() throws Exception
|
||||
{
|
||||
_sslContextFactory.checkKeyStore();
|
||||
|
||||
_sslContextFactory.start();
|
||||
|
||||
SSLEngine sslEngine = _sslContextFactory.newSslEngine();
|
||||
|
@ -627,7 +633,6 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements
|
|||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
_sslContextFactory.stop();
|
||||
_sslBuffers=null;
|
||||
super.doStop();
|
||||
}
|
||||
|
|
|
@ -39,6 +39,9 @@ import static org.junit.matchers.JUnitMatchers.containsString;
|
|||
public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
||||
{
|
||||
protected static final int MAX_IDLE_TIME=250;
|
||||
private int sleepTime = MAX_IDLE_TIME + MAX_IDLE_TIME/5;
|
||||
private int minimumTestRuntime = MAX_IDLE_TIME-MAX_IDLE_TIME/5;
|
||||
private int maximumTestRuntime = MAX_IDLE_TIME*10;
|
||||
|
||||
static
|
||||
{
|
||||
|
@ -68,11 +71,11 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
long start = System.currentTimeMillis();
|
||||
IO.toString(is);
|
||||
|
||||
Thread.sleep(300);
|
||||
Thread.sleep(sleepTime);
|
||||
assertEquals(-1, is.read());
|
||||
|
||||
Assert.assertTrue(System.currentTimeMillis()-start>200);
|
||||
Assert.assertTrue(System.currentTimeMillis()-start<5000);
|
||||
Assert.assertTrue(System.currentTimeMillis()-start>minimumTestRuntime);
|
||||
Assert.assertTrue(System.currentTimeMillis()-start<maximumTestRuntime);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -101,11 +104,11 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
long start = System.currentTimeMillis();
|
||||
IO.toString(is);
|
||||
|
||||
Thread.sleep(300);
|
||||
Thread.sleep(sleepTime);
|
||||
assertEquals(-1, is.read());
|
||||
|
||||
Assert.assertTrue(System.currentTimeMillis()-start>200);
|
||||
Assert.assertTrue(System.currentTimeMillis()-start<5000);
|
||||
Assert.assertTrue(System.currentTimeMillis()-start>minimumTestRuntime);
|
||||
Assert.assertTrue(System.currentTimeMillis()-start<maximumTestRuntime);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -126,7 +129,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
{}
|
||||
super.handle(target,baseRequest,request,response);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
client.setSoTimeout(10000);
|
||||
|
@ -151,14 +154,14 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
// read the response
|
||||
String result=IO.toString(is);
|
||||
Assert.assertThat("OK",result,containsString("200 OK"));
|
||||
|
||||
|
||||
// check client reads EOF
|
||||
assertEquals(-1, is.read());
|
||||
|
||||
// wait for idle timeout
|
||||
TimeUnit.MILLISECONDS.sleep(MAX_IDLE_TIME+MAX_IDLE_TIME/2);
|
||||
|
||||
|
||||
|
||||
// further writes will get broken pipe or similar
|
||||
try
|
||||
{
|
||||
|
@ -199,7 +202,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
{}
|
||||
super.handle(target,baseRequest,request,response);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
client.setSoTimeout(10000);
|
||||
|
@ -220,10 +223,10 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
"\r\n").getBytes("utf-8"));
|
||||
os.write(contentB);
|
||||
os.flush();
|
||||
|
||||
|
||||
// Get the server side endpoint
|
||||
EndPoint endp = endpoint.exchange(null,10,TimeUnit.SECONDS);
|
||||
|
||||
|
||||
// read the response
|
||||
IO.toString(is);
|
||||
|
||||
|
@ -232,7 +235,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
|
||||
TimeUnit.MILLISECONDS.sleep(MAX_IDLE_TIME+MAX_IDLE_TIME/2);
|
||||
|
||||
|
||||
|
||||
// further writes will get broken pipe or similar
|
||||
try
|
||||
{
|
||||
|
@ -251,7 +254,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
{
|
||||
// expected
|
||||
}
|
||||
|
||||
|
||||
// check the server side is closed
|
||||
Assert.assertFalse(endp.isOpen());
|
||||
}
|
||||
|
@ -266,7 +269,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
InputStream is=client.getInputStream();
|
||||
assertFalse(client.isClosed());
|
||||
|
||||
Thread.sleep(500);
|
||||
Thread.sleep(sleepTime);
|
||||
long start = System.currentTimeMillis();
|
||||
try
|
||||
{
|
||||
|
@ -281,7 +284,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
|
|||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
Assert.assertTrue(System.currentTimeMillis()-start<5000);
|
||||
Assert.assertTrue(System.currentTimeMillis()-start<maximumTestRuntime);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ import junit.framework.Assert;
|
|||
|
||||
import org.eclipse.jetty.http.MimeTypes;
|
||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
|
@ -78,7 +79,7 @@ public class RequestTest
|
|||
_server.stop();
|
||||
_server.join();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testParamExtraction() throws Exception
|
||||
{
|
||||
|
@ -101,27 +102,27 @@ public class RequestTest
|
|||
System.err.println(map);
|
||||
assertFalse(map == null);
|
||||
assertTrue(map.isEmpty());
|
||||
|
||||
|
||||
Enumeration names = request.getParameterNames();
|
||||
assertFalse(names.hasMoreElements());
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//Send a request with query string with illegal hex code to cause
|
||||
//an exception parsing the params
|
||||
String request="GET /?param=%ZZaaa HTTP/1.1\r\n"+
|
||||
"Host: whatever\r\n"+
|
||||
"Content-Type: text/html;charset=utf8\n"+
|
||||
"\n";
|
||||
|
||||
|
||||
String responses=_connector.getResponses(request);
|
||||
assertTrue(responses.startsWith("HTTP/1.1 200"));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testBadUtf8ParamExtraction() throws Exception
|
||||
{
|
||||
|
@ -133,20 +134,40 @@ public class RequestTest
|
|||
return value.startsWith("aaa") && value.endsWith("bb");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//Send a request with query string with illegal hex code to cause
|
||||
//an exception parsing the params
|
||||
String request="GET /?param=aaa%E7bbb HTTP/1.1\r\n"+
|
||||
"Host: whatever\r\n"+
|
||||
"Content-Type: text/html;charset=utf8\n"+
|
||||
"\n";
|
||||
|
||||
|
||||
String responses=_connector.getResponses(request);
|
||||
assertTrue(responses.startsWith("HTTP/1.1 200"));
|
||||
assertTrue(responses.startsWith("HTTP/1.1 200"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testInvalidHostHeader() throws Exception
|
||||
{
|
||||
// Use a contextHandler with vhosts to force call to Request.getServerName()
|
||||
ContextHandler handler = new ContextHandler();
|
||||
handler.addVirtualHosts(new String[1]);
|
||||
_server.stop();
|
||||
_server.setHandler(handler);
|
||||
_server.start();
|
||||
|
||||
// Request with illegal Host header
|
||||
String request="GET / HTTP/1.1\r\n"+
|
||||
"Host: whatever.com:\r\n"+
|
||||
"Content-Type: text/html;charset=utf8\n"+
|
||||
"\n";
|
||||
|
||||
String responses=_connector.getResponses(request);
|
||||
assertTrue("400 Bad Request response expected",responses.startsWith("HTTP/1.1 400"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testContentTypeEncoding() throws Exception
|
||||
{
|
||||
|
@ -196,7 +217,7 @@ public class RequestTest
|
|||
assertTrue(results.get(i++).startsWith("text/html"));
|
||||
assertEquals(" x=z; ",results.get(i++));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testHostPort() throws Exception
|
||||
{
|
||||
|
@ -369,7 +390,7 @@ public class RequestTest
|
|||
Reader reader=request.getReader();
|
||||
String in = IO.toString(reader);
|
||||
String param = request.getParameter("param");
|
||||
|
||||
|
||||
byte[] b=("read='"+in+"' param="+param+"\n").getBytes(StringUtil.__UTF8);
|
||||
response.setContentLength(b.length);
|
||||
response.getOutputStream().write(b);
|
||||
|
@ -389,11 +410,11 @@ public class RequestTest
|
|||
"param=wrong\r\n";
|
||||
|
||||
String responses = _connector.getResponses(request);
|
||||
|
||||
|
||||
assertTrue(responses.indexOf("read='param=wrong' param=right")>0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testPartialInput() throws Exception
|
||||
{
|
||||
|
@ -752,7 +773,7 @@ public class RequestTest
|
|||
{
|
||||
_server.setAttribute("org.eclipse.jetty.server.Request.maxFormContentSize",-1);
|
||||
_server.setAttribute("org.eclipse.jetty.server.Request.maxFormKeys",1000);
|
||||
|
||||
|
||||
// This file is not distributed - as it is dangerous
|
||||
File evil_keys = new File("/tmp/keys_mapping_to_zero_2m");
|
||||
if (!evil_keys.exists())
|
||||
|
@ -760,10 +781,10 @@ public class RequestTest
|
|||
Log.info("testHashDOS skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
BufferedReader in = new BufferedReader(new FileReader(evil_keys));
|
||||
StringBuilder buf = new StringBuilder(4000000);
|
||||
|
||||
|
||||
String key=null;
|
||||
buf.append("a=b");
|
||||
while((key=in.readLine())!=null)
|
||||
|
@ -771,7 +792,7 @@ public class RequestTest
|
|||
buf.append("&").append(key).append("=").append("x");
|
||||
}
|
||||
buf.append("&c=d");
|
||||
|
||||
|
||||
_handler._checker = new RequestTester()
|
||||
{
|
||||
public boolean check(HttpServletRequest request,HttpServletResponse response)
|
||||
|
@ -787,15 +808,15 @@ public class RequestTest
|
|||
"Connection: close\r\n"+
|
||||
"\r\n"+
|
||||
buf;
|
||||
|
||||
|
||||
long start=System.currentTimeMillis();
|
||||
String response = _connector.getResponses(request);
|
||||
assertTrue(response.contains("200 OK"));
|
||||
long now=System.currentTimeMillis();
|
||||
assertTrue((now-start)<5000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
interface RequestTester
|
||||
{
|
||||
boolean check(HttpServletRequest request,HttpServletResponse response) throws IOException;
|
||||
|
@ -812,12 +833,12 @@ public class RequestTest
|
|||
|
||||
if (request.getContentLength()>0 && !MimeTypes.FORM_ENCODED.equals(request.getContentType()))
|
||||
_content=IO.toString(request.getInputStream());
|
||||
|
||||
|
||||
if (_checker!=null && _checker.check(request,response))
|
||||
response.setStatus(200);
|
||||
else
|
||||
response.sendError(500);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
package org.eclipse.jetty.server;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -24,14 +23,14 @@ import java.net.Socket;
|
|||
import org.eclipse.jetty.server.nio.SelectChannelConnector;
|
||||
import org.eclipse.jetty.server.session.SessionHandler;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class SelectChannelTimeoutTest extends ConnectorTimeoutTest
|
||||
{
|
||||
|
||||
@Before
|
||||
public void init() throws Exception
|
||||
|
||||
@BeforeClass
|
||||
public static void init() throws Exception
|
||||
{
|
||||
SelectChannelConnector connector = new SelectChannelConnector();
|
||||
connector.setMaxIdleTime(MAX_IDLE_TIME); // 250 msec max idle
|
||||
|
@ -50,9 +49,9 @@ public class SelectChannelTimeoutTest extends ConnectorTimeoutTest
|
|||
|
||||
_handler.setSuspendFor(100);
|
||||
_handler.setResumeAfter(25);
|
||||
assertTrue(process(null).toUpperCase().contains("RESUMED"));
|
||||
assertTrue(process(null).toUpperCase().contains("RESUMED"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testIdleTimeoutAfterTimeout() throws Exception
|
||||
{
|
||||
|
@ -62,13 +61,13 @@ public class SelectChannelTimeoutTest extends ConnectorTimeoutTest
|
|||
session.setHandler(_handler);
|
||||
_server.setHandler(session);
|
||||
_server.start();
|
||||
|
||||
|
||||
_handler.setSuspendFor(50);
|
||||
assertTrue(process(null).toUpperCase().contains("TIMEOUT"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testIdleTimeoutAfterComplete() throws Exception
|
||||
public void testIdleTimeoutAfterComplete() throws Exception
|
||||
{
|
||||
SuspendHandler _handler = new SuspendHandler();
|
||||
_server.stop();
|
||||
|
@ -76,15 +75,15 @@ public class SelectChannelTimeoutTest extends ConnectorTimeoutTest
|
|||
session.setHandler(_handler);
|
||||
_server.setHandler(session);
|
||||
_server.start();
|
||||
|
||||
|
||||
_handler.setSuspendFor(100);
|
||||
_handler.setCompleteAfter(25);
|
||||
assertTrue(process(null).toUpperCase().contains("COMPLETED"));
|
||||
}
|
||||
|
||||
private synchronized String process(String content) throws UnsupportedEncodingException, IOException, InterruptedException
|
||||
private synchronized String process(String content) throws UnsupportedEncodingException, IOException, InterruptedException
|
||||
{
|
||||
String request = "GET / HTTP/1.1\r\n" + "Host: localhost\r\n" + "Connection: close\r\n";
|
||||
String request = "GET / HTTP/1.1\r\n" + "Host: localhost\r\n";
|
||||
|
||||
if (content == null)
|
||||
request += "\r\n";
|
||||
|
@ -97,11 +96,13 @@ public class SelectChannelTimeoutTest extends ConnectorTimeoutTest
|
|||
{
|
||||
SelectChannelConnector connector = (SelectChannelConnector)_connector;
|
||||
Socket socket = new Socket((String)null,connector.getLocalPort());
|
||||
socket.setSoTimeout(10 * MAX_IDLE_TIME);
|
||||
socket.getOutputStream().write(request.getBytes("UTF-8"));
|
||||
InputStream inputStream = socket.getInputStream();
|
||||
long start = System.currentTimeMillis();
|
||||
String response = IO.toString(inputStream);
|
||||
Thread.sleep(500);
|
||||
assertEquals("Socket should be closed and return -1 on reading",-1,socket.getInputStream().read());
|
||||
long timeElapsed = System.currentTimeMillis() - start;
|
||||
assertTrue("Time elapsed should be at least MAX_IDLE_TIME",timeElapsed > MAX_IDLE_TIME);
|
||||
return response;
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ public class ELContextCleaner implements ServletContextListener
|
|||
}
|
||||
catch (NoSuchFieldException e)
|
||||
{
|
||||
LOG.warn("Cannot purge classes from javax.el.BeanELResolver", e);
|
||||
LOG.info("Not cleaning cached beans: no such field javax.el.BeanELResolver.properties");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,4 +3,3 @@ name: RO:Name
|
|||
displayName: RO:Display Name
|
||||
className: RO:Class Name
|
||||
initParameters: RO:Initial parameters
|
||||
|
||||
|
|
|
@ -18,7 +18,8 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
|
@ -42,7 +43,14 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
* <ul>
|
||||
* <li><b>allowedOrigins</b>, a comma separated list of origins that are
|
||||
* allowed to access the resources. Default value is <b>*</b>, meaning all
|
||||
* origins</li>
|
||||
* origins.<br />
|
||||
* If an allowed origin contains one or more * characters (for example
|
||||
* http://*.domain.com), then "*" characters are converted to ".*", "."
|
||||
* characters are escaped to "\." and the resulting allowed origin
|
||||
* interpreted as a regular expression.<br />
|
||||
* Allowed origins can therefore be more complex expressions such as
|
||||
* https?://*.domain.[a-z]{3} that matches http or https, multiple subdomains
|
||||
* and any 3 letter top-level domain (.com, .net, .org, etc.).</li>
|
||||
* <li><b>allowedMethods</b>, a comma separated list of HTTP methods that
|
||||
* are allowed to be used when accessing the resources. Default value is
|
||||
* <b>GET,POST</b></li>
|
||||
|
@ -229,19 +237,34 @@ public class CrossOriginFilter implements Filter
|
|||
if (origin.trim().length() == 0)
|
||||
continue;
|
||||
|
||||
boolean allowed = false;
|
||||
for (String allowedOrigin : allowedOrigins)
|
||||
{
|
||||
if (allowedOrigin.equals(origin))
|
||||
if (allowedOrigin.contains("*"))
|
||||
{
|
||||
allowed = true;
|
||||
break;
|
||||
Matcher matcher = createMatcher(origin,allowedOrigin);
|
||||
if (matcher.matches())
|
||||
return true;
|
||||
}
|
||||
else if (allowedOrigin.equals(origin))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (!allowed)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private Matcher createMatcher(String origin, String allowedOrigin)
|
||||
{
|
||||
String regex = parseAllowedWildcardOriginToRegex(allowedOrigin);
|
||||
Pattern pattern = Pattern.compile(regex);
|
||||
return pattern.matcher(origin);
|
||||
}
|
||||
|
||||
private String parseAllowedWildcardOriginToRegex(String allowedOrigin)
|
||||
{
|
||||
String regex = allowedOrigin.replace(".","\\.");
|
||||
return regex.replace("*",".*"); // we want to be greedy here to match multiple subdomains, thus we use .*
|
||||
}
|
||||
|
||||
private boolean isSimpleRequest(HttpServletRequest request)
|
||||
|
|
|
@ -59,6 +59,13 @@ import org.eclipse.jetty.util.TypeUtil;
|
|||
* <p>
|
||||
* If the init parameter "delete" is set to "true", any files created will be deleted when the
|
||||
* current request returns.
|
||||
* <p>
|
||||
* The init parameter maxFormKeys sets the maximum number of keys that may be present in a
|
||||
* form (default set by system property org.eclipse.jetty.server.Request.maxFormKeys or 1000) to protect
|
||||
* against DOS attacks by bad hash keys.
|
||||
* <p>
|
||||
* The init parameter deleteFiles controls if uploaded files are automatically deleted after the request
|
||||
* completes.
|
||||
*
|
||||
*/
|
||||
public class MultiPartFilter implements Filter
|
||||
|
@ -69,6 +76,7 @@ public class MultiPartFilter implements Filter
|
|||
private boolean _deleteFiles;
|
||||
private ServletContext _context;
|
||||
private int _fileOutputBuffer = 0;
|
||||
private int _maxFormKeys = Integer.getInteger("org.eclipse.jetty.server.Request.maxFormKeys",1000).intValue();
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
/**
|
||||
|
@ -82,6 +90,9 @@ public class MultiPartFilter implements Filter
|
|||
if(fileOutputBuffer!=null)
|
||||
_fileOutputBuffer = Integer.parseInt(fileOutputBuffer);
|
||||
_context=filterConfig.getServletContext();
|
||||
String mfks = filterConfig.getInitParameter("maxFormKeys");
|
||||
if (mfks!=null)
|
||||
_maxFormKeys=Integer.parseInt(mfks);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
|
@ -134,7 +145,7 @@ public class MultiPartFilter implements Filter
|
|||
String content_transfer_encoding=null;
|
||||
|
||||
|
||||
outer:while(!lastPart)
|
||||
outer:while(!lastPart && params.size()<_maxFormKeys)
|
||||
{
|
||||
String type_content=null;
|
||||
|
||||
|
|
|
@ -57,12 +57,12 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
|||
|
||||
/**
|
||||
* Asynchronous Proxy Servlet.
|
||||
*
|
||||
*
|
||||
* Forward requests to another server either as a standard web proxy (as defined by RFC2616) or as a transparent proxy.
|
||||
* <p>
|
||||
* This servlet needs the jetty-util and jetty-client classes to be available to the web application.
|
||||
* <p>
|
||||
* To facilitate JMX monitoring, the "HttpClient", it's "ThreadPool" and the "Logger" are set as context attributes prefixed with the servlet name.
|
||||
* To facilitate JMX monitoring, the "HttpClient" and "ThreadPool" are set as context attributes prefixed with the servlet name.
|
||||
* <p>
|
||||
* The following init parameters may be used to configure the servlet:
|
||||
* <ul>
|
||||
|
@ -75,17 +75,15 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
|||
* <li>requestBufferSize - the size of the request buffer (d. 12,288)
|
||||
* <li>responseHeaderSize - the size of the response header buffer (d. 6,144)
|
||||
* <li>responseBufferSize - the size of the response buffer (d. 32,768)
|
||||
* <li>HostHeader - Force the host header to a particular value
|
||||
* <li>HostHeader - Force the host header to a particular value
|
||||
* <li>whiteList - comma-separated list of allowed proxy destinations
|
||||
* <li>blackList - comma-separated list of forbidden proxy destinations
|
||||
* </ul>
|
||||
*
|
||||
*
|
||||
* @see org.eclipse.jetty.server.handler.ConnectHandler
|
||||
*/
|
||||
public class ProxyServlet implements Servlet
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(ProxyServlet.class);
|
||||
|
||||
protected Logger _log;
|
||||
protected HttpClient _client;
|
||||
protected String _hostHeader;
|
||||
|
@ -111,25 +109,24 @@ public class ProxyServlet implements Servlet
|
|||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see javax.servlet.Servlet#init(javax.servlet.ServletConfig)
|
||||
*/
|
||||
public void init(ServletConfig config) throws ServletException
|
||||
{
|
||||
_config = config;
|
||||
_context = config.getServletContext();
|
||||
|
||||
|
||||
_hostHeader = config.getInitParameter("HostHeader");
|
||||
|
||||
try
|
||||
{
|
||||
_log = createLogger(config);
|
||||
_log = createLogger(config);
|
||||
|
||||
_client = createHttpClient(config);
|
||||
|
||||
|
||||
if (_context != null)
|
||||
{
|
||||
_context.setAttribute(config.getServletName() + ".Logger",_log);
|
||||
_context.setAttribute(config.getServletName() + ".ThreadPool",_client.getThreadPool());
|
||||
_context.setAttribute(config.getServletName() + ".HttpClient",_client);
|
||||
}
|
||||
|
@ -162,12 +159,12 @@ public class ProxyServlet implements Servlet
|
|||
_log.debug(x);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create and return a logger based on the ServletConfig for use in the
|
||||
* Create and return a logger based on the ServletConfig for use in the
|
||||
* proxy servlet
|
||||
*
|
||||
*
|
||||
* @param config
|
||||
* @return Logger
|
||||
*/
|
||||
|
@ -175,24 +172,24 @@ public class ProxyServlet implements Servlet
|
|||
{
|
||||
return Log.getLogger("org.eclipse.jetty.servlets." + config.getServletName());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create and return an HttpClient based on ServletConfig
|
||||
*
|
||||
* By default this implementation will create an instance of the
|
||||
*
|
||||
* By default this implementation will create an instance of the
|
||||
* HttpClient for use by this proxy servlet.
|
||||
*
|
||||
* @param config
|
||||
* @return HttpClient
|
||||
*
|
||||
* @param config
|
||||
* @return HttpClient
|
||||
* @throws Exception
|
||||
*/
|
||||
protected HttpClient createHttpClient(ServletConfig config) throws Exception
|
||||
{
|
||||
HttpClient client = new HttpClient();
|
||||
client.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
|
||||
|
||||
|
||||
String t = config.getInitParameter("maxThreads");
|
||||
|
||||
|
||||
if (t != null)
|
||||
{
|
||||
client.setThreadPool(new QueuedThreadPool(Integer.parseInt(t)));
|
||||
|
@ -201,67 +198,67 @@ public class ProxyServlet implements Servlet
|
|||
{
|
||||
client.setThreadPool(new QueuedThreadPool());
|
||||
}
|
||||
|
||||
((QueuedThreadPool)client.getThreadPool()).setName(config.getServletName());
|
||||
|
||||
((QueuedThreadPool)client.getThreadPool()).setName(config.getServletName());
|
||||
|
||||
t = config.getInitParameter("maxConnections");
|
||||
|
||||
|
||||
if (t != null)
|
||||
{
|
||||
client.setMaxConnectionsPerAddress(Integer.parseInt(t));
|
||||
}
|
||||
|
||||
|
||||
t = config.getInitParameter("timeout");
|
||||
|
||||
|
||||
if ( t != null )
|
||||
{
|
||||
client.setTimeout(Long.parseLong(t));
|
||||
}
|
||||
|
||||
|
||||
t = config.getInitParameter("idleTimeout");
|
||||
|
||||
|
||||
if ( t != null )
|
||||
{
|
||||
client.setIdleTimeout(Long.parseLong(t));
|
||||
}
|
||||
|
||||
|
||||
t = config.getInitParameter("requestHeaderSize");
|
||||
|
||||
|
||||
if ( t != null )
|
||||
{
|
||||
client.setRequestHeaderSize(Integer.parseInt(t));
|
||||
}
|
||||
|
||||
|
||||
t = config.getInitParameter("requestBufferSize");
|
||||
|
||||
|
||||
if ( t != null )
|
||||
{
|
||||
client.setRequestBufferSize(Integer.parseInt(t));
|
||||
}
|
||||
|
||||
|
||||
t = config.getInitParameter("responseHeaderSize");
|
||||
|
||||
|
||||
if ( t != null )
|
||||
{
|
||||
client.setResponseHeaderSize(Integer.parseInt(t));
|
||||
}
|
||||
|
||||
|
||||
t = config.getInitParameter("responseBufferSize");
|
||||
|
||||
|
||||
if ( t != null )
|
||||
{
|
||||
client.setResponseBufferSize(Integer.parseInt(t));
|
||||
}
|
||||
|
||||
|
||||
client.start();
|
||||
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Helper function to process a parameter value containing a list of new entries and initialize the specified host map.
|
||||
*
|
||||
*
|
||||
* @param list
|
||||
* comma-separated list of new entries
|
||||
* @param hostMap
|
||||
|
@ -301,7 +298,7 @@ public class ProxyServlet implements Servlet
|
|||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Check the request hostname and path against white- and blacklist.
|
||||
*
|
||||
*
|
||||
* @param host
|
||||
* hostname to check
|
||||
* @param path
|
||||
|
@ -353,7 +350,7 @@ public class ProxyServlet implements Servlet
|
|||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see javax.servlet.Servlet#getServletConfig()
|
||||
*/
|
||||
public ServletConfig getServletConfig()
|
||||
|
@ -364,7 +361,7 @@ public class ProxyServlet implements Servlet
|
|||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Get the hostHeader.
|
||||
*
|
||||
*
|
||||
* @return the hostHeader
|
||||
*/
|
||||
public String getHostHeader()
|
||||
|
@ -375,7 +372,7 @@ public class ProxyServlet implements Servlet
|
|||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Set the hostHeader.
|
||||
*
|
||||
*
|
||||
* @param hostHeader
|
||||
* the hostHeader to set
|
||||
*/
|
||||
|
@ -387,7 +384,7 @@ public class ProxyServlet implements Servlet
|
|||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see javax.servlet.Servlet#service(javax.servlet.ServletRequest, javax.servlet.ServletResponse)
|
||||
*/
|
||||
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
|
||||
|
@ -412,7 +409,7 @@ public class ProxyServlet implements Servlet
|
|||
response.sendError(HttpServletResponse.SC_GATEWAY_TIMEOUT); // Need better test that isInitial
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
String uri = request.getRequestURI();
|
||||
if (request.getQueryString() != null)
|
||||
uri += "?" + request.getQueryString();
|
||||
|
@ -430,14 +427,17 @@ public class ProxyServlet implements Servlet
|
|||
|
||||
HttpExchange exchange = new HttpExchange()
|
||||
{
|
||||
@Override
|
||||
protected void onRequestCommitted() throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRequestComplete() throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResponseComplete() throws IOException
|
||||
{
|
||||
if (debug != 0)
|
||||
|
@ -445,6 +445,7 @@ public class ProxyServlet implements Servlet
|
|||
continuation.complete();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResponseContent(Buffer content) throws IOException
|
||||
{
|
||||
if (debug != 0)
|
||||
|
@ -452,10 +453,12 @@ public class ProxyServlet implements Servlet
|
|||
content.writeTo(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResponseHeaderComplete() throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
|
||||
{
|
||||
if (debug != 0)
|
||||
|
@ -467,6 +470,7 @@ public class ProxyServlet implements Servlet
|
|||
response.setStatus(status);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResponseHeader(Buffer name, Buffer value) throws IOException
|
||||
{
|
||||
String s = name.toString().toLowerCase();
|
||||
|
@ -481,11 +485,12 @@ public class ProxyServlet implements Servlet
|
|||
_log.debug(debug + " " + name + "! " + value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onConnectionFailed(Throwable ex)
|
||||
{
|
||||
handleOnConnectionFailed(ex,request,response);
|
||||
|
||||
// it is possible this might trigger before the
|
||||
|
||||
// it is possible this might trigger before the
|
||||
// continuation.suspend()
|
||||
if (!continuation.isInitial())
|
||||
{
|
||||
|
@ -493,16 +498,17 @@ public class ProxyServlet implements Servlet
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onException(Throwable ex)
|
||||
{
|
||||
if (ex instanceof EofException)
|
||||
{
|
||||
LOG.ignore(ex);
|
||||
_log.ignore(ex);
|
||||
return;
|
||||
}
|
||||
handleOnException(ex,request,response);
|
||||
|
||||
// it is possible this might trigger before the
|
||||
|
||||
// it is possible this might trigger before the
|
||||
// continuation.suspend()
|
||||
if (!continuation.isInitial())
|
||||
{
|
||||
|
@ -510,6 +516,7 @@ public class ProxyServlet implements Servlet
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onExpire()
|
||||
{
|
||||
handleOnExpire(request,response);
|
||||
|
@ -597,14 +604,14 @@ public class ProxyServlet implements Servlet
|
|||
if (hasContent)
|
||||
exchange.setRequestContentSource(in);
|
||||
|
||||
customizeExchange(exchange, request);
|
||||
|
||||
customizeExchange(exchange, request);
|
||||
|
||||
/*
|
||||
* we need to set the timeout on the continuation to take into
|
||||
* account the timeout of the HttpClient and the HttpExchange
|
||||
*/
|
||||
long ctimeout = (_client.getTimeout() > exchange.getTimeout()) ? _client.getTimeout() : exchange.getTimeout();
|
||||
|
||||
|
||||
// continuation fudge factor of 1000, underlying components
|
||||
// should fail/expire first from exchange
|
||||
if ( ctimeout == 0 )
|
||||
|
@ -612,12 +619,12 @@ public class ProxyServlet implements Servlet
|
|||
continuation.setTimeout(0); // ideally never times out
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
continuation.setTimeout(ctimeout + 1000);
|
||||
}
|
||||
|
||||
|
||||
customizeContinuation(continuation);
|
||||
|
||||
|
||||
continuation.suspend(response);
|
||||
_client.send(exchange);
|
||||
|
||||
|
@ -678,7 +685,7 @@ public class ProxyServlet implements Servlet
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see javax.servlet.Servlet#getServletInfo()
|
||||
*/
|
||||
public String getServletInfo()
|
||||
|
@ -689,7 +696,7 @@ public class ProxyServlet implements Servlet
|
|||
|
||||
/**
|
||||
* Extension point for subclasses to customize an exchange. Useful for setting timeouts etc. The default implementation does nothing.
|
||||
*
|
||||
*
|
||||
* @param exchange
|
||||
* @param request
|
||||
*/
|
||||
|
@ -701,7 +708,7 @@ public class ProxyServlet implements Servlet
|
|||
/**
|
||||
* Extension point for subclasses to customize the Continuation after it's initial creation in the service method. Useful for setting timeouts etc. The
|
||||
* default implementation does nothing.
|
||||
*
|
||||
*
|
||||
* @param continuation
|
||||
*/
|
||||
protected void customizeContinuation(Continuation continuation)
|
||||
|
@ -712,7 +719,7 @@ public class ProxyServlet implements Servlet
|
|||
/**
|
||||
* Extension point for custom handling of an HttpExchange's onConnectionFailed method. The default implementation delegates to
|
||||
* {@link #handleOnException(Throwable, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)}
|
||||
*
|
||||
*
|
||||
* @param ex
|
||||
* @param request
|
||||
* @param response
|
||||
|
@ -725,15 +732,15 @@ public class ProxyServlet implements Servlet
|
|||
/**
|
||||
* Extension point for custom handling of an HttpExchange's onException method. The default implementation sets the response status to
|
||||
* HttpServletResponse.SC_INTERNAL_SERVER_ERROR (503)
|
||||
*
|
||||
*
|
||||
* @param ex
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
protected void handleOnException(Throwable ex, HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
LOG.warn(ex.toString());
|
||||
LOG.debug(ex);
|
||||
_log.warn(ex.toString());
|
||||
_log.debug(ex);
|
||||
if (!response.isCommitted())
|
||||
{
|
||||
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
|
@ -743,7 +750,7 @@ public class ProxyServlet implements Servlet
|
|||
/**
|
||||
* Extension point for custom handling of an HttpExchange's onExpire method. The default implementation sets the response status to
|
||||
* HttpServletResponse.SC_GATEWAY_TIMEOUT (504)
|
||||
*
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
|
@ -757,7 +764,7 @@ public class ProxyServlet implements Servlet
|
|||
|
||||
/**
|
||||
* Transparent Proxy.
|
||||
*
|
||||
*
|
||||
* This convenience extension to ProxyServlet configures the servlet as a transparent proxy. The servlet is configured with init parameters:
|
||||
* <ul>
|
||||
* <li>ProxyTo - a URI like http://host:80/context to which the request is proxied.
|
||||
|
@ -765,7 +772,7 @@ public class ProxyServlet implements Servlet
|
|||
* </ul>
|
||||
* For example, if a request was received at /foo/bar and the ProxyTo was http://host:80/context and the Prefix was /foo, then the request would be proxied
|
||||
* to http://host:80/context/bar
|
||||
*
|
||||
*
|
||||
*/
|
||||
public static class Transparent extends ProxyServlet
|
||||
{
|
||||
|
|
|
@ -76,6 +76,52 @@ public class CrossOriginFilterTest
|
|||
Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleRequestWithMatchingWildcardOrigin() throws Exception
|
||||
{
|
||||
FilterHolder filterHolder = new FilterHolder(new CrossOriginFilter());
|
||||
String origin = "http://subdomain.example.com";
|
||||
filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "http://*.example.com");
|
||||
tester.getContext().addFilter(filterHolder, "/*", FilterMapping.DEFAULT);
|
||||
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
tester.getContext().addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
|
||||
|
||||
String request = "" +
|
||||
"GET / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Origin: " + origin + "\r\n" +
|
||||
"\r\n";
|
||||
String response = tester.getResponses(request);
|
||||
Assert.assertTrue(response.contains("HTTP/1.1 200"));
|
||||
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER));
|
||||
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER));
|
||||
Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleRequestWithMatchingWildcardOriginAndMultipleSubdomains() throws Exception
|
||||
{
|
||||
FilterHolder filterHolder = new FilterHolder(new CrossOriginFilter());
|
||||
String origin = "http://subdomain.subdomain.example.com";
|
||||
filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "http://*.example.com");
|
||||
tester.getContext().addFilter(filterHolder, "/*", FilterMapping.DEFAULT);
|
||||
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
tester.getContext().addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
|
||||
|
||||
String request = "" +
|
||||
"GET / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Origin: " + origin + "\r\n" +
|
||||
"\r\n";
|
||||
String response = tester.getResponses(request);
|
||||
Assert.assertTrue(response.contains("HTTP/1.1 200"));
|
||||
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER));
|
||||
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER));
|
||||
Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleRequestWithMatchingOrigin() throws Exception
|
||||
{
|
||||
|
@ -327,6 +373,7 @@ public class CrossOriginFilterTest
|
|||
|
||||
public static class ResourceServlet extends HttpServlet
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final CountDownLatch latch;
|
||||
|
||||
public ResourceServlet(CountDownLatch latch)
|
||||
|
|
|
@ -123,30 +123,35 @@ public class Main
|
|||
// if no non-option inis, add the start.ini and start.d
|
||||
if (!ini)
|
||||
{
|
||||
List<String> ini_args=new ArrayList<String>();
|
||||
File start_ini = new File(_jettyHome,"start.ini");
|
||||
if (start_ini.exists())
|
||||
ini_args.addAll(loadStartIni(start_ini));
|
||||
|
||||
File start_d = new File(_jettyHome,"start.d");
|
||||
if (start_d.isDirectory())
|
||||
{
|
||||
File[] inis = start_d.listFiles(new FilenameFilter()
|
||||
{
|
||||
public boolean accept(File dir, String name)
|
||||
{
|
||||
return name.toLowerCase().endsWith(".ini");
|
||||
}
|
||||
});
|
||||
Arrays.sort(inis);
|
||||
for (File i : inis)
|
||||
ini_args.addAll(loadStartIni(i));
|
||||
}
|
||||
arguments.addAll(0,ini_args);
|
||||
arguments.addAll(0,parseStartIniFiles());
|
||||
}
|
||||
|
||||
return arguments;
|
||||
}
|
||||
|
||||
List<String> parseStartIniFiles()
|
||||
{
|
||||
List<String> ini_args=new ArrayList<String>();
|
||||
File start_ini = new File(_jettyHome,"start.ini");
|
||||
if (start_ini.exists())
|
||||
ini_args.addAll(loadStartIni(start_ini));
|
||||
|
||||
File start_d = new File(_jettyHome,"start.d");
|
||||
if (start_d.isDirectory())
|
||||
{
|
||||
File[] inis = start_d.listFiles(new FilenameFilter()
|
||||
{
|
||||
public boolean accept(File dir, String name)
|
||||
{
|
||||
return name.toLowerCase().endsWith(".ini");
|
||||
}
|
||||
});
|
||||
Arrays.sort(inis);
|
||||
for (File i : inis)
|
||||
ini_args.addAll(loadStartIni(i));
|
||||
}
|
||||
return ini_args;
|
||||
}
|
||||
|
||||
public List<String> processCommandLine(List<String> arguments) throws Exception
|
||||
{
|
||||
|
@ -1075,7 +1080,7 @@ public class Main
|
|||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// usageExit(e,ERR_UNKNOWN);
|
||||
usageExit(e,ERR_UNKNOWN);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
@ -20,7 +20,7 @@ Command Line Options:
|
|||
when the start.ini includes -X or -D arguments.
|
||||
|
||||
--exec Run the generated command line (see --dry-run) in
|
||||
a sub processes. This can be used when start.ini
|
||||
a sub process. This can be used when start.ini
|
||||
contains -X or -D arguments, but creates an extra
|
||||
JVM instance.
|
||||
|
||||
|
@ -36,8 +36,10 @@ Command Line Options:
|
|||
|
||||
--ini=<file> Load command line arguments from a file. If
|
||||
no --ini options are specified, then the
|
||||
start.ini file will be read if it exists.
|
||||
A --ini option with no file indicates that
|
||||
start.ini file will be read if it exists in
|
||||
jetty.home. If specified jetty.home/start.ini
|
||||
and additional .ini files in jetty.home/start.d/
|
||||
will NOT be read. A --ini option with no file indicates that
|
||||
start.ini should not be read.
|
||||
|
||||
--pre=<file> Specify a configuration file that is to be processed
|
||||
|
@ -116,10 +118,10 @@ Available Configurations:
|
|||
Defaults:
|
||||
A start.ini file may be used to specify default arguments to start.jar,
|
||||
which are used if no command line arguments are provided and override
|
||||
the defaults in the start.config file. If the directory start.d exists,
|
||||
then multiple *.ini files will be read from that directory in alphabetical
|
||||
order. If --ini options are provided on the command line, then start.ini
|
||||
and start.d will not be read.
|
||||
the defaults in the start.config file. If the directory jetty.home/start.d
|
||||
exists, then multiple *.ini files will be read from that directory in
|
||||
alphabetical order. If --ini options are provided on the command line,
|
||||
then start.ini and start.d will NOT be read.
|
||||
|
||||
The current start.ini arguments are:
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ package org.eclipse.jetty.start;
|
|||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -39,15 +39,18 @@ public class MainTest
|
|||
|
||||
/**
|
||||
* Test method for {@link org.eclipse.jetty.start.StartIniParser#loadStartIni(java.lang.String)}.
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testLoadStartIni()
|
||||
public void testLoadStartIni() throws IOException
|
||||
{
|
||||
URL startIni = this.getClass().getResource("/jetty.home/start.ini");
|
||||
String startIniFileName = startIni.getFile();
|
||||
List<String> args = Main.loadStartIni(new File(startIniFileName));
|
||||
assertEquals("Expected 5 uncommented lines in start.ini",5,args.size());
|
||||
URL startIni = this.getClass().getResource("/jetty.home/");
|
||||
System.setProperty("jetty.home",startIni.getFile());
|
||||
Main main = new Main();
|
||||
List<String> args = main.parseStartIniFiles();
|
||||
assertEquals("Expected 5 uncommented lines in start.ini",9,args.size());
|
||||
assertEquals("First uncommented line in start.ini doesn't match expected result","OPTIONS=Server,jsp,resources,websocket,ext",args.get(0));
|
||||
assertEquals("Last uncommented line in start.ini doesn't match expected result","etc/jetty-testrealm.xml",args.get(8));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -12,92 +12,224 @@ import org.eclipse.jetty.util.log.Log;
|
|||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
/**
|
||||
* An AggregateLifeCycle is an AbstractLifeCycle with a collection of dependent beans.
|
||||
* An AggregateLifeCycle is an {@link LifeCycle} implementation for a collection of contained beans.
|
||||
* <p>
|
||||
* Beans can be added the AggregateLifeCycle either as managed beans or as unmanaged beans. A managed bean is started, stopped and destroyed with the aggregate.
|
||||
* An umanaged bean is associated with the aggregate for the purposes of {@link #dump()}, but it's lifecycle must be managed externally.
|
||||
* <p>
|
||||
* When a bean is added, if it is a {@link LifeCycle} and it is already started, then it is assumed to be an unmanaged bean.
|
||||
* Otherwise the methods {@link #addBean(LifeCycle, boolean)}, {@link #manage(LifeCycle)} and {@link #unmanage(LifeCycle)} can be used to
|
||||
* explicitly control the life cycle relationship.
|
||||
* <p>
|
||||
* If adding a bean that is shared between multiple {@link AggregateLifeCycle} instances, then it should be started before being added, so it is unmanged, or
|
||||
* the API must be used to explicitly set it as unmanaged.
|
||||
* <p>
|
||||
* Dependent beans are started and stopped with the {@link LifeCycle} and if they are destroyed if they are also {@link Destroyable}.
|
||||
*
|
||||
*/
|
||||
public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable, Dumpable
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(AggregateLifeCycle.class);
|
||||
private final List<Object> _dependentBeans=new CopyOnWriteArrayList<Object>();
|
||||
private final List<Bean> _beans=new CopyOnWriteArrayList<Bean>();
|
||||
private boolean _started=false;
|
||||
|
||||
public void destroy()
|
||||
private class Bean
|
||||
{
|
||||
for (Object o : _dependentBeans)
|
||||
Bean(Object b)
|
||||
{
|
||||
if (o instanceof Destroyable)
|
||||
{
|
||||
((Destroyable)o).destroy();
|
||||
}
|
||||
_bean=b;
|
||||
}
|
||||
_dependentBeans.clear();
|
||||
final Object _bean;
|
||||
volatile boolean _managed=true;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Start the managed lifecycle beans in the order they were added.
|
||||
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
|
||||
*/
|
||||
@Override
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
for (Object o:_dependentBeans)
|
||||
for (Bean b:_beans)
|
||||
{
|
||||
if (o instanceof LifeCycle)
|
||||
((LifeCycle)o).start();
|
||||
if (b._managed && b._bean instanceof LifeCycle)
|
||||
{
|
||||
LifeCycle l=(LifeCycle)b._bean;
|
||||
if (!l.isRunning())
|
||||
l.start();
|
||||
}
|
||||
}
|
||||
// indicate that we are started, so that addBean will start other beans added.
|
||||
_started=true;
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Stop the joined lifecycle beans in the reverse order they were added.
|
||||
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
|
||||
*/
|
||||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
_started=false;
|
||||
super.doStop();
|
||||
List<Object> reverse = new ArrayList<Object>(_dependentBeans);
|
||||
List<Bean> reverse = new ArrayList<Bean>(_beans);
|
||||
Collections.reverse(reverse);
|
||||
for (Object o:reverse)
|
||||
for (Bean b:reverse)
|
||||
{
|
||||
if (o instanceof LifeCycle)
|
||||
((LifeCycle)o).stop();
|
||||
if (b._managed && b._bean instanceof LifeCycle)
|
||||
{
|
||||
LifeCycle l=(LifeCycle)b._bean;
|
||||
if (l.isRunning())
|
||||
l.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Destroy the joined Destroyable beans in the reverse order they were added.
|
||||
* @see org.eclipse.jetty.util.component.Destroyable#destroy()
|
||||
*/
|
||||
public void destroy()
|
||||
{
|
||||
List<Bean> reverse = new ArrayList<Bean>(_beans);
|
||||
Collections.reverse(reverse);
|
||||
for (Bean b:reverse)
|
||||
{
|
||||
if (b._bean instanceof Destroyable && b._managed)
|
||||
{
|
||||
Destroyable d=(Destroyable)b._bean;
|
||||
d.destroy();
|
||||
}
|
||||
}
|
||||
_beans.clear();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Is the bean contained in the aggregate.
|
||||
* @param bean
|
||||
* @return True if the aggregate contains the bean
|
||||
*/
|
||||
public boolean contains(Object bean)
|
||||
{
|
||||
for (Bean b:_beans)
|
||||
if (b._bean==bean)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Is the bean joined to the aggregate.
|
||||
* @param bean
|
||||
* @return True if the aggregate contains the bean and it is joined
|
||||
*/
|
||||
public boolean isManaged(Object bean)
|
||||
{
|
||||
for (Bean b:_beans)
|
||||
if (b._bean==bean)
|
||||
return b._managed;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Add an associated bean.
|
||||
* The bean will be added to this LifeCycle and if it is also a
|
||||
* {@link LifeCycle} instance, it will be
|
||||
* started/stopped. Any beans that are also
|
||||
* {@link Destroyable}, will be destroyed with the server.
|
||||
* If the bean is a {@link LifeCycle}, then it will be managed if it is not
|
||||
* already started and umanaged if it is already started. The {@link #addBean(Object, boolean)}
|
||||
* method should be used if this is not correct, or the {@link #manage(Object)} and {@link #unmanage(Object)}
|
||||
* methods may be used after an add to change the status.
|
||||
* @param o the bean object to add
|
||||
* @return true if the bean was added or false if it has already been added.
|
||||
*/
|
||||
public boolean addBean(Object o)
|
||||
{
|
||||
if (o == null)
|
||||
// beans are joined unless they are started lifecycles
|
||||
return addBean(o,!((o instanceof LifeCycle)&&((LifeCycle)o).isStarted()));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Add an associated lifecycle.
|
||||
* @param o The lifecycle to add
|
||||
* @param managed True if the LifeCycle is to be joined, otherwise it will be disjoint.
|
||||
* @return
|
||||
*/
|
||||
public boolean addBean(Object o, boolean managed)
|
||||
{
|
||||
if (contains(o))
|
||||
return false;
|
||||
boolean added=false;
|
||||
if (!_dependentBeans.contains(o))
|
||||
{
|
||||
_dependentBeans.add(o);
|
||||
added=true;
|
||||
}
|
||||
|
||||
try
|
||||
Bean b = new Bean(o);
|
||||
b._managed=managed;
|
||||
_beans.add(b);
|
||||
|
||||
if (o instanceof LifeCycle)
|
||||
{
|
||||
if (isStarted() && o instanceof LifeCycle)
|
||||
((LifeCycle)o).start();
|
||||
LifeCycle l=(LifeCycle)o;
|
||||
|
||||
// Start the bean if we are started
|
||||
if (managed && _started)
|
||||
{
|
||||
try
|
||||
{
|
||||
l.start();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
throw new RuntimeException (e);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Manage a bean by this aggregate, so that it is started/stopped/destroyed with the
|
||||
* aggregate lifecycle.
|
||||
* @param bean The bean to manage (must already have been added).
|
||||
*/
|
||||
public void manage(Object bean)
|
||||
{
|
||||
for (Bean b :_beans)
|
||||
{
|
||||
throw new RuntimeException (e);
|
||||
if (b._bean==bean)
|
||||
{
|
||||
b._managed=true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return added;
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Unmanage a bean by this aggregate, so that it is not started/stopped/destroyed with the
|
||||
* aggregate lifecycle.
|
||||
* @param bean The bean to manage (must already have been added).
|
||||
*/
|
||||
public void unmanage(Object bean)
|
||||
{
|
||||
for (Bean b :_beans)
|
||||
{
|
||||
if (b._bean==bean)
|
||||
{
|
||||
b._managed=false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get dependent beans
|
||||
* @return List of beans.
|
||||
*/
|
||||
public Collection<Object> getBeans()
|
||||
{
|
||||
return _dependentBeans;
|
||||
return getBeans(Object.class);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -109,19 +241,17 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable
|
|||
public <T> List<T> getBeans(Class<T> clazz)
|
||||
{
|
||||
ArrayList<T> beans = new ArrayList<T>();
|
||||
Iterator<?> iter = _dependentBeans.iterator();
|
||||
while (iter.hasNext())
|
||||
for (Bean b:_beans)
|
||||
{
|
||||
Object o = iter.next();
|
||||
if (clazz.isInstance(o))
|
||||
beans.add((T)o);
|
||||
if (clazz.isInstance(b._bean))
|
||||
beans.add((T)(b._bean));
|
||||
}
|
||||
return beans;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get dependent bean of a specific class.
|
||||
/** Get dependent beans of a specific class.
|
||||
* If more than one bean of the type exist, the first is returned.
|
||||
* @see #addBean(Object)
|
||||
* @param clazz
|
||||
|
@ -129,23 +259,13 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable
|
|||
*/
|
||||
public <T> T getBean(Class<T> clazz)
|
||||
{
|
||||
Iterator<?> iter = _dependentBeans.iterator();
|
||||
T t=null;
|
||||
int count=0;
|
||||
while (iter.hasNext())
|
||||
for (Bean b:_beans)
|
||||
{
|
||||
Object o = iter.next();
|
||||
if (clazz.isInstance(o))
|
||||
{
|
||||
count++;
|
||||
if (t==null)
|
||||
t=(T)o;
|
||||
}
|
||||
if (clazz.isInstance(b._bean))
|
||||
return (T)b._bean;
|
||||
}
|
||||
if (count>1 && LOG.isDebugEnabled())
|
||||
LOG.debug("getBean({}) 1 of {}",clazz.getName(),count);
|
||||
|
||||
return t;
|
||||
return null;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -154,7 +274,7 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable
|
|||
*/
|
||||
public void removeBeans ()
|
||||
{
|
||||
_dependentBeans.clear();
|
||||
_beans.clear();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -163,9 +283,17 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable
|
|||
*/
|
||||
public boolean removeBean (Object o)
|
||||
{
|
||||
if (o == null)
|
||||
return false;
|
||||
return _dependentBeans.remove(o);
|
||||
Iterator<Bean> i = _beans.iterator();
|
||||
while(i.hasNext())
|
||||
{
|
||||
Bean b=i.next();
|
||||
if (b._bean==o)
|
||||
{
|
||||
_beans.remove(b);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -218,7 +346,32 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable
|
|||
public void dump(Appendable out,String indent) throws IOException
|
||||
{
|
||||
dumpThis(out);
|
||||
dump(out,indent,_dependentBeans);
|
||||
int size=_beans.size();
|
||||
if (size==0)
|
||||
return;
|
||||
int i=0;
|
||||
for (Bean b : _beans)
|
||||
{
|
||||
i++;
|
||||
|
||||
if (b._managed)
|
||||
{
|
||||
out.append(indent).append(" +- ");
|
||||
if (b._bean instanceof Dumpable)
|
||||
((Dumpable)b._bean).dump(out,indent+(i==size?" ":" | "));
|
||||
else
|
||||
out.append(String.valueOf(b._bean)).append("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
out.append(indent).append(" +~ ");
|
||||
out.append(String.valueOf(b._bean)).append("\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (i!=size)
|
||||
out.append(indent).append(" |\n");
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
package org.eclipse.jetty.util.log;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Abstract Logger.
|
||||
* Manages the atomic registration of the logger by name.
|
||||
*/
|
||||
public abstract class AbstractLogger implements Logger
|
||||
{
|
||||
public final Logger getLogger(String name)
|
||||
{
|
||||
if (isBlank(name))
|
||||
return this;
|
||||
|
||||
final String basename = getName();
|
||||
final String fullname = (isBlank(basename) || Log.getRootLogger()==this)?name:(basename + "." + name);
|
||||
|
||||
Logger logger = Log.getLoggers().get(fullname);
|
||||
if (logger == null)
|
||||
{
|
||||
Logger newlog = newLogger(fullname);
|
||||
|
||||
logger = Log.getMutableLoggers().putIfAbsent(fullname,newlog);
|
||||
if (logger == null)
|
||||
logger=newlog;
|
||||
}
|
||||
|
||||
return logger;
|
||||
}
|
||||
|
||||
|
||||
protected abstract Logger newLogger(String fullname);
|
||||
|
||||
/**
|
||||
* A more robust form of name blank test. Will return true for null names, and names that have only whitespace
|
||||
*
|
||||
* @param name
|
||||
* the name to test
|
||||
* @return true for null or blank name, false if any non-whitespace character is found.
|
||||
*/
|
||||
private static boolean isBlank(String name)
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
int size = name.length();
|
||||
char c;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
c = name.charAt(i);
|
||||
if (!Character.isWhitespace(c))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -28,7 +28,7 @@ import java.util.logging.Level;
|
|||
* standard java.util.logging configuration</a>.
|
||||
* </p>
|
||||
*/
|
||||
public class JavaUtilLog implements Logger
|
||||
public class JavaUtilLog extends AbstractLogger
|
||||
{
|
||||
private Level configuredLevel;
|
||||
private java.util.logging.Logger _logger;
|
||||
|
@ -116,9 +116,12 @@ public class JavaUtilLog implements Logger
|
|||
_logger.log(Level.FINE, msg, thrown);
|
||||
}
|
||||
|
||||
public Logger getLogger(String name)
|
||||
/**
|
||||
* Create a Child Logger of this Logger.
|
||||
*/
|
||||
protected Logger newLogger(String fullname)
|
||||
{
|
||||
return new JavaUtilLog(name);
|
||||
return new JavaUtilLog(fullname);
|
||||
}
|
||||
|
||||
public void ignore(Throwable ignored)
|
||||
|
|
|
@ -19,8 +19,14 @@ import java.lang.reflect.Method;
|
|||
import java.net.URL;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.Loader;
|
||||
|
@ -59,6 +65,12 @@ public class Log
|
|||
*/
|
||||
public static boolean __ignored;
|
||||
|
||||
/**
|
||||
* Hold loggers only.
|
||||
*/
|
||||
private final static ConcurrentMap<String, Logger> __loggers = new ConcurrentHashMap<String, Logger>();
|
||||
|
||||
|
||||
static
|
||||
{
|
||||
/* Instantiate a default configuration properties (empty)
|
||||
|
@ -102,7 +114,10 @@ public class Log
|
|||
while (systemKeyEnum.hasMoreElements())
|
||||
{
|
||||
String key = systemKeyEnum.nextElement();
|
||||
__props.setProperty(key,System.getProperty(key));
|
||||
String val = System.getProperty(key);
|
||||
//protect against application code insertion of non-String values (returned as null)
|
||||
if (val != null)
|
||||
__props.setProperty(key,val);
|
||||
}
|
||||
|
||||
/* Now use the configuration properties to configure the Log statics
|
||||
|
@ -415,6 +430,28 @@ public class Log
|
|||
if (!initialized())
|
||||
return null;
|
||||
|
||||
return name == null ? LOG : LOG.getLogger(name);
|
||||
if(name==null)
|
||||
return LOG;
|
||||
|
||||
Logger logger = __loggers.get(name);
|
||||
if(logger==null)
|
||||
logger = LOG.getLogger(name);
|
||||
|
||||
return logger;
|
||||
}
|
||||
|
||||
static ConcurrentMap<String, Logger> getMutableLoggers()
|
||||
{
|
||||
return __loggers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a map of all configured {@link Logger} instances.
|
||||
*
|
||||
* @return a map of all configured {@link Logger} instances
|
||||
*/
|
||||
public static Map<String, Logger> getLoggers()
|
||||
{
|
||||
return Collections.unmodifiableMap(__loggers);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ import java.lang.reflect.Method;
|
|||
/**
|
||||
*
|
||||
*/
|
||||
public class LoggerLog implements Logger
|
||||
public class LoggerLog extends AbstractLogger
|
||||
{
|
||||
private final Object _logger;
|
||||
private final Method _debugMT;
|
||||
|
@ -189,11 +189,14 @@ public class LoggerLog implements Logger
|
|||
}
|
||||
}
|
||||
|
||||
public Logger getLogger(String name)
|
||||
/**
|
||||
* Create a Child Logger of this Logger.
|
||||
*/
|
||||
protected Logger newLogger(String fullname)
|
||||
{
|
||||
try
|
||||
{
|
||||
Object logger=_getLoggerN.invoke(_logger, name);
|
||||
Object logger=_getLoggerN.invoke(_logger, fullname);
|
||||
return new LoggerLog(logger);
|
||||
}
|
||||
catch (Exception e)
|
||||
|
|
|
@ -18,7 +18,7 @@ package org.eclipse.jetty.util.log;
|
|||
/**
|
||||
* Slf4jLog Logger
|
||||
*/
|
||||
public class Slf4jLog implements Logger
|
||||
public class Slf4jLog extends AbstractLogger
|
||||
{
|
||||
private final org.slf4j.Logger _logger;
|
||||
|
||||
|
@ -114,9 +114,12 @@ public class Slf4jLog implements Logger
|
|||
warn("setDebugEnabled not implemented",null,null);
|
||||
}
|
||||
|
||||
public Logger getLogger(String name)
|
||||
/**
|
||||
* Create a Child Logger of this Logger.
|
||||
*/
|
||||
protected Logger newLogger(String fullname)
|
||||
{
|
||||
return new Slf4jLog(name);
|
||||
return new Slf4jLog(fullname);
|
||||
}
|
||||
|
||||
public void ignore(Throwable ignored)
|
||||
|
|
|
@ -35,7 +35,7 @@ import org.eclipse.jetty.util.DateCache;
|
|||
* used for logging. For named debuggers, the system property name+".LONG" is checked. If it is not not set, then
|
||||
* "org.eclipse.jetty.util.log.LONG" is used as the default.
|
||||
*/
|
||||
public class StdErrLog implements Logger
|
||||
public class StdErrLog extends AbstractLogger
|
||||
{
|
||||
private static final String EOL = System.getProperty("line.separator");
|
||||
private static DateCache _dateCache;
|
||||
|
@ -45,11 +45,6 @@ public class StdErrLog implements Logger
|
|||
Log.__props.getProperty("org.eclipse.jetty.util.log.stderr.SOURCE","false")));
|
||||
private final static boolean __long = Boolean.parseBoolean(Log.__props.getProperty("org.eclipse.jetty.util.log.stderr.LONG","false"));
|
||||
|
||||
/**
|
||||
* Tracking for child loggers only.
|
||||
*/
|
||||
private final static ConcurrentMap<String, StdErrLog> __loggers = new ConcurrentHashMap<String, StdErrLog>();
|
||||
|
||||
static
|
||||
{
|
||||
String deprecatedProperties[] =
|
||||
|
@ -332,28 +327,22 @@ public class StdErrLog implements Logger
|
|||
{
|
||||
if (enabled)
|
||||
{
|
||||
synchronized (__loggers)
|
||||
{
|
||||
this._level = LEVEL_DEBUG;
|
||||
this._level = LEVEL_DEBUG;
|
||||
|
||||
// Boot stomp all cached log levels to DEBUG
|
||||
for(StdErrLog log: __loggers.values())
|
||||
{
|
||||
log._level = LEVEL_DEBUG;
|
||||
}
|
||||
for (Logger log : Log.getLoggers().values())
|
||||
{
|
||||
if (log instanceof StdErrLog)
|
||||
((StdErrLog)log).setLevel(LEVEL_DEBUG);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
synchronized (__loggers)
|
||||
this._level = this._configuredLevel;
|
||||
|
||||
for (Logger log : Log.getLoggers().values())
|
||||
{
|
||||
this._level = this._configuredLevel;
|
||||
|
||||
// restore all cached log configured levels
|
||||
for(StdErrLog log: __loggers.values())
|
||||
{
|
||||
log._level = log._configuredLevel;
|
||||
}
|
||||
if (log instanceof StdErrLog)
|
||||
((StdErrLog)log).setLevel(((StdErrLog)log)._configuredLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -570,67 +559,18 @@ public class StdErrLog implements Logger
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A more robust form of name blank test. Will return true for null names, and names that have only whitespace
|
||||
*
|
||||
* @param name
|
||||
* the name to test
|
||||
* @return true for null or blank name, false if any non-whitespace character is found.
|
||||
*/
|
||||
private static boolean isBlank(String name)
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
int size = name.length();
|
||||
char c;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
c = name.charAt(i);
|
||||
if (!Character.isWhitespace(c))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Child Logger relative to this Logger.
|
||||
*
|
||||
* @param name
|
||||
* the child name
|
||||
* @return the appropriate child logger (if name specified results in a new unique child)
|
||||
* Create a Child Logger of this Logger.
|
||||
*/
|
||||
public Logger getLogger(String name)
|
||||
protected Logger newLogger(String fullname)
|
||||
{
|
||||
if (isBlank(name))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
String fullname = name;
|
||||
if (!isBlank(_name))
|
||||
{
|
||||
fullname = _name + "." + name;
|
||||
}
|
||||
|
||||
StdErrLog logger = __loggers.get(fullname);
|
||||
if (logger == null)
|
||||
{
|
||||
StdErrLog sel = new StdErrLog(fullname);
|
||||
// Preserve configuration for new loggers configuration
|
||||
sel.setPrintLongNames(_printLongNames);
|
||||
// Let Level come from configured Properties instead - sel.setLevel(_level);
|
||||
sel.setSource(_source);
|
||||
sel._stderr = this._stderr;
|
||||
logger = __loggers.putIfAbsent(fullname,sel);
|
||||
if (logger == null)
|
||||
{
|
||||
logger = sel;
|
||||
}
|
||||
}
|
||||
StdErrLog logger = new StdErrLog(fullname);
|
||||
// Preserve configuration for new loggers configuration
|
||||
logger.setPrintLongNames(_printLongNames);
|
||||
// Let Level come from configured Properties instead - sel.setLevel(_level);
|
||||
logger.setSource(_source);
|
||||
logger._stderr = this._stderr;
|
||||
|
||||
return logger;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,6 @@ import java.util.Collections;
|
|||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.net.ssl.CertPathTrustManagerParameters;
|
||||
import javax.net.ssl.KeyManager;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
|
@ -73,7 +72,7 @@ import org.eclipse.jetty.util.security.Password;
|
|||
public class SslContextFactory extends AbstractLifeCycle
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(SslContextFactory.class);
|
||||
|
||||
|
||||
public static final String DEFAULT_KEYMANAGERFACTORY_ALGORITHM =
|
||||
(Security.getProperty("ssl.KeyManagerFactory.algorithm") == null ?
|
||||
"SunX509" : Security.getProperty("ssl.KeyManagerFactory.algorithm"));
|
||||
|
@ -96,7 +95,7 @@ public class SslContextFactory extends AbstractLifeCycle
|
|||
// private final Set<String> _excludeProtocols = new HashSet<String>(Collections.singleton("SSLv2Hello"));
|
||||
/** Included protocols. */
|
||||
private Set<String> _includeProtocols = null;
|
||||
|
||||
|
||||
/** Excluded cipher suites. */
|
||||
private final Set<String> _excludeCipherSuites = new HashSet<String>();
|
||||
/** Included cipher suites. */
|
||||
|
@ -178,7 +177,7 @@ public class SslContextFactory extends AbstractLifeCycle
|
|||
|
||||
/** SSL context */
|
||||
private SSLContext _context;
|
||||
|
||||
|
||||
private boolean _trustAll;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -225,7 +224,7 @@ public class SslContextFactory extends AbstractLifeCycle
|
|||
_trustStore==null && _trustStoreInputStream == null && _trustStorePath == null )
|
||||
{
|
||||
TrustManager[] trust_managers=null;
|
||||
|
||||
|
||||
if (_trustAll)
|
||||
{
|
||||
LOG.debug("No keystore or trust store configured. ACCEPTING UNTRUSTED CERTIFICATES!!!!!");
|
||||
|
@ -247,7 +246,7 @@ public class SslContextFactory extends AbstractLifeCycle
|
|||
};
|
||||
trust_managers = new TrustManager[] { trustAllCerts };
|
||||
}
|
||||
|
||||
|
||||
SecureRandom secureRandom = (_secureRandomAlgorithm == null)?null:SecureRandom.getInstance(_secureRandomAlgorithm);
|
||||
_context = SSLContext.getInstance(_sslProtocol);
|
||||
_context.init(null, trust_managers, secureRandom);
|
||||
|
@ -255,7 +254,7 @@ public class SslContextFactory extends AbstractLifeCycle
|
|||
else
|
||||
{
|
||||
// verify that keystore and truststore
|
||||
// parameters are set up correctly
|
||||
// parameters are set up correctly
|
||||
checkKeyStore();
|
||||
|
||||
KeyStore keyStore = loadKeyStore();
|
||||
|
@ -293,7 +292,7 @@ public class SslContextFactory extends AbstractLifeCycle
|
|||
_context.init(keyManagers,trustManagers,secureRandom);
|
||||
|
||||
SSLEngine engine=newSslEngine();
|
||||
|
||||
|
||||
LOG.info("Enabled Protocols {} of {}",Arrays.asList(engine.getEnabledProtocols()),Arrays.asList(engine.getSupportedProtocols()));
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Enabled Ciphers {} of {}",Arrays.asList(engine.getEnabledCipherSuites()),Arrays.asList(engine.getSupportedCipherSuites()));
|
||||
|
@ -334,7 +333,7 @@ public class SslContextFactory extends AbstractLifeCycle
|
|||
checkNotStarted();
|
||||
_excludeProtocols.addAll(Arrays.asList(protocol));
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return The array of protocol names to include in
|
||||
|
@ -380,7 +379,7 @@ public class SslContextFactory extends AbstractLifeCycle
|
|||
_excludeCipherSuites.clear();
|
||||
_excludeCipherSuites.addAll(Arrays.asList(cipherSuites));
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param cipher Cipher names to add to {@link SSLEngine#setEnabledCipherSuites(String[])}
|
||||
|
@ -429,7 +428,7 @@ public class SslContextFactory extends AbstractLifeCycle
|
|||
{
|
||||
return _keyStorePath;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param keyStorePath
|
||||
|
@ -878,7 +877,7 @@ public class SslContextFactory extends AbstractLifeCycle
|
|||
{
|
||||
return (_keyManagerFactoryAlgorithm);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param algorithm
|
||||
|
@ -1094,7 +1093,7 @@ public class SslContextFactory extends AbstractLifeCycle
|
|||
|
||||
/* ------------------------------------------------------------ */
|
||||
protected TrustManager[] getTrustManagers(KeyStore trustStore, Collection<? extends CRL> crls) throws Exception
|
||||
{
|
||||
{
|
||||
TrustManager[] managers = null;
|
||||
if (trustStore != null)
|
||||
{
|
||||
|
@ -1156,15 +1155,15 @@ public class SslContextFactory extends AbstractLifeCycle
|
|||
* used as truststore.
|
||||
* @throws IllegalStateException if SslContextFactory configuration can't be used.
|
||||
*/
|
||||
public void checkKeyStore()
|
||||
public void checkKeyStore()
|
||||
{
|
||||
if (_context != null)
|
||||
return; //nothing to check if using preconfigured context
|
||||
|
||||
|
||||
|
||||
|
||||
if (_keyStore == null && _keyStoreInputStream == null && _keyStorePath == null)
|
||||
throw new IllegalStateException("SSL doesn't have a valid keystore");
|
||||
|
||||
|
||||
// if the keystore has been configured but there is no
|
||||
// truststore configured, use the keystore as the truststore
|
||||
if (_trustStore == null && _trustStoreInputStream == null && _trustStorePath == null)
|
||||
|
@ -1209,7 +1208,7 @@ public class SslContextFactory extends AbstractLifeCycle
|
|||
public String[] selectProtocols(String[] enabledProtocols, String[] supportedProtocols)
|
||||
{
|
||||
Set<String> selected_protocols = new HashSet<String>();
|
||||
|
||||
|
||||
// Set the starting protocols - either from the included or enabled list
|
||||
if (_includeProtocols!=null)
|
||||
{
|
||||
|
@ -1220,15 +1219,15 @@ public class SslContextFactory extends AbstractLifeCycle
|
|||
}
|
||||
else
|
||||
selected_protocols.addAll(Arrays.asList(enabledProtocols));
|
||||
|
||||
|
||||
|
||||
|
||||
// Remove any excluded protocols
|
||||
if (_excludeProtocols != null)
|
||||
selected_protocols.removeAll(_excludeProtocols);
|
||||
|
||||
|
||||
return selected_protocols.toArray(new String[selected_protocols.size()]);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Select cipher suites to be used by the connector
|
||||
|
@ -1241,7 +1240,7 @@ public class SslContextFactory extends AbstractLifeCycle
|
|||
public String[] selectCipherSuites(String[] enabledCipherSuites, String[] supportedCipherSuites)
|
||||
{
|
||||
Set<String> selected_ciphers = new HashSet<String>();
|
||||
|
||||
|
||||
// Set the starting ciphers - either from the included or enabled list
|
||||
if (_includeCipherSuites!=null)
|
||||
{
|
||||
|
@ -1252,8 +1251,8 @@ public class SslContextFactory extends AbstractLifeCycle
|
|||
}
|
||||
else
|
||||
selected_ciphers.addAll(Arrays.asList(enabledCipherSuites));
|
||||
|
||||
|
||||
|
||||
|
||||
// Remove any excluded ciphers
|
||||
if (_excludeCipherSuites != null)
|
||||
selected_ciphers.removeAll(_excludeCipherSuites);
|
||||
|
@ -1450,7 +1449,7 @@ public class SslContextFactory extends AbstractLifeCycle
|
|||
{
|
||||
SSLServerSocketFactory factory = _context.getServerSocketFactory();
|
||||
|
||||
SSLServerSocket socket =
|
||||
SSLServerSocket socket =
|
||||
(SSLServerSocket) (host==null ?
|
||||
factory.createServerSocket(port,backlog):
|
||||
factory.createServerSocket(port,backlog,InetAddress.getByName(host)));
|
||||
|
@ -1467,14 +1466,14 @@ public class SslContextFactory extends AbstractLifeCycle
|
|||
|
||||
return socket;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public SSLSocket newSslSocket() throws IOException
|
||||
{
|
||||
SSLSocketFactory factory = _context.getSocketFactory();
|
||||
|
||||
|
||||
SSLSocket socket = (SSLSocket)factory.createSocket();
|
||||
|
||||
|
||||
if (getWantClientAuth())
|
||||
socket.setWantClientAuth(getWantClientAuth());
|
||||
if (getNeedClientAuth())
|
||||
|
@ -1482,23 +1481,23 @@ public class SslContextFactory extends AbstractLifeCycle
|
|||
|
||||
socket.setEnabledCipherSuites(selectCipherSuites(
|
||||
socket.getEnabledCipherSuites(),
|
||||
socket.getSupportedCipherSuites()));
|
||||
socket.getSupportedCipherSuites()));
|
||||
socket.setEnabledProtocols(selectProtocols(socket.getEnabledProtocols(),socket.getSupportedProtocols()));
|
||||
|
||||
return socket;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public SSLEngine newSslEngine(String host,int port)
|
||||
{
|
||||
SSLEngine sslEngine=isSessionCachingEnabled()
|
||||
?_context.createSSLEngine(host, port)
|
||||
:_context.createSSLEngine();
|
||||
|
||||
|
||||
customize(sslEngine);
|
||||
return sslEngine;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public SSLEngine newSslEngine()
|
||||
{
|
||||
|
@ -1518,8 +1517,18 @@ public class SslContextFactory extends AbstractLifeCycle
|
|||
sslEngine.setEnabledCipherSuites(selectCipherSuites(
|
||||
sslEngine.getEnabledCipherSuites(),
|
||||
sslEngine.getSupportedCipherSuites()));
|
||||
|
||||
|
||||
sslEngine.setEnabledProtocols(selectProtocols(sslEngine.getEnabledProtocols(),sslEngine.getSupportedProtocols()));
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%s@%x(%s,%s)#%s",
|
||||
getClass().getSimpleName(),
|
||||
hashCode(),
|
||||
_keyStorePath,
|
||||
_trustStorePath,
|
||||
getState());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -363,6 +363,7 @@ public class QueuedThreadPool extends AbstractLifeCycle implements SizedThreadPo
|
|||
return true;
|
||||
}
|
||||
}
|
||||
LOG.debug("Dispatched {} to stopped {}",job,this);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -110,6 +110,107 @@ public class AggregateLifeCycleTest
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisJoint() throws Exception
|
||||
{
|
||||
final AtomicInteger destroyed=new AtomicInteger();
|
||||
final AtomicInteger started=new AtomicInteger();
|
||||
final AtomicInteger stopped=new AtomicInteger();
|
||||
|
||||
AggregateLifeCycle a0=new AggregateLifeCycle();
|
||||
|
||||
AggregateLifeCycle a1=new AggregateLifeCycle()
|
||||
{
|
||||
@Override
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
started.incrementAndGet();
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
stopped.incrementAndGet();
|
||||
super.doStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
destroyed.incrementAndGet();
|
||||
super.destroy();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Start the a1 bean before adding, makes it auto disjoint
|
||||
a1.start();
|
||||
|
||||
// Now add it
|
||||
a0.addBean(a1);
|
||||
Assert.assertFalse(a0.isManaged(a1));
|
||||
|
||||
a0.start();
|
||||
Assert.assertEquals(1,started.get());
|
||||
Assert.assertEquals(0,stopped.get());
|
||||
Assert.assertEquals(0,destroyed.get());
|
||||
|
||||
a0.start();
|
||||
Assert.assertEquals(1,started.get());
|
||||
Assert.assertEquals(0,stopped.get());
|
||||
Assert.assertEquals(0,destroyed.get());
|
||||
|
||||
a0.stop();
|
||||
Assert.assertEquals(1,started.get());
|
||||
Assert.assertEquals(0,stopped.get());
|
||||
Assert.assertEquals(0,destroyed.get());
|
||||
|
||||
a1.stop();
|
||||
Assert.assertEquals(1,started.get());
|
||||
Assert.assertEquals(1,stopped.get());
|
||||
Assert.assertEquals(0,destroyed.get());
|
||||
|
||||
a0.start();
|
||||
Assert.assertEquals(1,started.get());
|
||||
Assert.assertEquals(1,stopped.get());
|
||||
Assert.assertEquals(0,destroyed.get());
|
||||
|
||||
a0.manage(a1);
|
||||
Assert.assertTrue(a0.isManaged(a1));
|
||||
|
||||
a0.stop();
|
||||
Assert.assertEquals(1,started.get());
|
||||
Assert.assertEquals(1,stopped.get());
|
||||
Assert.assertEquals(0,destroyed.get());
|
||||
|
||||
|
||||
a0.start();
|
||||
Assert.assertEquals(2,started.get());
|
||||
Assert.assertEquals(1,stopped.get());
|
||||
Assert.assertEquals(0,destroyed.get());
|
||||
|
||||
a0.stop();
|
||||
Assert.assertEquals(2,started.get());
|
||||
Assert.assertEquals(2,stopped.get());
|
||||
Assert.assertEquals(0,destroyed.get());
|
||||
|
||||
|
||||
a0.unmanage(a1);
|
||||
Assert.assertFalse(a0.isManaged(a1));
|
||||
|
||||
a0.destroy();
|
||||
Assert.assertEquals(2,started.get());
|
||||
Assert.assertEquals(2,stopped.get());
|
||||
Assert.assertEquals(0,destroyed.get());
|
||||
|
||||
a1.destroy();
|
||||
Assert.assertEquals(2,started.get());
|
||||
Assert.assertEquals(2,stopped.get());
|
||||
Assert.assertEquals(1,destroyed.get());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDumpable()
|
||||
{
|
||||
|
@ -159,6 +260,11 @@ public class AggregateLifeCycleTest
|
|||
System.err.println("--");
|
||||
a2.addBean(aa0);
|
||||
a0.dumpStdErr();
|
||||
|
||||
System.err.println("--");
|
||||
a0.unmanage(aa);
|
||||
a2.unmanage(aa0);
|
||||
a0.dumpStdErr();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,9 @@ package org.eclipse.jetty.util.log;
|
|||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
|
@ -23,18 +26,23 @@ import org.junit.Test;
|
|||
public class LogTest
|
||||
{
|
||||
private static Logger originalLogger;
|
||||
private static Map<String,Logger> originalLoggers;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@BeforeClass
|
||||
public static void rememberOriginalLogger()
|
||||
{
|
||||
originalLogger = Log.getLog();
|
||||
originalLoggers = new HashMap<String, Logger>(Log.getLoggers());
|
||||
Log.getMutableLoggers().clear();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void restoreOriginalLogger()
|
||||
{
|
||||
Log.setLog(originalLogger);
|
||||
Log.getMutableLoggers().clear();
|
||||
Log.getMutableLoggers().putAll(originalLoggers);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -1,26 +1,9 @@
|
|||
package org.eclipse.jetty.util.log;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class NamedLogTest
|
||||
{
|
||||
private static Logger originalLogger;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@BeforeClass
|
||||
public static void rememberOriginalLogger()
|
||||
{
|
||||
originalLogger = Log.getLog();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void restoreOriginalLogger()
|
||||
{
|
||||
Log.setLog(originalLogger);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNamedLogging()
|
||||
{
|
||||
|
@ -37,7 +20,7 @@ public class NamedLogTest
|
|||
red.generateLogs();
|
||||
green.generateLogs();
|
||||
blue.generateLogs();
|
||||
|
||||
|
||||
output.assertContains(Red.class.getName());
|
||||
output.assertContains(Green.class.getName());
|
||||
output.assertContains(Blue.class.getName());
|
||||
|
|
|
@ -43,4 +43,10 @@ public class StdErrCapture
|
|||
String output = new String(test.toByteArray());
|
||||
Assert.assertThat(output,not(containsString(unexpectedString)));
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
err.flush();
|
||||
return new String(test.toByteArray());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ public class WebSocketClientFactory extends AggregateLifeCycle
|
|||
*/
|
||||
public WebSocketClientFactory()
|
||||
{
|
||||
this(new QueuedThreadPool());
|
||||
this(null);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -114,14 +114,20 @@ public class WebSocketClientFactory extends AggregateLifeCycle
|
|||
*/
|
||||
public WebSocketClientFactory(ThreadPool threadPool, MaskGen maskGen, int bufferSize)
|
||||
{
|
||||
if (threadPool == null)
|
||||
threadPool = new QueuedThreadPool();
|
||||
_threadPool = threadPool;
|
||||
addBean(threadPool);
|
||||
addBean(_threadPool);
|
||||
|
||||
_buffers = new WebSocketBuffers(bufferSize);
|
||||
addBean(_buffers);
|
||||
|
||||
_maskGen = maskGen;
|
||||
addBean(_maskGen);
|
||||
|
||||
_selector = new WebSocketClientSelector();
|
||||
addBean(_selector);
|
||||
|
||||
addBean(_sslContextFactory);
|
||||
}
|
||||
|
||||
|
@ -208,6 +214,7 @@ public class WebSocketClientFactory extends AggregateLifeCycle
|
|||
protected void doStop() throws Exception
|
||||
{
|
||||
closeConnections();
|
||||
super.doStop();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
|
|
@ -121,7 +121,7 @@ public class WebSocketConnectionRFC6455 extends AbstractConnection implements We
|
|||
|
||||
private final static byte[] MAGIC;
|
||||
private final List<Extension> _extensions;
|
||||
private final WebSocketParserD13 _parser;
|
||||
private final WebSocketParserRFC6455 _parser;
|
||||
private final WebSocketGeneratorRFC6455 _generator;
|
||||
private final WebSocketGenerator _outbound;
|
||||
private final WebSocket _webSocket;
|
||||
|
@ -197,7 +197,7 @@ public class WebSocketConnectionRFC6455 extends AbstractConnection implements We
|
|||
_outbound=(_extensions==null||_extensions.size()==0)?_generator:extensions.get(extensions.size()-1);
|
||||
WebSocketParser.FrameHandler inbound = (_extensions == null || _extensions.size() == 0) ? frameHandler : extensions.get(0);
|
||||
|
||||
_parser = new WebSocketParserD13(buffers, endpoint, inbound,maskgen==null);
|
||||
_parser = new WebSocketParserRFC6455(buffers, endpoint, inbound,maskgen==null);
|
||||
|
||||
_protocol=protocol;
|
||||
|
||||
|
@ -642,7 +642,13 @@ public class WebSocketConnectionRFC6455 extends AbstractConnection implements We
|
|||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return this.getClass().getSimpleName()+"D13@"+_endp.getLocalAddr()+":"+_endp.getLocalPort()+"<->"+_endp.getRemoteAddr()+":"+_endp.getRemotePort();
|
||||
return String.format("%s@%x l(%s:%d)<->r(%s:%d)",
|
||||
getClass().getSimpleName(),
|
||||
hashCode(),
|
||||
_endp.getLocalAddr(),
|
||||
_endp.getLocalPort(),
|
||||
_endp.getRemoteAddr(),
|
||||
_endp.getRemotePort());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -973,6 +979,6 @@ public class WebSocketConnectionRFC6455 extends AbstractConnection implements We
|
|||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("WS/D%d p=%s g=%s", _draft, _parser, _generator);
|
||||
return String.format("%s p=%s g=%s", getClass().getSimpleName(), _parser, _generator);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,9 +43,9 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
* Parser the WebSocket protocol.
|
||||
*
|
||||
*/
|
||||
public class WebSocketParserD13 implements WebSocketParser
|
||||
public class WebSocketParserRFC6455 implements WebSocketParser
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(WebSocketParserD13.class);
|
||||
private static final Logger LOG = Log.getLogger(WebSocketParserRFC6455.class);
|
||||
|
||||
public enum State {
|
||||
|
||||
|
@ -89,7 +89,7 @@ public class WebSocketParserD13 implements WebSocketParser
|
|||
* @param handler the handler to notify when a parse event occurs
|
||||
* @param shouldBeMasked whether masking should be handled
|
||||
*/
|
||||
public WebSocketParserD13(WebSocketBuffers buffers, EndPoint endp, FrameHandler handler, boolean shouldBeMasked)
|
||||
public WebSocketParserRFC6455(WebSocketBuffers buffers, EndPoint endp, FrameHandler handler, boolean shouldBeMasked)
|
||||
{
|
||||
_buffers=buffers;
|
||||
_endp=endp;
|
|
@ -95,10 +95,11 @@ public class SafariWebsocketDraft0Test
|
|||
|
||||
CaptureSocket socket = servlet.captures.get(0);
|
||||
Assert.assertThat("CaptureSocket",socket,notNullValue());
|
||||
Assert.assertThat("CaptureSocket.isConnected", socket.awaitConnected(1000), is(true));
|
||||
Assert.assertThat("CaptureSocket.isConnected", socket.awaitConnected(10000), is(true));
|
||||
|
||||
// Give servlet time to process messages
|
||||
threadSleep(1,TimeUnit.SECONDS);
|
||||
for (int i=0;i<100 && socket.messages.size()<5;i++)
|
||||
threadSleep(100,TimeUnit.MILLISECONDS);
|
||||
|
||||
// Should have captured 5 messages.
|
||||
Assert.assertThat("CaptureSocket.messages.size",socket.messages.size(),is(5));
|
||||
|
|
|
@ -74,8 +74,10 @@ public class WebSocketClientTest
|
|||
@Test
|
||||
public void testMessageBiggerThanBufferSize() throws Exception
|
||||
{
|
||||
QueuedThreadPool threadPool = new QueuedThreadPool();
|
||||
int bufferSize = 512;
|
||||
WebSocketClientFactory factory = new WebSocketClientFactory(new QueuedThreadPool(), new ZeroMaskGen(), bufferSize);
|
||||
WebSocketClientFactory factory = new WebSocketClientFactory(threadPool, new ZeroMaskGen(), bufferSize);
|
||||
threadPool.start();
|
||||
factory.start();
|
||||
WebSocketClient client = new WebSocketClient(factory);
|
||||
|
||||
|
@ -118,6 +120,7 @@ public class WebSocketClientTest
|
|||
Assert.assertTrue(dataLatch.await(1000, TimeUnit.SECONDS));
|
||||
|
||||
factory.stop();
|
||||
threadPool.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.jetty.websocket;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
|
@ -28,11 +26,9 @@ import java.util.concurrent.CountDownLatch;
|
|||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eclipse.jetty.io.Buffer;
|
||||
import org.eclipse.jetty.io.bio.SocketEndPoint;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
|
@ -45,7 +41,9 @@ import org.junit.AfterClass;
|
|||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class WebSocketLoadD13Test
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class WebSocketLoadRFC6455Test
|
||||
{
|
||||
private static Server _server;
|
||||
private static Connector _connector;
|
||||
|
@ -127,7 +125,7 @@ public class WebSocketLoadD13Test
|
|||
{
|
||||
this.outbound = outbound;
|
||||
}
|
||||
|
||||
|
||||
public void onMessage(String data)
|
||||
{
|
||||
try
|
||||
|
@ -155,7 +153,7 @@ public class WebSocketLoadD13Test
|
|||
private final CountDownLatch latch;
|
||||
private final SocketEndPoint _endp;
|
||||
private final WebSocketGeneratorRFC6455 _generator;
|
||||
private final WebSocketParserD13 _parser;
|
||||
private final WebSocketParserRFC6455 _parser;
|
||||
private final WebSocketParser.FrameHandler _handler = new WebSocketParser.FrameHandler()
|
||||
{
|
||||
public void onFrame(byte flags, byte opcode, Buffer buffer)
|
||||
|
@ -168,7 +166,7 @@ public class WebSocketLoadD13Test
|
|||
}
|
||||
};
|
||||
private volatile Buffer _response;
|
||||
|
||||
|
||||
public WebSocketClient(String host, int port, int readTimeout, CountDownLatch latch, int iterations) throws IOException
|
||||
{
|
||||
this.latch = latch;
|
||||
|
@ -177,11 +175,11 @@ public class WebSocketLoadD13Test
|
|||
output = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "ISO-8859-1"));
|
||||
input = new BufferedReader(new InputStreamReader(socket.getInputStream(), "ISO-8859-1"));
|
||||
this.iterations = iterations;
|
||||
|
||||
|
||||
_endp=new SocketEndPoint(socket);
|
||||
_generator = new WebSocketGeneratorRFC6455(new WebSocketBuffers(32*1024),_endp,new FixedMaskGen());
|
||||
_parser = new WebSocketParserD13(new WebSocketBuffers(32*1024),_endp,_handler,false);
|
||||
|
||||
_parser = new WebSocketParserRFC6455(new WebSocketBuffers(32*1024),_endp,_handler,false);
|
||||
|
||||
}
|
||||
|
||||
private void open() throws IOException
|
||||
|
@ -216,9 +214,9 @@ public class WebSocketLoadD13Test
|
|||
byte[] data = message.getBytes(StringUtil.__UTF8);
|
||||
_generator.addFrame((byte)0x8,WebSocketConnectionRFC6455.OP_TEXT,data,0,data.length);
|
||||
_generator.flush();
|
||||
|
||||
|
||||
//System.err.println("-> "+message);
|
||||
|
||||
|
||||
_response=null;
|
||||
while(_response==null)
|
||||
_parser.parseNext();
|
|
@ -15,8 +15,6 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.jetty.websocket;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
@ -30,11 +28,9 @@ import java.util.concurrent.atomic.AtomicLong;
|
|||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.zip.Deflater;
|
||||
import java.util.zip.Inflater;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eclipse.jetty.io.Buffer;
|
||||
import org.eclipse.jetty.io.ByteArrayEndPoint;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
|
@ -48,6 +44,10 @@ import org.junit.AfterClass;
|
|||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class WebSocketMessageRFC6455Test
|
||||
{
|
||||
private static Server __server;
|
||||
|
@ -78,7 +78,7 @@ public class WebSocketMessageRFC6455Test
|
|||
}
|
||||
};
|
||||
wsHandler.getWebSocketFactory().setBufferSize(8192);
|
||||
wsHandler.getWebSocketFactory().setMaxIdleTime(1000);
|
||||
wsHandler.getWebSocketFactory().setMaxIdleTime(1000);
|
||||
wsHandler.setHandler(new DefaultHandler());
|
||||
__server.setHandler(wsHandler);
|
||||
__server.start();
|
||||
|
@ -91,13 +91,13 @@ public class WebSocketMessageRFC6455Test
|
|||
__server.join();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testHash()
|
||||
{
|
||||
assertEquals("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",WebSocketConnectionRFC6455.hashKey("dGhlIHNhbXBsZSBub25jZQ=="));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testServerSendBigStringMessage() throws Exception
|
||||
{
|
||||
|
@ -119,7 +119,7 @@ public class WebSocketMessageRFC6455Test
|
|||
socket.setSoTimeout(1000);
|
||||
|
||||
InputStream input = socket.getInputStream();
|
||||
|
||||
|
||||
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
|
||||
skipTo("Sec-WebSocket-Accept: ",input);
|
||||
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
|
||||
|
@ -127,7 +127,7 @@ public class WebSocketMessageRFC6455Test
|
|||
|
||||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
||||
assertNotNull(__serverWebSocket.connection);
|
||||
|
||||
|
||||
// Server sends a big message
|
||||
StringBuilder message = new StringBuilder();
|
||||
String text = "0123456789ABCDEF";
|
||||
|
@ -167,7 +167,7 @@ public class WebSocketMessageRFC6455Test
|
|||
socket.setSoTimeout(1000);
|
||||
|
||||
InputStream input = socket.getInputStream();
|
||||
|
||||
|
||||
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
|
||||
skipTo("Sec-WebSocket-Accept: ",input);
|
||||
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
|
||||
|
@ -175,7 +175,7 @@ public class WebSocketMessageRFC6455Test
|
|||
|
||||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
||||
assertNotNull(__serverWebSocket.connection);
|
||||
|
||||
|
||||
assertEquals(0x81,input.read());
|
||||
assertEquals(0x0f,input.read());
|
||||
lookFor("sent on connect",input);
|
||||
|
@ -312,8 +312,8 @@ public class WebSocketMessageRFC6455Test
|
|||
|
||||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
||||
assertNotNull(__serverWebSocket.connection);
|
||||
|
||||
|
||||
|
||||
|
||||
// Server sends a big message
|
||||
String text = "0123456789ABCDEF ";
|
||||
text=text+text+text+text;
|
||||
|
@ -324,15 +324,15 @@ public class WebSocketMessageRFC6455Test
|
|||
deflater.setInput(data);
|
||||
deflater.finish();
|
||||
byte[] buf=new byte[data.length];
|
||||
|
||||
|
||||
buf[0]=(byte)((byte)0x7e);
|
||||
buf[1]=(byte)(data.length>>8);
|
||||
buf[2]=(byte)(data.length&0xff);
|
||||
|
||||
|
||||
int l=deflater.deflate(buf,3,buf.length-3);
|
||||
|
||||
assertTrue(deflater.finished());
|
||||
|
||||
|
||||
output.write(0xC1);
|
||||
output.write((byte)(0x80|(0xff&(l+3))));
|
||||
output.write(0x00);
|
||||
|
@ -341,41 +341,41 @@ public class WebSocketMessageRFC6455Test
|
|||
output.write(0x00);
|
||||
output.write(buf,0,l+3);
|
||||
output.flush();
|
||||
|
||||
|
||||
assertEquals(0x40+WebSocketConnectionRFC6455.OP_TEXT,input.read());
|
||||
assertEquals(0x20+3,input.read());
|
||||
assertEquals(0x7e,input.read());
|
||||
assertEquals(0x02,input.read());
|
||||
assertEquals(0x20,input.read());
|
||||
|
||||
|
||||
byte[] raw = new byte[32];
|
||||
assertEquals(32,input.read(raw));
|
||||
|
||||
|
||||
Inflater inflater = new Inflater();
|
||||
inflater.setInput(raw);
|
||||
|
||||
|
||||
byte[] result = new byte[544];
|
||||
assertEquals(544,inflater.inflate(result));
|
||||
assertEquals(TypeUtil.toHexString(data,0,544),TypeUtil.toHexString(result));
|
||||
|
||||
|
||||
|
||||
assertEquals((byte)0xC0,(byte)input.read());
|
||||
assertEquals(0x21+3,input.read());
|
||||
assertEquals(0x7e,input.read());
|
||||
assertEquals(0x02,input.read());
|
||||
assertEquals(0x21,input.read());
|
||||
|
||||
|
||||
assertEquals(32,input.read(raw));
|
||||
|
||||
|
||||
inflater.reset();
|
||||
inflater.setInput(raw);
|
||||
result = new byte[545];
|
||||
assertEquals(545,inflater.inflate(result));
|
||||
assertEquals(TypeUtil.toHexString(data,544,545),TypeUtil.toHexString(result));
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testServerEcho() throws Exception
|
||||
{
|
||||
|
@ -403,10 +403,10 @@ public class WebSocketMessageRFC6455Test
|
|||
output.write(bytes[i]^0xff);
|
||||
output.flush();
|
||||
// Make sure the read times out if there are problems with the implementation
|
||||
socket.setSoTimeout(1000);
|
||||
socket.setSoTimeout(1000);
|
||||
|
||||
InputStream input = socket.getInputStream();
|
||||
|
||||
|
||||
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
|
||||
skipTo("Sec-WebSocket-Accept: ",input);
|
||||
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
|
||||
|
@ -414,12 +414,12 @@ public class WebSocketMessageRFC6455Test
|
|||
|
||||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
||||
assertNotNull(__serverWebSocket.connection);
|
||||
|
||||
|
||||
assertEquals(0x84,input.read());
|
||||
assertEquals(0x0f,input.read());
|
||||
lookFor("this is an echo",input);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testBlockedConsumer() throws Exception
|
||||
{
|
||||
|
@ -436,7 +436,7 @@ public class WebSocketMessageRFC6455Test
|
|||
mesg[5]=(byte)0xff;
|
||||
for (int i=0;i<bytes.length;i++)
|
||||
mesg[6+i]=(byte)(bytes[i]^0xff);
|
||||
|
||||
|
||||
final int count = 100000;
|
||||
|
||||
output.write(
|
||||
|
@ -489,7 +489,7 @@ public class WebSocketMessageRFC6455Test
|
|||
}
|
||||
}
|
||||
}.start();
|
||||
|
||||
|
||||
// Send enough messages to fill receive buffer
|
||||
long max=0;
|
||||
long start=System.currentTimeMillis();
|
||||
|
@ -500,7 +500,7 @@ public class WebSocketMessageRFC6455Test
|
|||
{
|
||||
// System.err.println(">>> "+i);
|
||||
output.flush();
|
||||
|
||||
|
||||
long now=System.currentTimeMillis();
|
||||
long duration=now-start;
|
||||
start=now;
|
||||
|
@ -518,13 +518,13 @@ public class WebSocketMessageRFC6455Test
|
|||
assertEquals(count+1,__textCount.get()); // all messages
|
||||
assertTrue(max>2000); // was blocked
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testBlockedProducer() throws Exception
|
||||
{
|
||||
final Socket socket = new Socket("localhost", __connector.getLocalPort());
|
||||
OutputStream output = socket.getOutputStream();
|
||||
|
||||
|
||||
final int count = 100000;
|
||||
|
||||
output.write(
|
||||
|
@ -581,8 +581,8 @@ public class WebSocketMessageRFC6455Test
|
|||
}
|
||||
}
|
||||
}.start();
|
||||
|
||||
|
||||
|
||||
|
||||
// Send enough messages to fill receive buffer
|
||||
long max=0;
|
||||
long start=System.currentTimeMillis();
|
||||
|
@ -593,7 +593,7 @@ public class WebSocketMessageRFC6455Test
|
|||
if (i%100==0)
|
||||
{
|
||||
output.flush();
|
||||
|
||||
|
||||
long now=System.currentTimeMillis();
|
||||
long duration=now-start;
|
||||
start=now;
|
||||
|
@ -601,10 +601,10 @@ public class WebSocketMessageRFC6455Test
|
|||
max=duration;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
while(totalB.get()<(count*(mesg.length()+2)))
|
||||
Thread.sleep(100);
|
||||
|
||||
|
||||
assertEquals(count*(mesg.length()+2),totalB.get()); // all messages
|
||||
assertTrue(max>1000); // was blocked
|
||||
}
|
||||
|
@ -635,7 +635,7 @@ public class WebSocketMessageRFC6455Test
|
|||
output.flush();
|
||||
|
||||
InputStream input = socket.getInputStream();
|
||||
|
||||
|
||||
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
|
||||
skipTo("Sec-WebSocket-Accept: ",input);
|
||||
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
|
||||
|
@ -668,7 +668,7 @@ public class WebSocketMessageRFC6455Test
|
|||
|
||||
socket.setSoTimeout(1000);
|
||||
InputStream input = socket.getInputStream();
|
||||
|
||||
|
||||
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
|
||||
skipTo("Sec-WebSocket-Accept: ",input);
|
||||
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
|
||||
|
@ -676,10 +676,10 @@ public class WebSocketMessageRFC6455Test
|
|||
|
||||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
||||
assertNotNull(__serverWebSocket.connection);
|
||||
|
||||
|
||||
__serverWebSocket.getConnection().setMaxTextMessageSize(10*1024);
|
||||
__serverWebSocket.getConnection().setAllowFrameFragmentation(true);
|
||||
|
||||
|
||||
output.write(0x81);
|
||||
output.write(0x80|0x7E);
|
||||
output.write((byte)((16*1024)>>8));
|
||||
|
@ -692,7 +692,7 @@ public class WebSocketMessageRFC6455Test
|
|||
for (int i=0;i<(16*1024);i++)
|
||||
output.write('X');
|
||||
output.flush();
|
||||
|
||||
|
||||
|
||||
assertEquals(0x80|WebSocketConnectionRFC6455.OP_CLOSE,input.read());
|
||||
assertEquals(33,input.read());
|
||||
|
@ -720,7 +720,7 @@ public class WebSocketMessageRFC6455Test
|
|||
|
||||
socket.setSoTimeout(1000);
|
||||
InputStream input = socket.getInputStream();
|
||||
|
||||
|
||||
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
|
||||
skipTo("Sec-WebSocket-Accept: ",input);
|
||||
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
|
||||
|
@ -728,9 +728,9 @@ public class WebSocketMessageRFC6455Test
|
|||
|
||||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
||||
assertNotNull(__serverWebSocket.connection);
|
||||
|
||||
|
||||
__serverWebSocket.getConnection().setMaxTextMessageSize(15);
|
||||
|
||||
|
||||
output.write(0x01);
|
||||
output.write(0x8a);
|
||||
output.write(0xff);
|
||||
|
@ -779,7 +779,7 @@ public class WebSocketMessageRFC6455Test
|
|||
|
||||
socket.setSoTimeout(100000);
|
||||
InputStream input = socket.getInputStream();
|
||||
|
||||
|
||||
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
|
||||
skipTo("Sec-WebSocket-Accept: ",input);
|
||||
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
|
||||
|
@ -787,9 +787,9 @@ public class WebSocketMessageRFC6455Test
|
|||
|
||||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
||||
assertNotNull(__serverWebSocket.connection);
|
||||
|
||||
|
||||
__serverWebSocket.getConnection().setMaxTextMessageSize(15);
|
||||
|
||||
|
||||
output.write(0x01);
|
||||
output.write(0x94);
|
||||
output.write(0xff);
|
||||
|
@ -800,9 +800,9 @@ public class WebSocketMessageRFC6455Test
|
|||
for (int i=0;i<bytes.length;i++)
|
||||
output.write(bytes[i]^0xff);
|
||||
output.flush();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
assertEquals(0x80|WebSocketConnectionRFC6455.OP_CLOSE,input.read());
|
||||
assertEquals(30,input.read());
|
||||
int code=(0xff&input.read())*0x100+(0xff&input.read());
|
||||
|
@ -829,7 +829,7 @@ public class WebSocketMessageRFC6455Test
|
|||
|
||||
socket.setSoTimeout(1000);
|
||||
InputStream input = socket.getInputStream();
|
||||
|
||||
|
||||
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
|
||||
skipTo("Sec-WebSocket-Accept: ",input);
|
||||
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
|
||||
|
@ -838,7 +838,7 @@ public class WebSocketMessageRFC6455Test
|
|||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
||||
assertNotNull(__serverWebSocket.connection);
|
||||
__serverWebSocket.getConnection().setMaxBinaryMessageSize(1024);
|
||||
|
||||
|
||||
output.write(WebSocketConnectionRFC6455.OP_BINARY);
|
||||
output.write(0x8a);
|
||||
output.write(0xff);
|
||||
|
@ -859,12 +859,12 @@ public class WebSocketMessageRFC6455Test
|
|||
for (int i=0;i<bytes.length;i++)
|
||||
output.write(bytes[i]^0xff);
|
||||
output.flush();
|
||||
|
||||
|
||||
assertEquals(0x80+WebSocketConnectionRFC6455.OP_BINARY,input.read());
|
||||
assertEquals(20,input.read());
|
||||
lookFor("01234567890123456789",input);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testMaxBinarySize() throws Exception
|
||||
{
|
||||
|
@ -884,7 +884,7 @@ public class WebSocketMessageRFC6455Test
|
|||
|
||||
socket.setSoTimeout(100000);
|
||||
InputStream input = socket.getInputStream();
|
||||
|
||||
|
||||
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
|
||||
skipTo("Sec-WebSocket-Accept: ",input);
|
||||
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
|
||||
|
@ -892,9 +892,9 @@ public class WebSocketMessageRFC6455Test
|
|||
|
||||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
||||
assertNotNull(__serverWebSocket.connection);
|
||||
|
||||
|
||||
__serverWebSocket.getConnection().setMaxBinaryMessageSize(15);
|
||||
|
||||
|
||||
output.write(0x02);
|
||||
output.write(0x8a);
|
||||
output.write(0xff);
|
||||
|
@ -916,20 +916,20 @@ public class WebSocketMessageRFC6455Test
|
|||
output.write(bytes[i]^0xff);
|
||||
output.flush();
|
||||
|
||||
|
||||
|
||||
assertEquals(0x80|WebSocketConnectionRFC6455.OP_CLOSE,input.read());
|
||||
assertEquals(19,input.read());
|
||||
int code=(0xff&input.read())*0x100+(0xff&input.read());
|
||||
assertEquals(WebSocketConnectionRFC6455.CLOSE_MESSAGE_TOO_LARGE,code);
|
||||
lookFor("Message size > 15",input);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testCloseIn() throws Exception
|
||||
{
|
||||
int[][] tests =
|
||||
int[][] tests =
|
||||
{
|
||||
{-1,0,-1},
|
||||
{-1,0,-1},
|
||||
|
@ -960,7 +960,7 @@ public class WebSocketMessageRFC6455Test
|
|||
"",
|
||||
"mesg"
|
||||
};
|
||||
|
||||
|
||||
String[] resp =
|
||||
{
|
||||
"",
|
||||
|
@ -1007,14 +1007,14 @@ public class WebSocketMessageRFC6455Test
|
|||
|
||||
int code=tests[t][0];
|
||||
String m=mesg[t];
|
||||
|
||||
|
||||
output.write(0x88);
|
||||
output.write(0x80 + (code<=0?0:(2+m.length())));
|
||||
output.write(0x00);
|
||||
output.write(0x00);
|
||||
output.write(0x00);
|
||||
output.write(0x00);
|
||||
|
||||
|
||||
if (code>0)
|
||||
{
|
||||
output.write(code/0x100);
|
||||
|
@ -1022,12 +1022,12 @@ public class WebSocketMessageRFC6455Test
|
|||
output.write(m.getBytes());
|
||||
}
|
||||
output.flush();
|
||||
|
||||
|
||||
__serverWebSocket.awaitDisconnected(1000);
|
||||
|
||||
byte[] buf = new byte[128];
|
||||
int len = input.read(buf);
|
||||
|
||||
|
||||
assertEquals(tst,2+tests[t][1],len);
|
||||
assertEquals(tst,(byte)0x88,buf[0]);
|
||||
|
||||
|
@ -1035,7 +1035,7 @@ public class WebSocketMessageRFC6455Test
|
|||
{
|
||||
code=(0xff&buf[2])*0x100+(0xff&buf[3]);
|
||||
assertEquals(tst,tests[t][2],code);
|
||||
|
||||
|
||||
if (len>4)
|
||||
{
|
||||
m = new String(buf,4,len-4,"UTF-8");
|
||||
|
@ -1044,19 +1044,19 @@ public class WebSocketMessageRFC6455Test
|
|||
}
|
||||
else
|
||||
assertEquals(tst,tests[t][2],-1);
|
||||
|
||||
|
||||
|
||||
len = input.read(buf);
|
||||
assertEquals(tst,-1,len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testCloseOut() throws Exception
|
||||
{
|
||||
int[][] tests =
|
||||
int[][] tests =
|
||||
{
|
||||
{-1,0,-1},
|
||||
{-1,0,-1},
|
||||
|
@ -1127,7 +1127,7 @@ public class WebSocketMessageRFC6455Test
|
|||
{
|
||||
int code=(0xff&buf[2])*0x100+(0xff&buf[3]);
|
||||
assertEquals(tst,tests[t][2],code);
|
||||
|
||||
|
||||
if (len>4)
|
||||
{
|
||||
String m = new String(buf,4,len-4,"UTF-8");
|
||||
|
@ -1136,7 +1136,7 @@ public class WebSocketMessageRFC6455Test
|
|||
}
|
||||
else
|
||||
assertEquals(tst,tests[t][2],-1);
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
output.write(0x88);
|
||||
|
@ -1152,12 +1152,12 @@ public class WebSocketMessageRFC6455Test
|
|||
System.err.println("socket "+socket);
|
||||
throw e;
|
||||
}
|
||||
|
||||
|
||||
len = input.read(buf);
|
||||
assertEquals(tst,-1,len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testNotUTF8() throws Exception
|
||||
|
@ -1225,7 +1225,7 @@ public class WebSocketMessageRFC6455Test
|
|||
|
||||
socket.setSoTimeout(100000);
|
||||
InputStream input = socket.getInputStream();
|
||||
|
||||
|
||||
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
|
||||
skipTo("Sec-WebSocket-Accept: ",input);
|
||||
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
|
||||
|
@ -1233,9 +1233,9 @@ public class WebSocketMessageRFC6455Test
|
|||
|
||||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
||||
assertNotNull(__serverWebSocket.connection);
|
||||
|
||||
|
||||
__serverWebSocket.getConnection().setMaxBinaryMessageSize(15);
|
||||
|
||||
|
||||
output.write(0x02);
|
||||
output.write(0x94);
|
||||
output.write(0xff);
|
||||
|
@ -1246,7 +1246,7 @@ public class WebSocketMessageRFC6455Test
|
|||
for (int i=0;i<bytes.length;i++)
|
||||
output.write(bytes[i]^0xff);
|
||||
output.flush();
|
||||
|
||||
|
||||
assertEquals(0x80|WebSocketConnectionRFC6455.OP_CLOSE,input.read());
|
||||
assertEquals(19,input.read());
|
||||
int code=(0xff&input.read())*0x100+(0xff&input.read());
|
||||
|
@ -1283,7 +1283,7 @@ public class WebSocketMessageRFC6455Test
|
|||
|
||||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
||||
assertNotNull(__serverWebSocket.connection);
|
||||
|
||||
|
||||
assertEquals(0x81,input.read());
|
||||
assertEquals(0x0f,input.read());
|
||||
lookFor("sent on connect",input);
|
||||
|
@ -1302,8 +1302,8 @@ public class WebSocketMessageRFC6455Test
|
|||
output.write(0xff);
|
||||
output.write(0xff);
|
||||
output.flush();
|
||||
|
||||
|
||||
|
||||
|
||||
assertTrue(__serverWebSocket.awaitDisconnected(5000));
|
||||
try
|
||||
{
|
||||
|
@ -1346,12 +1346,12 @@ public class WebSocketMessageRFC6455Test
|
|||
|
||||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
||||
assertNotNull(__serverWebSocket.connection);
|
||||
|
||||
|
||||
assertEquals(0x81,input.read());
|
||||
assertEquals(0x0f,input.read());
|
||||
lookFor("sent on connect",input);
|
||||
socket.close();
|
||||
|
||||
|
||||
assertTrue(__serverWebSocket.awaitDisconnected(500));
|
||||
|
||||
try
|
||||
|
@ -1362,7 +1362,7 @@ public class WebSocketMessageRFC6455Test
|
|||
catch(IOException e)
|
||||
{
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1395,19 +1395,19 @@ public class WebSocketMessageRFC6455Test
|
|||
|
||||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
||||
assertNotNull(__serverWebSocket.connection);
|
||||
|
||||
|
||||
assertEquals(0x81,input.read());
|
||||
assertEquals(0x0f,input.read());
|
||||
lookFor("sent on connect",input);
|
||||
|
||||
|
||||
socket.shutdownOutput();
|
||||
|
||||
|
||||
assertTrue(__serverWebSocket.awaitDisconnected(500));
|
||||
|
||||
assertEquals(0x88,input.read());
|
||||
assertEquals(0x00,input.read());
|
||||
assertEquals(-1,input.read());
|
||||
|
||||
|
||||
// look for broken pipe
|
||||
try
|
||||
{
|
||||
|
@ -1420,24 +1420,24 @@ public class WebSocketMessageRFC6455Test
|
|||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testParserAndGenerator() throws Exception
|
||||
{
|
||||
String message = "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF";
|
||||
final AtomicReference<String> received = new AtomicReference<String>();
|
||||
ByteArrayEndPoint endp = new ByteArrayEndPoint(new byte[0],4096);
|
||||
|
||||
|
||||
WebSocketGeneratorRFC6455 gen = new WebSocketGeneratorRFC6455(new WebSocketBuffers(8096),endp,null);
|
||||
|
||||
|
||||
byte[] data = message.getBytes(StringUtil.__UTF8);
|
||||
gen.addFrame((byte)0x8,(byte)0x4,data,0,data.length);
|
||||
|
||||
|
||||
endp = new ByteArrayEndPoint(endp.getOut().asArray(),4096);
|
||||
|
||||
WebSocketParserD13 parser = new WebSocketParserD13(new WebSocketBuffers(8096),endp,new WebSocketParser.FrameHandler()
|
||||
|
||||
WebSocketParserRFC6455 parser = new WebSocketParserRFC6455(new WebSocketBuffers(8096),endp,new WebSocketParser.FrameHandler()
|
||||
{
|
||||
public void onFrame(byte flags, byte opcode, Buffer buffer)
|
||||
{
|
||||
|
@ -1449,12 +1449,12 @@ public class WebSocketMessageRFC6455Test
|
|||
}
|
||||
|
||||
},false);
|
||||
|
||||
|
||||
parser.parseNext();
|
||||
|
||||
|
||||
assertEquals(message,received.get());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testParserAndGeneratorMasked() throws Exception
|
||||
{
|
||||
|
@ -1463,14 +1463,14 @@ public class WebSocketMessageRFC6455Test
|
|||
ByteArrayEndPoint endp = new ByteArrayEndPoint(new byte[0],4096);
|
||||
|
||||
MaskGen maskGen = new RandomMaskGen();
|
||||
|
||||
|
||||
WebSocketGeneratorRFC6455 gen = new WebSocketGeneratorRFC6455(new WebSocketBuffers(8096),endp,maskGen);
|
||||
byte[] data = message.getBytes(StringUtil.__UTF8);
|
||||
gen.addFrame((byte)0x8,(byte)0x1,data,0,data.length);
|
||||
|
||||
|
||||
endp = new ByteArrayEndPoint(endp.getOut().asArray(),4096);
|
||||
|
||||
WebSocketParserD13 parser = new WebSocketParserD13(new WebSocketBuffers(8096),endp,new WebSocketParser.FrameHandler()
|
||||
|
||||
WebSocketParserRFC6455 parser = new WebSocketParserRFC6455(new WebSocketBuffers(8096),endp,new WebSocketParser.FrameHandler()
|
||||
{
|
||||
public void onFrame(byte flags, byte opcode, Buffer buffer)
|
||||
{
|
||||
|
@ -1481,13 +1481,13 @@ public class WebSocketMessageRFC6455Test
|
|||
{
|
||||
}
|
||||
},true);
|
||||
|
||||
|
||||
parser.parseNext();
|
||||
|
||||
|
||||
assertEquals(message,received.get());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void lookFor(String string,InputStream in)
|
||||
throws IOException
|
||||
{
|
||||
|
@ -1535,7 +1535,7 @@ public class WebSocketMessageRFC6455Test
|
|||
state=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static class TestWebSocket implements WebSocket.OnFrame, WebSocket.OnBinaryMessage, WebSocket.OnTextMessage
|
||||
{
|
||||
|
@ -1556,7 +1556,7 @@ public class WebSocketMessageRFC6455Test
|
|||
{
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
|
||||
public void onOpen(Connection connection)
|
||||
{
|
||||
if (_onConnect)
|
||||
|
@ -1582,14 +1582,14 @@ public class WebSocketMessageRFC6455Test
|
|||
{
|
||||
return disconnected.await(time, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
|
||||
public void onClose(int code,String message)
|
||||
{
|
||||
disconnected.countDown();
|
||||
}
|
||||
|
||||
public boolean onFrame(byte flags, byte opcode, byte[] data, int offset, int length)
|
||||
{
|
||||
{
|
||||
if (_echo)
|
||||
{
|
||||
switch(opcode)
|
||||
|
@ -1598,7 +1598,7 @@ public class WebSocketMessageRFC6455Test
|
|||
case WebSocketConnectionRFC6455.OP_PING:
|
||||
case WebSocketConnectionRFC6455.OP_PONG:
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
try
|
||||
{
|
||||
|
@ -1642,7 +1642,7 @@ public class WebSocketMessageRFC6455Test
|
|||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (_aggregate)
|
||||
{
|
||||
try
|
||||
|
|
|
@ -35,6 +35,8 @@ public class WebSocketOverSSLTest
|
|||
{
|
||||
private Server _server;
|
||||
private int _port;
|
||||
private QueuedThreadPool _threadPool;
|
||||
private WebSocketClientFactory _wsFactory;
|
||||
private WebSocket.Connection _connection;
|
||||
|
||||
private void startServer(final WebSocket webSocket) throws Exception
|
||||
|
@ -61,13 +63,18 @@ public class WebSocketOverSSLTest
|
|||
{
|
||||
Assert.assertTrue(_server.isStarted());
|
||||
|
||||
WebSocketClientFactory factory = new WebSocketClientFactory(new QueuedThreadPool(), new ZeroMaskGen());
|
||||
SslContextFactory cf = factory.getSslContextFactory();
|
||||
_threadPool = new QueuedThreadPool();
|
||||
_threadPool.setName("wsc-" + _threadPool.getName());
|
||||
_threadPool.start();
|
||||
|
||||
_wsFactory = new WebSocketClientFactory(_threadPool, new ZeroMaskGen());
|
||||
SslContextFactory cf = _wsFactory.getSslContextFactory();
|
||||
cf.setKeyStorePath(MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath());
|
||||
cf.setKeyStorePassword("storepwd");
|
||||
cf.setKeyManagerPassword("keypwd");
|
||||
factory.start();
|
||||
WebSocketClient client = new WebSocketClient(factory);
|
||||
_wsFactory.start();
|
||||
|
||||
WebSocketClient client = new WebSocketClient(_wsFactory);
|
||||
_connection = client.open(new URI("wss://localhost:" + _port), webSocket).get(5, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
|
@ -76,6 +83,13 @@ public class WebSocketOverSSLTest
|
|||
{
|
||||
if (_connection != null)
|
||||
_connection.close();
|
||||
|
||||
if (_wsFactory != null)
|
||||
_wsFactory.stop();
|
||||
|
||||
if (_threadPool != null)
|
||||
_threadPool.stop();
|
||||
|
||||
if (_server != null)
|
||||
{
|
||||
_server.stop();
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.jetty.websocket;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -30,12 +28,16 @@ import org.eclipse.jetty.util.Utf8StringBuilder;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class WebSocketParserRFC6455Test
|
||||
{
|
||||
private ByteArrayEndPoint _endPoint;
|
||||
private MaskedByteArrayBuffer _in;
|
||||
private Handler _handler;
|
||||
private WebSocketParserD13 _parser;
|
||||
private WebSocketParserRFC6455 _parser;
|
||||
private byte[] _mask = new byte[] {(byte)0x00,(byte)0xF0,(byte)0x0F,(byte)0xFF};
|
||||
private int _m;
|
||||
|
||||
|
@ -45,7 +47,7 @@ public class WebSocketParserRFC6455Test
|
|||
{
|
||||
super(4096);
|
||||
}
|
||||
|
||||
|
||||
public void sendMask()
|
||||
{
|
||||
super.poke(putIndex(),_mask,0,4);
|
||||
|
@ -63,7 +65,7 @@ public class WebSocketParserRFC6455Test
|
|||
{
|
||||
super.put(b);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void put(byte b)
|
||||
{
|
||||
|
@ -87,10 +89,10 @@ public class WebSocketParserRFC6455Test
|
|||
{
|
||||
return put(b,0,b.length);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
|
@ -98,10 +100,10 @@ public class WebSocketParserRFC6455Test
|
|||
_endPoint = new ByteArrayEndPoint();
|
||||
_endPoint.setNonBlocking(true);
|
||||
_handler = new Handler();
|
||||
_parser=new WebSocketParserD13(buffers, _endPoint,_handler,true);
|
||||
_parser=new WebSocketParserRFC6455(buffers, _endPoint,_handler,true);
|
||||
_parser.setFakeFragments(false);
|
||||
_in = new MaskedByteArrayBuffer();
|
||||
|
||||
|
||||
_endPoint.setIn(_in);
|
||||
}
|
||||
|
||||
|
@ -127,7 +129,7 @@ public class WebSocketParserRFC6455Test
|
|||
_parser.returnBuffer();
|
||||
assertTrue(_parser.getBuffer()==null);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testShortText() throws Exception
|
||||
{
|
||||
|
@ -147,7 +149,7 @@ public class WebSocketParserRFC6455Test
|
|||
_parser.returnBuffer();
|
||||
assertTrue(_parser.getBuffer()==null);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testShortUtf8() throws Exception
|
||||
{
|
||||
|
@ -169,7 +171,7 @@ public class WebSocketParserRFC6455Test
|
|||
assertTrue(_parser.isBufferEmpty());
|
||||
assertTrue(_parser.getBuffer()==null);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testMediumText() throws Exception
|
||||
{
|
||||
|
@ -177,9 +179,9 @@ public class WebSocketParserRFC6455Test
|
|||
for (int i=0;i<4;i++)
|
||||
string = string+string;
|
||||
string += ". The end.";
|
||||
|
||||
|
||||
byte[] bytes = string.getBytes(StringUtil.__UTF8);
|
||||
|
||||
|
||||
_in.putUnmasked((byte)0x81);
|
||||
_in.putUnmasked((byte)(0x80|0x7E));
|
||||
_in.putUnmasked((byte)(bytes.length>>8));
|
||||
|
@ -197,21 +199,21 @@ public class WebSocketParserRFC6455Test
|
|||
assertTrue(_parser.isBufferEmpty());
|
||||
assertTrue(_parser.getBuffer()==null);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLongText() throws Exception
|
||||
{
|
||||
WebSocketBuffers buffers = new WebSocketBuffers(0x20000);
|
||||
ByteArrayEndPoint endPoint = new ByteArrayEndPoint();
|
||||
WebSocketParserD13 parser=new WebSocketParserD13(buffers, endPoint,_handler,false);
|
||||
WebSocketParserRFC6455 parser=new WebSocketParserRFC6455(buffers, endPoint,_handler,false);
|
||||
ByteArrayBuffer in = new ByteArrayBuffer(0x20000);
|
||||
endPoint.setIn(in);
|
||||
|
||||
|
||||
String string = "Hell\uFF4f Big W\uFF4Frld ";
|
||||
for (int i=0;i<12;i++)
|
||||
string = string+string;
|
||||
string += ". The end.";
|
||||
|
||||
|
||||
byte[] bytes = string.getBytes("UTF-8");
|
||||
|
||||
_in.sendMask();
|
||||
|
@ -269,7 +271,7 @@ public class WebSocketParserRFC6455Test
|
|||
{
|
||||
// Buffers are only 1024, so this frame is too large
|
||||
_parser.setFakeFragments(false);
|
||||
|
||||
|
||||
_in.putUnmasked((byte)0x81);
|
||||
_in.putUnmasked((byte)(0x80|0x7E));
|
||||
_in.putUnmasked((byte)(2048>>8));
|
||||
|
@ -280,8 +282,8 @@ public class WebSocketParserRFC6455Test
|
|||
|
||||
assertTrue(progress>0);
|
||||
assertEquals(WebSocketConnectionRFC6455.CLOSE_POLICY_VIOLATION,_handler._code);
|
||||
|
||||
|
||||
|
||||
|
||||
for (int i=0;i<2048;i++)
|
||||
_in.put((byte)'a');
|
||||
progress =_parser.parseNext();
|
||||
|
@ -289,7 +291,7 @@ public class WebSocketParserRFC6455Test
|
|||
assertTrue(progress>0);
|
||||
assertEquals(0,_handler._data.size());
|
||||
assertEquals(0,_handler._utf8.length());
|
||||
|
||||
|
||||
_handler._code=0;
|
||||
|
||||
_in.putUnmasked((byte)0x81);
|
||||
|
@ -310,7 +312,7 @@ public class WebSocketParserRFC6455Test
|
|||
{
|
||||
// Buffers are only 1024, so this frame will be fake fragmented
|
||||
_parser.setFakeFragments(true);
|
||||
|
||||
|
||||
_in.putUnmasked((byte)0x81);
|
||||
_in.putUnmasked((byte)(0x80|0x7E));
|
||||
_in.putUnmasked((byte)(2048>>8));
|
||||
|
@ -318,7 +320,7 @@ public class WebSocketParserRFC6455Test
|
|||
_in.sendMask();
|
||||
for (int i=0;i<2048;i++)
|
||||
_in.put((byte)('a'+i%26));
|
||||
|
||||
|
||||
int progress =_parser.parseNext();
|
||||
assertTrue(progress>0);
|
||||
|
||||
|
@ -355,21 +357,21 @@ public class WebSocketParserRFC6455Test
|
|||
_parser.returnBuffer();
|
||||
assertTrue(_parser.isBufferEmpty());
|
||||
assertTrue(_parser.getBuffer()==null);
|
||||
|
||||
|
||||
_in.clear();
|
||||
_in.put(bytes);
|
||||
_endPoint.setIn(_in);
|
||||
progress =_parser.parseNext();
|
||||
assertTrue(progress>0);
|
||||
|
||||
|
||||
_endPoint.shutdownInput();
|
||||
|
||||
|
||||
progress =_parser.parseNext();
|
||||
assertEquals(-1,progress);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private class Handler implements WebSocketParser.FrameHandler
|
||||
{
|
||||
Utf8StringBuilder _utf8 = new Utf8StringBuilder();
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue