Merge branch 'master' into release

This commit is contained in:
Jesse McConnell 2012-01-13 08:13:21 -06:00
commit 3318b0d116
105 changed files with 2769 additions and 2042 deletions

View File

@ -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.

View File

@ -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();

View File

@ -33,9 +33,9 @@ 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);

View File

@ -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);

View File

@ -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
{
}
}

View File

@ -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
{
@ -456,6 +430,5 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector,
{
return "Upgradable:"+_endp.toString();
}
}
}

View File

@ -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);
}
}

View File

@ -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,20 +701,15 @@ 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
// 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;
}
// 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);
final SSLSocket client = newClient();
@ -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));
@ -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));

View File

@ -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

View File

@ -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())

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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();
}
public Buffers getRequestBuffers();
@Override
protected void doStop()
throws Exception
{
_requestBuffers=null;
_responseBuffers=null;
}
public Buffers getResponseBuffers();
public Buffers getRequestBuffers()
{
return _requestBuffers;
}
public void setMaxBuffers(int maxBuffers);
public Buffers getResponseBuffers()
{
return _responseBuffers;
}
public void setMaxBuffers(int maxBuffers)
{
_maxBuffers = maxBuffers;
}
public int getMaxBuffers()
{
return _maxBuffers;
}
public int getMaxBuffers();
}

View File

@ -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;
}
}

View File

@ -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>

View File

@ -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);
}
}

View File

@ -92,4 +92,13 @@ public class PooledBuffers extends AbstractBuffers
_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);
}
}

View File

@ -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())

View File

@ -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);
}
}

View File

@ -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:

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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();

View File

@ -159,8 +159,6 @@ public class FormAuthModule extends BaseAuthModule
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));
}

View File

@ -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>

View File

@ -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);
}
}
/**

View File

@ -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);
}
}

View File

@ -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

View File

@ -1,3 +0,0 @@
Logger: Jetty Logging implementaton
debugEnabled: True if debug enabled
name: Logger name

View File

@ -1 +0,0 @@
StdErrLog: Log adapter that logs to stderr

View File

@ -66,7 +66,6 @@
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>${javax-mail-version}</version>
<exclusions>
<exclusion>
<groupId>javax.activation</groupId>

View File

@ -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

View File

@ -1,2 +1 @@
ThreadMonitor: Detect and report spinning and deadlocked threads

View File

@ -13,8 +13,6 @@
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;
/* ------------------------------------------------------------ */
/**
@ -98,7 +96,7 @@ public class AttrEventTriggerTest
_counter = _handler.getRequestCounter();
mBeanContainer.addBean(_counter);
_server.addBean(mBeanContainer);
_server.addBean(mBeanContainer, true);
_server.getContainer().addEventListener(mBeanContainer);
_server.start();
@ -106,7 +104,7 @@ public class AttrEventTriggerTest
_monitor = new JMXMonitor();
int port = _server.getConnectors()[0].getLocalPort();
int port = connector.getLocalPort();
_requestUrl = "http://localhost:"+port+ "/";
}

View File

@ -68,7 +68,6 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit4-version}</version>
<scope>test</scope>
</dependency>
<dependency>

View File

@ -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)

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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;

View File

@ -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;

View File

@ -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)
{

View File

@ -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
{

View File

@ -110,7 +110,6 @@
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.8.5</version>
<scope>test</scope>
</dependency>
</dependencies>

View File

@ -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");
}
}

View File

@ -185,9 +185,6 @@ public class AsyncContinuation implements AsyncContext, Continuation
}
/* ------------------------------------------------------------ */
/* (non-Javadoc)
* @see javax.servlet.ServletRequest#isSuspended()
*/
public boolean isSuspending()
{
synchronized(this)

View File

@ -45,6 +45,7 @@ public class AsyncHttpConnection extends AbstractHttpConnection implements Async
_asyncEndp=(AsyncEndPoint)endpoint;
}
@Override
public Connection handle() throws IOException
{
Connection connection = this;
@ -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;
}
}
}
@ -144,10 +145,8 @@ public class AsyncHttpConnection extends AbstractHttpConnection implements Async
// return buffers
_parser.returnBuffers();
_generator.returnBuffers();
}
if (_request.getAsyncContinuation().isComplete() || _request.getAsyncContinuation().isInitial())
{
// reenable idle checking unless request is suspended
_asyncEndp.setCheckForIdle(true);
}

View File

@ -466,7 +466,6 @@ public class Response implements HttpServletResponse
}
}
location=encodeRedirectURL(location);
resetBuffer();
setHeader(HttpHeaders.LOCATION,location);
setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);

View File

@ -75,6 +75,9 @@ 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"
*/

View File

@ -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;

View File

@ -19,18 +19,14 @@ 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);
}
/* ------------------------------------------------------------------------------- */
@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
/* ------------------------------------------------------------- */

View File

@ -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

View File

@ -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);
}

View File

@ -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;

View File

@ -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));

View File

@ -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();
}

View File

@ -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
@ -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);
}

View File

@ -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;
@ -145,6 +146,26 @@ public class RequestTest
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

View File

@ -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,7 +49,7 @@ public class SelectChannelTimeoutTest extends ConnectorTimeoutTest
_handler.setSuspendFor(100);
_handler.setResumeAfter(25);
assertTrue(process(null).toUpperCase().contains("RESUMED"));
assertTrue(process(null).toUpperCase().contains("RESUMED"));
}
@Test
@ -84,7 +83,7 @@ public class SelectChannelTimeoutTest extends ConnectorTimeoutTest
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;
}

View File

@ -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");
}
}

View File

@ -3,4 +3,3 @@ name: RO:Name
displayName: RO:Display Name
className: RO:Class Name
initParameters: RO:Initial parameters

View File

@ -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)

View File

@ -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;

View File

@ -62,7 +62,7 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool;
* <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>
@ -84,8 +84,6 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool;
*/
public class ProxyServlet implements Servlet
{
private static final Logger LOG = Log.getLogger(ProxyServlet.class);
protected Logger _log;
protected HttpClient _client;
protected String _hostHeader;
@ -129,7 +127,6 @@ public class ProxyServlet implements Servlet
if (_context != null)
{
_context.setAttribute(config.getServletName() + ".Logger",_log);
_context.setAttribute(config.getServletName() + ".ThreadPool",_client.getThreadPool());
_context.setAttribute(config.getServletName() + ".HttpClient",_client);
}
@ -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,6 +485,7 @@ public class ProxyServlet implements Servlet
_log.debug(debug + " " + name + "! " + value);
}
@Override
protected void onConnectionFailed(Throwable ex)
{
handleOnConnectionFailed(ex,request,response);
@ -493,11 +498,12 @@ 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);
@ -510,6 +516,7 @@ public class ProxyServlet implements Servlet
}
}
@Override
protected void onExpire()
{
handleOnExpire(request,response);
@ -732,8 +739,8 @@ public class ProxyServlet implements Servlet
*/
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);

View File

@ -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)

View File

@ -123,31 +123,36 @@ 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
{
// The XML Configuration Files to initialize with
@ -1075,7 +1080,7 @@ public class Main
}
catch (IOException e)
{
// usageExit(e,ERR_UNKNOWN);
usageExit(e,ERR_UNKNOWN);
}
finally
{

View File

@ -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:

View File

@ -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

View File

@ -12,83 +12,215 @@ 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)
return false;
boolean added=false;
if (!_dependentBeans.contains(o))
{
_dependentBeans.add(o);
added=true;
}
// beans are joined unless they are started lifecycles
return addBean(o,!((o instanceof LifeCycle)&&((LifeCycle)o).isStarted()));
}
try
/* ------------------------------------------------------------ */
/** 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;
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();
}
/* ------------------------------------------------------------ */
@ -97,7 +229,7 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable
*/
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");
}
/* ------------------------------------------------------------ */

View File

@ -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;
}
}

View File

@ -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)

View File

@ -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);
}
}

View File

@ -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)

View File

@ -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)

View File

@ -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;
this._level = this._configuredLevel;
// restore all cached log configured levels
for(StdErrLog log: __loggers.values())
{
log._level = log._configuredLevel;
}
for (Logger log : Log.getLoggers().values())
{
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;
}

View File

@ -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;
@ -1522,4 +1521,14 @@ public class SslContextFactory extends AbstractLifeCycle
sslEngine.setEnabledProtocols(selectProtocols(sslEngine.getEnabledProtocols(),sslEngine.getSupportedProtocols()));
}
/* ------------------------------------------------------------ */
public String toString()
{
return String.format("%s@%x(%s,%s)#%s",
getClass().getSimpleName(),
hashCode(),
_keyStorePath,
_trustStorePath,
getState());
}
}

View File

@ -363,6 +363,7 @@ public class QueuedThreadPool extends AbstractLifeCycle implements SizedThreadPo
return true;
}
}
LOG.debug("Dispatched {} to stopped {}",job,this);
return false;
}

View File

@ -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()
{
@ -160,5 +261,10 @@ public class AggregateLifeCycleTest
a2.addBean(aa0);
a0.dumpStdErr();
System.err.println("--");
a0.unmanage(aa);
a2.unmanage(aa0);
a0.dumpStdErr();
}
}

View File

@ -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

View File

@ -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()
{

View File

@ -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());
}
}

View File

@ -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();
}
/* ------------------------------------------------------------ */

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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));

View File

@ -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

View File

@ -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;
@ -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)
@ -180,7 +178,7 @@ public class WebSocketLoadD13Test
_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);
}

View File

@ -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;
@ -1437,7 +1437,7 @@ public class WebSocketMessageRFC6455Test
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)
{
@ -1470,7 +1470,7 @@ public class WebSocketMessageRFC6455Test
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)
{

View File

@ -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();

View File

@ -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;
@ -98,7 +100,7 @@ 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();
@ -203,7 +205,7 @@ public class WebSocketParserRFC6455Test
{
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);

Some files were not shown because too many files have changed in this diff Show More