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,10 +33,10 @@ public class ManyServletContexts
// Setup JMX
MBeanContainer mbContainer=new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
mbContainer.start();
server.getContainer().addEventListener(mbContainer);
server.addBean(mbContainer);
mbContainer.addBean(Log.getLog());
server.addBean(mbContainer,true);
ContextHandlerCollection contexts = new ContextHandlerCollection();
server.setHandler(contexts);

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
{
@ -451,11 +425,10 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector,
{
return _endp.isCheckForIdle();
}
public String toString()
{
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,21 +701,16 @@ public class SslBytesServerTest extends SslBytesTest
@Test
public void testRequestWithCloseAlert() throws Exception
{
if ( !OS.IS_LINUX )
{
// currently we are ignoring this test on anything other then linux
//http://tools.ietf.org/html/rfc2246#section-7.2.1
// Currently we are ignoring this test on anything other then linux
// http://tools.ietf.org/html/rfc2246#section-7.2.1
// TODO (react to this portion which seems to allow win/mac behavior)
// It is required that the other party respond with a close_notify alert of its own
// and close down the connection immediately, discarding any pending writes. It is not
// required for the initiator of the close to wait for the responding
// close_notify alert before closing the read side of the connection.
Assume.assumeTrue(OS.IS_LINUX);
// TODO (react to this portion which seems to allow win/mac behavior)
//It is required that the other party respond with a close_notify alert of its own
//and close down the connection immediately, discarding any pending writes. It is not
//required for the initiator of the close to wait for the responding
//close_notify alert before closing the read side of the connection.
return;
}
final SSLSocket client = newClient();
SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
@ -634,6 +761,7 @@ public class SslBytesServerTest extends SslBytesTest
// We can't forward to the client, its socket is already closed
// Check that we did not spin
TimeUnit.MILLISECONDS.sleep(500);
Assert.assertThat(sslHandles.get(), lessThan(20));
Assert.assertThat(sslFlushes.get(), lessThan(20));
Assert.assertThat(httpParses.get(), lessThan(50));
@ -692,6 +820,7 @@ public class SslBytesServerTest extends SslBytesTest
proxy.flushToClient(record);
// Check that we did not spin
TimeUnit.MILLISECONDS.sleep(500);
Assert.assertThat(sslHandles.get(), lessThan(20));
Assert.assertThat(sslFlushes.get(), lessThan(20));
Assert.assertThat(httpParses.get(), lessThan(50));
@ -700,7 +829,7 @@ public class SslBytesServerTest extends SslBytesTest
}
@Test
public void testRequestWithBigContentWriteBlockedAndResetException() throws Exception
public void testRequestWithBigContentWriteBlockedThenReset() throws Exception
{
final SSLSocket client = newClient();
@ -744,11 +873,63 @@ public class SslBytesServerTest extends SslBytesTest
// connection, and this will cause an exception in the
// server that is trying to write the data
proxy.resetServer();
TimeUnit.MILLISECONDS.sleep(500);
proxy.sendRSTToServer();
// Wait a while to detect spinning
TimeUnit.SECONDS.sleep(1);
TimeUnit.MILLISECONDS.sleep(500);
Assert.assertThat(sslHandles.get(), lessThan(20));
Assert.assertThat(sslFlushes.get(), lessThan(20));
Assert.assertThat(httpParses.get(), lessThan(50));
client.close();
}
@Test
public void testRequestWithBigContentReadBlockedThenReset() throws Exception
{
final SSLSocket client = newClient();
SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
client.startHandshake();
Assert.assertTrue(automaticProxyFlow.stop(5, TimeUnit.SECONDS));
byte[] data = new byte[128 * 1024];
Arrays.fill(data, (byte)'X');
final String content = new String(data, "UTF-8");
Future<Object> request = threadPool.submit(new Callable<Object>()
{
public Object call() throws Exception
{
OutputStream clientOutput = client.getOutputStream();
clientOutput.write(("" +
"GET /echo_suppress_exception HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Content-Length: " + content.length() + "\r\n" +
"\r\n" +
content).getBytes("UTF-8"));
clientOutput.flush();
return null;
}
});
// Nine TLSRecords will be generated for the request,
// but we write only 5 of them, so the server goes in read blocked state
for (int i = 0; i < 5; ++i)
{
// Application data
TLSRecord record = proxy.readFromClient();
Assert.assertEquals(TLSRecord.Type.APPLICATION, record.getType());
proxy.flushToServer(record, 0);
}
Assert.assertNull(request.get(5, TimeUnit.SECONDS));
// The server should be read blocked, and we send a RST
TimeUnit.MILLISECONDS.sleep(500);
proxy.sendRSTToServer();
// Wait a while to detect spinning
TimeUnit.MILLISECONDS.sleep(500);
Assert.assertThat(sslHandles.get(), lessThan(20));
Assert.assertThat(sslFlushes.get(), lessThan(20));
Assert.assertThat(httpParses.get(), lessThan(50));
@ -762,17 +943,17 @@ public class SslBytesServerTest extends SslBytesTest
if ( !OS.IS_LINUX )
{
// currently we are ignoring this test on anything other then linux
//http://tools.ietf.org/html/rfc2246#section-7.2.1
// TODO (react to this portion which seems to allow win/mac behavior)
//It is required that the other party respond with a close_notify alert of its own
// TODO (react to this portion which seems to allow win/mac behavior)
//It is required that the other party respond with a close_notify alert of its own
//and close down the connection immediately, discarding any pending writes. It is not
//required for the initiator of the close to wait for the responding
//close_notify alert before closing the read side of the connection.
return;
}
final SSLSocket client = newClient();
SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
@ -831,6 +1012,7 @@ public class SslBytesServerTest extends SslBytesTest
// We can't forward to the client, its socket is already closed
// Check that we did not spin
TimeUnit.MILLISECONDS.sleep(500);
Assert.assertThat(sslHandles.get(), lessThan(20));
Assert.assertThat(sslFlushes.get(), lessThan(20));
Assert.assertThat(httpParses.get(), lessThan(50));
@ -900,6 +1082,7 @@ public class SslBytesServerTest extends SslBytesTest
}
// Check that we did not spin
TimeUnit.MILLISECONDS.sleep(500);
Assert.assertThat(sslHandles.get(), lessThan(20));
Assert.assertThat(sslFlushes.get(), lessThan(20));
Assert.assertThat(httpParses.get(), lessThan(50));
@ -953,6 +1136,7 @@ public class SslBytesServerTest extends SslBytesTest
}
// Check that we did not spin
TimeUnit.MILLISECONDS.sleep(500);
Assert.assertThat(sslHandles.get(), lessThan(20));
Assert.assertThat(sslFlushes.get(), lessThan(20));
Assert.assertThat(httpParses.get(), lessThan(150));
@ -974,6 +1158,7 @@ public class SslBytesServerTest extends SslBytesTest
}
// Check that we did not spin
TimeUnit.MILLISECONDS.sleep(500);
Assert.assertThat(sslHandles.get(), lessThan(20));
Assert.assertThat(sslFlushes.get(), lessThan(20));
Assert.assertThat(httpParses.get(), lessThan(150));
@ -1105,6 +1290,7 @@ public class SslBytesServerTest extends SslBytesTest
}
// Check that we did not spin
TimeUnit.MILLISECONDS.sleep(500);
Assert.assertThat(sslHandles.get(), lessThan(20));
Assert.assertThat(sslFlushes.get(), lessThan(20));
Assert.assertThat(httpParses.get(), lessThan(50));
@ -1264,6 +1450,7 @@ public class SslBytesServerTest extends SslBytesTest
}
// Check that we did not spin
TimeUnit.MILLISECONDS.sleep(500);
Assert.assertThat(sslHandles.get(), lessThan(20));
Assert.assertThat(sslFlushes.get(), lessThan(20));
Assert.assertThat(httpParses.get(), lessThan(100));
@ -1312,7 +1499,7 @@ public class SslBytesServerTest extends SslBytesTest
// Client should close the socket, but let's hold it open.
// Check that we did not spin
TimeUnit.MILLISECONDS.sleep(100);
TimeUnit.MILLISECONDS.sleep(500);
Assert.assertThat(sslHandles.get(), lessThan(20));
Assert.assertThat(sslFlushes.get(), lessThan(20));
Assert.assertThat(httpParses.get(), lessThan(50));

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

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

@ -58,7 +58,7 @@ public abstract class AbstractBuffers implements Buffers
}
throw new IllegalStateException();
}
/* ------------------------------------------------------------ */
/**
* Create a new content Buffer
@ -77,7 +77,7 @@ public abstract class AbstractBuffers implements Buffers
}
throw new IllegalStateException();
}
/* ------------------------------------------------------------ */
/**
* Create a new content Buffer
@ -142,4 +142,9 @@ public abstract class AbstractBuffers implements Buffers
return false;
}
}
/* ------------------------------------------------------------ */
public String toString()
{
return String.format("%s [%d,%d]", getClass().getSimpleName(), _headerSize, _bufferSize);
}
}

View File

@ -25,7 +25,7 @@ public class PooledBuffers extends AbstractBuffers
_otherBuffers=bufferType==otherType;
_maxSize=maxSize;
}
/* ------------------------------------------------------------ */
public Buffer getHeader()
{
@ -55,17 +55,17 @@ public class PooledBuffers extends AbstractBuffers
return getHeader();
if (_otherBuffers && size==getBufferSize())
return getBuffer();
// Look for an other buffer
Buffer buffer = _others.poll();
// consume all other buffers until one of the right size is found
while (buffer!=null && buffer.capacity()!=size)
{
_size.decrementAndGet();
buffer = _others.poll();
}
if (buffer==null)
buffer=newBuffer(size);
else
@ -89,7 +89,16 @@ public class PooledBuffers extends AbstractBuffers
else if (isBuffer(buffer))
_buffers.add(buffer);
else
_others.add(buffer);
_others.add(buffer);
}
}
public String toString()
{
return String.format("%s [%d/%d@%d,%d/%d@%d,%d/%d@-]",
getClass().getSimpleName(),
_headers.size(),_maxSize,_headerSize,
_buffers.size(),_maxSize,_bufferSize,
_others.size(),_maxSize);
}
}

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:
@ -598,7 +600,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection
{
return _engine;
}
public AsyncEndPoint getEndpoint()
{
return _aEndp;

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

@ -158,8 +158,6 @@ public class FormAuthModule extends BaseAuthModule
boolean mandatory = isMandatory(messageInfo);
mandatory |= isJSecurityCheck(uri);
HttpSession session = request.getSession(mandatory);
System.err.println("FormAuthModule.validateRequest(info,subject,serviceSubject) for uri="+uri+" mandatory="+mandatory+" isLoginOrError="+isLoginOrErrorPage(URIUtil.addPaths(request.getServletPath(),request.getPathInfo())));
// not mandatory or its the login or login error page don't authenticate
if (!mandatory || isLoginOrErrorPage(URIUtil.addPaths(request.getServletPath(),request.getPathInfo()))) return AuthStatus.SUCCESS;
@ -171,7 +169,7 @@ public class FormAuthModule extends BaseAuthModule
{
final String username = request.getParameter(__J_USERNAME);
final String password = request.getParameter(__J_PASSWORD);
System.err.println("Try login username="+username+" password="+password);
boolean success = tryLogin(messageInfo, clientSubject, response, session, username, new Password(password));
if (success)
{
@ -189,7 +187,6 @@ public class FormAuthModule extends BaseAuthModule
nuri = URIUtil.SLASH;
}
System.err.println("FormAuthModule succesful login, sending redirect to "+nuri);
response.setContentLength(0);
response.sendRedirect(response.encodeRedirectURL(nuri));
return AuthStatus.SEND_CONTINUE;
@ -215,8 +212,6 @@ public class FormAuthModule extends BaseAuthModule
FormCredential form_cred = (FormCredential) session.getAttribute(__J_AUTHENTICATED);
if (form_cred != null)
{
System.err.println("Form cred: form.username="+form_cred._jUserName+" form.pwd="+new String(form_cred._jPassword));
//TODO: we would like the form auth module to be able to invoke the loginservice.validate() method to check the previously authed user
boolean success = tryLogin(messageInfo, clientSubject, response, session, form_cred._jUserName, new Password(new String(form_cred._jPassword)));
@ -249,7 +244,6 @@ public class FormAuthModule extends BaseAuthModule
session.setAttribute(__J_URI, buf.toString());
}
System.err.println("Redirecting to login page "+_formLoginPage+" and remembering juri="+buf.toString());
response.setContentLength(0);
response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths(request.getContextPath(), _formLoginPage)));
return AuthStatus.SEND_CONTINUE;
@ -288,12 +282,11 @@ public class FormAuthModule extends BaseAuthModule
{
char[] pwdChars = password.toString().toCharArray();
Set<LoginCallbackImpl> loginCallbacks = clientSubject.getPrivateCredentials(LoginCallbackImpl.class);
System.err.println("FormAuthModule, LoginCallbackImpl.isEmpty="+loginCallbacks.isEmpty());
if (!loginCallbacks.isEmpty())
{
LoginCallbackImpl loginCallback = loginCallbacks.iterator().next();
FormCredential form_cred = new FormCredential(username, pwdChars, loginCallback.getUserPrincipal(), loginCallback.getSubject());
session.setAttribute(__J_AUTHENTICATED, form_cred);
}
@ -310,7 +303,6 @@ public class FormAuthModule extends BaseAuthModule
public boolean isLoginOrErrorPage(String pathInContext)
{
System.err.println("ISLOGINORERRORPAGE? "+pathInContext+" error: "+_formErrorPath+" login:"+_formLoginPath);
return pathInContext != null && (pathInContext.equals(_formErrorPath) || pathInContext.equals(_formLoginPath));
}

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

@ -4,17 +4,15 @@
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.monitor;
import static org.junit.Assert.assertEquals;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
@ -22,7 +20,6 @@ import java.lang.management.ManagementFactory;
import java.util.Collection;
import java.util.Iterator;
import java.util.TreeSet;
import javax.management.MBeanServer;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@ -35,13 +32,12 @@ import org.eclipse.jetty.client.security.SimpleRealmResolver;
import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.jmx.MBeanContainer;
import org.eclipse.jetty.monitor.JMXMonitor;
import org.eclipse.jetty.monitor.jmx.ConsoleNotifier;
import org.eclipse.jetty.monitor.jmx.EventNotifier;
import org.eclipse.jetty.monitor.jmx.EventState;
import org.eclipse.jetty.monitor.jmx.EventState.TriggerState;
import org.eclipse.jetty.monitor.jmx.EventTrigger;
import org.eclipse.jetty.monitor.jmx.MonitorAction;
import org.eclipse.jetty.monitor.jmx.EventState.TriggerState;
import org.eclipse.jetty.monitor.triggers.AndEventTrigger;
import org.eclipse.jetty.monitor.triggers.AttrEventTrigger;
import org.eclipse.jetty.monitor.triggers.EqualToAttrEventTrigger;
@ -61,6 +57,8 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
/* ------------------------------------------------------------ */
/**
@ -81,93 +79,93 @@ public class AttrEventTriggerTest
File docRoot = new File("target/test-output/docroot/");
docRoot.mkdirs();
docRoot.deleteOnExit();
System.setProperty("org.eclipse.jetty.util.log.DEBUG","");
_server = new Server();
SelectChannelConnector connector = new SelectChannelConnector();
_server.addConnector(connector);
_handler = new TestHandler();
_server.setHandler(_handler);
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
MBeanContainer mBeanContainer = new MBeanContainer(mBeanServer);
mBeanContainer.addBean(Log.getLog());
_counter = _handler.getRequestCounter();
mBeanContainer.addBean(_counter);
_server.addBean(mBeanContainer);
_server.getContainer().addEventListener(mBeanContainer);
_server.addBean(mBeanContainer, true);
_server.getContainer().addEventListener(mBeanContainer);
_server.start();
startClient(null);
_monitor = new JMXMonitor();
int port = _server.getConnectors()[0].getLocalPort();
int port = connector.getLocalPort();
_requestUrl = "http://localhost:"+port+ "/";
}
@After
public void tearDown()
throws Exception
{
stopClient();
if (_server != null)
{
_server.stop();
_server = null;
}
}
}
@Test
public void testNoCondition()
throws Exception
{
long requestCount = 10;
AttrEventTrigger<Long> trigger =
AttrEventTrigger<Long> trigger =
new AttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter");
EventNotifier notifier = new ConsoleNotifier("%s");
CounterAction action = new CounterAction(trigger, notifier, 500, 100);
performTest(action, requestCount, 1000);
ResultSet result = new ResultSet(1,requestCount);
assertEquals(result, action.getHits());
}
@Test
public void testEqual_TRUE()
throws Exception
{
long requestCount = 10;
long testValue = 5;
EqualToAttrEventTrigger<Long> trigger =
EqualToAttrEventTrigger<Long> trigger =
new EqualToAttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",testValue);
EventNotifier notifier = new ConsoleNotifier("%s");
CounterAction action = new CounterAction(trigger, notifier, 500, 100);
performTest(action, requestCount, 1000);
ResultSet result = new ResultSet(testValue);
assertEquals(result, action.getHits());
}
@Test
public void testEqual_FALSE()
throws Exception
{
long requestCount = 10;
long testValue = 11;
EqualToAttrEventTrigger<Long> trigger =
EqualToAttrEventTrigger<Long> trigger =
new EqualToAttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",
testValue);
@ -175,19 +173,19 @@ public class AttrEventTriggerTest
CounterAction action = new CounterAction(trigger, notifier, 500, 100);
performTest(action, requestCount, 1000);
ResultSet result = new ResultSet();
assertEquals(result, action.getHits());
}
@Test
public void testLowerLimit()
throws Exception
{
long requestCount = 10;
long testRangeLow = 5;
GreaterThanAttrEventTrigger<Long> trigger =
GreaterThanAttrEventTrigger<Long> trigger =
new GreaterThanAttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",
testRangeLow);
@ -195,27 +193,27 @@ public class AttrEventTriggerTest
CounterAction action = new CounterAction(trigger, notifier, 500, 100);
performTest(action, requestCount, 1000);
ResultSet result = new ResultSet(6,10);
assertEquals(result, action.getHits());
}
@Test
public void testLowerLimitIncl()
throws Exception
{
long requestCount = 10;
long testRangeLow = 5;
GreaterThanOrEqualToAttrEventTrigger<Long> trigger =
GreaterThanOrEqualToAttrEventTrigger<Long> trigger =
new GreaterThanOrEqualToAttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",
testRangeLow);
EventNotifier notifier = new ConsoleNotifier("%s");
CounterAction action = new CounterAction(trigger, notifier, 500, 100);
performTest(action, requestCount, 1000);
ResultSet result = new ResultSet(5,10);
assertEquals(result, action.getHits());
}
@ -226,8 +224,8 @@ public class AttrEventTriggerTest
{
long requestCount = 10;
long testRangeHigh = 5;
LessThanAttrEventTrigger<Long> trigger =
LessThanAttrEventTrigger<Long> trigger =
new LessThanAttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",
testRangeHigh);
@ -235,11 +233,11 @@ public class AttrEventTriggerTest
CounterAction action = new CounterAction(trigger, notifier, 500, 100);
performTest(action, requestCount, 1000);
ResultSet result = new ResultSet(1,4);
assertEquals(result, action.getHits());
}
@Test
public void testUpperLimitIncl()
@ -247,8 +245,8 @@ public class AttrEventTriggerTest
{
long requestCount = 10;
long testRangeHigh = 5;
LessThanOrEqualToAttrEventTrigger<Long> trigger =
LessThanOrEqualToAttrEventTrigger<Long> trigger =
new LessThanOrEqualToAttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",
testRangeHigh);
@ -256,11 +254,11 @@ public class AttrEventTriggerTest
CounterAction action = new CounterAction(trigger, notifier, 500, 100);
performTest(action, requestCount, 1000);
ResultSet result = new ResultSet(1,5);
assertEquals(result, action.getHits());
}
@Test
public void testRangeInclusive()
throws Exception
@ -268,20 +266,20 @@ public class AttrEventTriggerTest
long requestCount = 10;
long testRangeLow = 3;
long testRangeHigh = 8;
RangeInclAttrEventTrigger<Long> trigger =
RangeInclAttrEventTrigger<Long> trigger =
new RangeInclAttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",
testRangeLow, testRangeHigh);
EventNotifier notifier = new ConsoleNotifier("%s");
CounterAction action = new CounterAction(trigger, notifier, 500, 100);
performTest(action, requestCount, 1000);
ResultSet result = new ResultSet(testRangeLow,testRangeHigh);
assertEquals(result, action.getHits());
}
@Test
public void testInsideRangeExclusive()
throws Exception
@ -289,20 +287,20 @@ public class AttrEventTriggerTest
long requestCount = 10;
long testRangeLow = 3;
long testRangeHigh = 8;
RangeAttrEventTrigger<Long> trigger =
RangeAttrEventTrigger<Long> trigger =
new RangeAttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",
testRangeLow, testRangeHigh);
EventNotifier notifier = new ConsoleNotifier("%s");
CounterAction action = new CounterAction(trigger, notifier, 500, 100);
performTest(action, requestCount, 1000);
ResultSet result = new ResultSet(testRangeLow+1,testRangeHigh-1);
assertEquals(result, action.getHits());
}
@Test
public void testRangeComposite()
throws Exception
@ -310,23 +308,23 @@ public class AttrEventTriggerTest
long requestCount = 10;
long testRangeLow = 4;
long testRangeHigh = 7;
GreaterThanAttrEventTrigger<Long> trigger1 =
GreaterThanAttrEventTrigger<Long> trigger1 =
new GreaterThanAttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",
testRangeLow);
LessThanOrEqualToAttrEventTrigger<Long> trigger2 =
LessThanOrEqualToAttrEventTrigger<Long> trigger2 =
new LessThanOrEqualToAttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",
testRangeHigh);
AndEventTrigger trigger = new AndEventTrigger(trigger1, trigger2);
EventNotifier notifier = new ConsoleNotifier("%s");
CounterAction action = new CounterAction(trigger, notifier, 500, 100);
performTest(action, requestCount, 1000);
ResultSet result = new ResultSet(testRangeLow+1,testRangeHigh);
assertEquals(result, action.getHits());
}
@Test
public void testRangeOuter()
throws Exception
@ -334,23 +332,23 @@ public class AttrEventTriggerTest
long requestCount = 10;
long testRangeLow = 4;
long testRangeHigh = 7;
LessThanOrEqualToAttrEventTrigger<Long> trigger1 =
LessThanOrEqualToAttrEventTrigger<Long> trigger1 =
new LessThanOrEqualToAttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",
testRangeLow);
GreaterThanAttrEventTrigger<Long> trigger2 =
GreaterThanAttrEventTrigger<Long> trigger2 =
new GreaterThanAttrEventTrigger<Long>("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",
testRangeHigh);
OrEventTrigger trigger = new OrEventTrigger(trigger1, trigger2);
EventNotifier notifier = new ConsoleNotifier("%s");
CounterAction action = new CounterAction(trigger, notifier, 500, 100);
performTest(action, requestCount, 1000);
ResultSet result = new ResultSet(1,testRangeLow,testRangeHigh+1, requestCount);
assertEquals(result, action.getHits());
}
protected void performTest(MonitorAction action, long count, long interval)
throws Exception
{
@ -363,17 +361,17 @@ public class AttrEventTriggerTest
ContentExchange getExchange = new ContentExchange();
getExchange.setURL(_requestUrl);
getExchange.setMethod(HttpMethods.GET);
_client.send(getExchange);
int state = getExchange.waitForDone();
String content = "";
int responseStatus = getExchange.getResponseStatus();
if (responseStatus == HttpStatus.OK_200)
{
content = getExchange.getResponseContent();
}
}
assertEquals(HttpStatus.OK_200,responseStatus);
Thread.sleep(interval);
}
@ -382,12 +380,12 @@ public class AttrEventTriggerTest
break;
}
}
Thread.sleep(interval);
_monitor.removeActions(action);
}
protected void startClient(Realm realm)
throws Exception
{
@ -397,7 +395,7 @@ public class AttrEventTriggerTest
_client.setRealmResolver(new SimpleRealmResolver(realm));
_client.start();
}
protected void stopClient()
throws Exception
{
@ -412,7 +410,7 @@ public class AttrEventTriggerTest
extends AbstractHandler
{
private RequestCounter _counter = new RequestCounter();
public void handle(String target, Request baseRequest,
HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
@ -421,40 +419,40 @@ public class AttrEventTriggerTest
return;
}
_counter.increment();
response.setContentType("text/plain");
response.setStatus(HttpServletResponse.SC_OK);
PrintWriter writer = response.getWriter();
writer.println("===TEST RESPONSE===");
baseRequest.setHandled(true);
}
public RequestCounter getRequestCounter()
{
return _counter;
}
}
protected static class ResultSet extends TreeSet<Long>
{
{
public ResultSet() {}
public ResultSet(long value)
{
add(value);
}
public ResultSet(long start, long end)
{
addEntries(start, end);
}
public ResultSet(long start, long pause, long resume, long end)
{
addEntries(start, pause);
addEntries(resume, end);
}
public void addEntries(long start, long stop)
{
if (start > 0 && stop > 0)
@ -471,23 +469,23 @@ public class AttrEventTriggerTest
return (this.size() == set.size()) && containsAll(set);
}
}
protected static class CounterAction
extends MonitorAction
{
private ResultSet _hits = new ResultSet();
public CounterAction(EventTrigger trigger, EventNotifier notifier, long interval, long delay)
{
super(trigger, notifier, interval, delay);
}
public void execute(EventTrigger trigger, EventState<?> state, long timestamp)
{
if (trigger != null && state != null)
{
Collection<?> values = state.values();
Iterator<?> it = values.iterator();
while(it.hasNext())
{
@ -500,7 +498,7 @@ public class AttrEventTriggerTest
}
}
}
public ResultSet getHits()
{
return _hits;

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;
@ -54,10 +55,10 @@ public class AsyncHttpConnection extends AbstractHttpConnection implements Async
try
{
setCurrentConnection(this);
// don't check for idle while dispatched (unless blocking IO is done).
_asyncEndp.setCheckForIdle(false);
// While progress and the connection has not changed
while (progress && connection==this)
@ -67,7 +68,7 @@ public class AsyncHttpConnection extends AbstractHttpConnection implements Async
{
// Handle resumed request
if (_request._async.isAsync())
{
{
if (_request._async.isDispatchable())
handleRequest();
}
@ -126,10 +127,10 @@ public class AsyncHttpConnection extends AbstractHttpConnection implements Async
}
else if (_request.getAsyncContinuation().isAsyncStarted())
{
// The request is suspended, so even though progress has been made, break the while loop
// The request is suspended, so even though progress has been made,
// exit the while loop by setting progress to false
LOG.debug("suspended {}",this);
// TODO: breaking inside finally blocks is bad: rethink how we should exit from here
break;
progress=false;
}
}
}
@ -137,20 +138,18 @@ public class AsyncHttpConnection extends AbstractHttpConnection implements Async
finally
{
setCurrentConnection(null);
// If we are not suspended
if (!_request.getAsyncContinuation().isAsyncStarted())
{
// return buffers
_parser.returnBuffers();
_generator.returnBuffers();
}
if (_request.getAsyncContinuation().isComplete() || _request.getAsyncContinuation().isInitial())
{
// reenable idle checking unless request is suspended
_asyncEndp.setCheckForIdle(true);
}
// Safety net to catch spinning
if (some_progress)
_total_no_progress=0;

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,7 +75,10 @@ import org.eclipse.jetty.util.resource.Resource;
* <p>
* If the context init parameter "org.eclipse.jetty.server.context.ManagedAttributes" is set to a comma separated list of names, then they are treated as
* context attribute names, which if set as attributes are passed to the servers Container so that they may be managed with JMX.
*
* <p>
* The maximum size of a form that can be processed by this context is controlled by the system properties org.eclipse.jetty.server.Request.maxFormKeys
* and org.eclipse.jetty.server.Request.maxFormContentSize. These can also be configured with {@link #setMaxFormContentSize(int)} and {@link #setMaxFormKeys(int)}
*
* @org.apache.xbean.XBean description="Creates a basic HTTP context"
*/
public class ContextHandler extends ScopedHandler implements Attributes, Server.Graceful

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

@ -4,35 +4,31 @@
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
/**
*
*
*/
package org.eclipse.jetty.server.nio;
import org.eclipse.jetty.io.Buffers.Type;
import org.eclipse.jetty.server.AbstractConnector;
/* ------------------------------------------------------------ */
/**
*
*
*/
public abstract class AbstractNIOConnector extends AbstractConnector implements NIOConnector
{
public AbstractNIOConnector()
{
setRequestBufferType(Type.DIRECT);
setRequestHeaderType(Type.INDIRECT);
setResponseBufferType(Type.DIRECT);
setResponseHeaderType(Type.INDIRECT);
_buffers.setRequestBufferType(Type.DIRECT);
_buffers.setRequestHeaderType(Type.INDIRECT);
_buffers.setResponseBufferType(Type.DIRECT);
_buffers.setResponseHeaderType(Type.INDIRECT);
}
/* ------------------------------------------------------------------------------- */
public boolean getUseDirectBuffers()
{
@ -46,8 +42,7 @@ public abstract class AbstractNIOConnector extends AbstractConnector implements
*/
public void setUseDirectBuffers(boolean direct)
{
setRequestBufferType(direct?Type.DIRECT:Type.INDIRECT);
setResponseBufferType(direct?Type.DIRECT:Type.INDIRECT);
_buffers.setRequestBufferType(direct?Type.DIRECT:Type.INDIRECT);
_buffers.setResponseBufferType(direct?Type.DIRECT:Type.INDIRECT);
}
}

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
@ -126,7 +129,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
{}
super.handle(target,baseRequest,request,response);
}
});
Socket client=newSocket(HOST,_connector.getLocalPort());
client.setSoTimeout(10000);
@ -151,14 +154,14 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
// read the response
String result=IO.toString(is);
Assert.assertThat("OK",result,containsString("200 OK"));
// check client reads EOF
assertEquals(-1, is.read());
// wait for idle timeout
TimeUnit.MILLISECONDS.sleep(MAX_IDLE_TIME+MAX_IDLE_TIME/2);
// further writes will get broken pipe or similar
try
{
@ -199,7 +202,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
{}
super.handle(target,baseRequest,request,response);
}
});
Socket client=newSocket(HOST,_connector.getLocalPort());
client.setSoTimeout(10000);
@ -220,10 +223,10 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
"\r\n").getBytes("utf-8"));
os.write(contentB);
os.flush();
// Get the server side endpoint
EndPoint endp = endpoint.exchange(null,10,TimeUnit.SECONDS);
// read the response
IO.toString(is);
@ -232,7 +235,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
TimeUnit.MILLISECONDS.sleep(MAX_IDLE_TIME+MAX_IDLE_TIME/2);
// further writes will get broken pipe or similar
try
{
@ -251,7 +254,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
{
// expected
}
// check the server side is closed
Assert.assertFalse(endp.isOpen());
}
@ -266,7 +269,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
InputStream is=client.getInputStream();
assertFalse(client.isClosed());
Thread.sleep(500);
Thread.sleep(sleepTime);
long start = System.currentTimeMillis();
try
{
@ -281,7 +284,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
{
e.printStackTrace();
}
Assert.assertTrue(System.currentTimeMillis()-start<5000);
Assert.assertTrue(System.currentTimeMillis()-start<maximumTestRuntime);
}

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;
@ -78,7 +79,7 @@ public class RequestTest
_server.stop();
_server.join();
}
@Test
public void testParamExtraction() throws Exception
{
@ -101,27 +102,27 @@ public class RequestTest
System.err.println(map);
assertFalse(map == null);
assertTrue(map.isEmpty());
Enumeration names = request.getParameterNames();
assertFalse(names.hasMoreElements());
}
return true;
}
};
//Send a request with query string with illegal hex code to cause
//an exception parsing the params
String request="GET /?param=%ZZaaa HTTP/1.1\r\n"+
"Host: whatever\r\n"+
"Content-Type: text/html;charset=utf8\n"+
"\n";
String responses=_connector.getResponses(request);
assertTrue(responses.startsWith("HTTP/1.1 200"));
}
@Test
public void testBadUtf8ParamExtraction() throws Exception
{
@ -133,20 +134,40 @@ public class RequestTest
return value.startsWith("aaa") && value.endsWith("bb");
}
};
//Send a request with query string with illegal hex code to cause
//an exception parsing the params
String request="GET /?param=aaa%E7bbb HTTP/1.1\r\n"+
"Host: whatever\r\n"+
"Content-Type: text/html;charset=utf8\n"+
"\n";
String responses=_connector.getResponses(request);
assertTrue(responses.startsWith("HTTP/1.1 200"));
assertTrue(responses.startsWith("HTTP/1.1 200"));
}
@Test
public void testInvalidHostHeader() throws Exception
{
// Use a contextHandler with vhosts to force call to Request.getServerName()
ContextHandler handler = new ContextHandler();
handler.addVirtualHosts(new String[1]);
_server.stop();
_server.setHandler(handler);
_server.start();
// Request with illegal Host header
String request="GET / HTTP/1.1\r\n"+
"Host: whatever.com:\r\n"+
"Content-Type: text/html;charset=utf8\n"+
"\n";
String responses=_connector.getResponses(request);
assertTrue("400 Bad Request response expected",responses.startsWith("HTTP/1.1 400"));
}
@Test
public void testContentTypeEncoding() throws Exception
{
@ -196,7 +217,7 @@ public class RequestTest
assertTrue(results.get(i++).startsWith("text/html"));
assertEquals(" x=z; ",results.get(i++));
}
@Test
public void testHostPort() throws Exception
{
@ -369,7 +390,7 @@ public class RequestTest
Reader reader=request.getReader();
String in = IO.toString(reader);
String param = request.getParameter("param");
byte[] b=("read='"+in+"' param="+param+"\n").getBytes(StringUtil.__UTF8);
response.setContentLength(b.length);
response.getOutputStream().write(b);
@ -389,11 +410,11 @@ public class RequestTest
"param=wrong\r\n";
String responses = _connector.getResponses(request);
assertTrue(responses.indexOf("read='param=wrong' param=right")>0);
}
@Test
public void testPartialInput() throws Exception
{
@ -752,7 +773,7 @@ public class RequestTest
{
_server.setAttribute("org.eclipse.jetty.server.Request.maxFormContentSize",-1);
_server.setAttribute("org.eclipse.jetty.server.Request.maxFormKeys",1000);
// This file is not distributed - as it is dangerous
File evil_keys = new File("/tmp/keys_mapping_to_zero_2m");
if (!evil_keys.exists())
@ -760,10 +781,10 @@ public class RequestTest
Log.info("testHashDOS skipped");
return;
}
BufferedReader in = new BufferedReader(new FileReader(evil_keys));
StringBuilder buf = new StringBuilder(4000000);
String key=null;
buf.append("a=b");
while((key=in.readLine())!=null)
@ -771,7 +792,7 @@ public class RequestTest
buf.append("&").append(key).append("=").append("x");
}
buf.append("&c=d");
_handler._checker = new RequestTester()
{
public boolean check(HttpServletRequest request,HttpServletResponse response)
@ -787,15 +808,15 @@ public class RequestTest
"Connection: close\r\n"+
"\r\n"+
buf;
long start=System.currentTimeMillis();
String response = _connector.getResponses(request);
assertTrue(response.contains("200 OK"));
long now=System.currentTimeMillis();
assertTrue((now-start)<5000);
}
interface RequestTester
{
boolean check(HttpServletRequest request,HttpServletResponse response) throws IOException;
@ -812,12 +833,12 @@ public class RequestTest
if (request.getContentLength()>0 && !MimeTypes.FORM_ENCODED.equals(request.getContentType()))
_content=IO.toString(request.getInputStream());
if (_checker!=null && _checker.check(request,response))
response.setStatus(200);
else
response.sendError(500);
}
}

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,9 +49,9 @@ public class SelectChannelTimeoutTest extends ConnectorTimeoutTest
_handler.setSuspendFor(100);
_handler.setResumeAfter(25);
assertTrue(process(null).toUpperCase().contains("RESUMED"));
assertTrue(process(null).toUpperCase().contains("RESUMED"));
}
@Test
public void testIdleTimeoutAfterTimeout() throws Exception
{
@ -62,13 +61,13 @@ public class SelectChannelTimeoutTest extends ConnectorTimeoutTest
session.setHandler(_handler);
_server.setHandler(session);
_server.start();
_handler.setSuspendFor(50);
assertTrue(process(null).toUpperCase().contains("TIMEOUT"));
}
@Test
public void testIdleTimeoutAfterComplete() throws Exception
public void testIdleTimeoutAfterComplete() throws Exception
{
SuspendHandler _handler = new SuspendHandler();
_server.stop();
@ -76,15 +75,15 @@ public class SelectChannelTimeoutTest extends ConnectorTimeoutTest
session.setHandler(_handler);
_server.setHandler(session);
_server.start();
_handler.setSuspendFor(100);
_handler.setCompleteAfter(25);
assertTrue(process(null).toUpperCase().contains("COMPLETED"));
}
private synchronized String process(String content) throws UnsupportedEncodingException, IOException, InterruptedException
private synchronized String process(String content) throws UnsupportedEncodingException, IOException, InterruptedException
{
String request = "GET / HTTP/1.1\r\n" + "Host: localhost\r\n" + "Connection: close\r\n";
String request = "GET / HTTP/1.1\r\n" + "Host: localhost\r\n";
if (content == null)
request += "\r\n";
@ -97,11 +96,13 @@ public class SelectChannelTimeoutTest extends ConnectorTimeoutTest
{
SelectChannelConnector connector = (SelectChannelConnector)_connector;
Socket socket = new Socket((String)null,connector.getLocalPort());
socket.setSoTimeout(10 * MAX_IDLE_TIME);
socket.getOutputStream().write(request.getBytes("UTF-8"));
InputStream inputStream = socket.getInputStream();
long start = System.currentTimeMillis();
String response = IO.toString(inputStream);
Thread.sleep(500);
assertEquals("Socket should be closed and return -1 on reading",-1,socket.getInputStream().read());
long timeElapsed = System.currentTimeMillis() - start;
assertTrue("Time elapsed should be at least MAX_IDLE_TIME",timeElapsed > MAX_IDLE_TIME);
return response;
}

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

@ -57,12 +57,12 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool;
/**
* Asynchronous Proxy Servlet.
*
*
* Forward requests to another server either as a standard web proxy (as defined by RFC2616) or as a transparent proxy.
* <p>
* This servlet needs the jetty-util and jetty-client classes to be available to the web application.
* <p>
* To facilitate JMX monitoring, the "HttpClient", it's "ThreadPool" and the "Logger" are set as context attributes prefixed with the servlet name.
* To facilitate JMX monitoring, the "HttpClient" and "ThreadPool" are set as context attributes prefixed with the servlet name.
* <p>
* The following init parameters may be used to configure the servlet:
* <ul>
@ -75,17 +75,15 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool;
* <li>requestBufferSize - the size of the request buffer (d. 12,288)
* <li>responseHeaderSize - the size of the response header buffer (d. 6,144)
* <li>responseBufferSize - the size of the response buffer (d. 32,768)
* <li>HostHeader - Force the host header to a particular value
* <li>HostHeader - Force the host header to a particular value
* <li>whiteList - comma-separated list of allowed proxy destinations
* <li>blackList - comma-separated list of forbidden proxy destinations
* </ul>
*
*
* @see org.eclipse.jetty.server.handler.ConnectHandler
*/
public class ProxyServlet implements Servlet
{
private static final Logger LOG = Log.getLogger(ProxyServlet.class);
protected Logger _log;
protected HttpClient _client;
protected String _hostHeader;
@ -111,25 +109,24 @@ public class ProxyServlet implements Servlet
/* ------------------------------------------------------------ */
/*
* (non-Javadoc)
*
*
* @see javax.servlet.Servlet#init(javax.servlet.ServletConfig)
*/
public void init(ServletConfig config) throws ServletException
{
_config = config;
_context = config.getServletContext();
_hostHeader = config.getInitParameter("HostHeader");
try
{
_log = createLogger(config);
_log = createLogger(config);
_client = createHttpClient(config);
if (_context != null)
{
_context.setAttribute(config.getServletName() + ".Logger",_log);
_context.setAttribute(config.getServletName() + ".ThreadPool",_client.getThreadPool());
_context.setAttribute(config.getServletName() + ".HttpClient",_client);
}
@ -162,12 +159,12 @@ public class ProxyServlet implements Servlet
_log.debug(x);
}
}
/**
* Create and return a logger based on the ServletConfig for use in the
* Create and return a logger based on the ServletConfig for use in the
* proxy servlet
*
*
* @param config
* @return Logger
*/
@ -175,24 +172,24 @@ public class ProxyServlet implements Servlet
{
return Log.getLogger("org.eclipse.jetty.servlets." + config.getServletName());
}
/**
* Create and return an HttpClient based on ServletConfig
*
* By default this implementation will create an instance of the
*
* By default this implementation will create an instance of the
* HttpClient for use by this proxy servlet.
*
* @param config
* @return HttpClient
*
* @param config
* @return HttpClient
* @throws Exception
*/
protected HttpClient createHttpClient(ServletConfig config) throws Exception
{
HttpClient client = new HttpClient();
client.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
String t = config.getInitParameter("maxThreads");
if (t != null)
{
client.setThreadPool(new QueuedThreadPool(Integer.parseInt(t)));
@ -201,67 +198,67 @@ public class ProxyServlet implements Servlet
{
client.setThreadPool(new QueuedThreadPool());
}
((QueuedThreadPool)client.getThreadPool()).setName(config.getServletName());
((QueuedThreadPool)client.getThreadPool()).setName(config.getServletName());
t = config.getInitParameter("maxConnections");
if (t != null)
{
client.setMaxConnectionsPerAddress(Integer.parseInt(t));
}
t = config.getInitParameter("timeout");
if ( t != null )
{
client.setTimeout(Long.parseLong(t));
}
t = config.getInitParameter("idleTimeout");
if ( t != null )
{
client.setIdleTimeout(Long.parseLong(t));
}
t = config.getInitParameter("requestHeaderSize");
if ( t != null )
{
client.setRequestHeaderSize(Integer.parseInt(t));
}
t = config.getInitParameter("requestBufferSize");
if ( t != null )
{
client.setRequestBufferSize(Integer.parseInt(t));
}
t = config.getInitParameter("responseHeaderSize");
if ( t != null )
{
client.setResponseHeaderSize(Integer.parseInt(t));
}
t = config.getInitParameter("responseBufferSize");
if ( t != null )
{
client.setResponseBufferSize(Integer.parseInt(t));
}
client.start();
return client;
}
/* ------------------------------------------------------------ */
/**
* Helper function to process a parameter value containing a list of new entries and initialize the specified host map.
*
*
* @param list
* comma-separated list of new entries
* @param hostMap
@ -301,7 +298,7 @@ public class ProxyServlet implements Servlet
/* ------------------------------------------------------------ */
/**
* Check the request hostname and path against white- and blacklist.
*
*
* @param host
* hostname to check
* @param path
@ -353,7 +350,7 @@ public class ProxyServlet implements Servlet
/* ------------------------------------------------------------ */
/*
* (non-Javadoc)
*
*
* @see javax.servlet.Servlet#getServletConfig()
*/
public ServletConfig getServletConfig()
@ -364,7 +361,7 @@ public class ProxyServlet implements Servlet
/* ------------------------------------------------------------ */
/**
* Get the hostHeader.
*
*
* @return the hostHeader
*/
public String getHostHeader()
@ -375,7 +372,7 @@ public class ProxyServlet implements Servlet
/* ------------------------------------------------------------ */
/**
* Set the hostHeader.
*
*
* @param hostHeader
* the hostHeader to set
*/
@ -387,7 +384,7 @@ public class ProxyServlet implements Servlet
/* ------------------------------------------------------------ */
/*
* (non-Javadoc)
*
*
* @see javax.servlet.Servlet#service(javax.servlet.ServletRequest, javax.servlet.ServletResponse)
*/
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
@ -412,7 +409,7 @@ public class ProxyServlet implements Servlet
response.sendError(HttpServletResponse.SC_GATEWAY_TIMEOUT); // Need better test that isInitial
else
{
String uri = request.getRequestURI();
if (request.getQueryString() != null)
uri += "?" + request.getQueryString();
@ -430,14 +427,17 @@ public class ProxyServlet implements Servlet
HttpExchange exchange = new HttpExchange()
{
@Override
protected void onRequestCommitted() throws IOException
{
}
@Override
protected void onRequestComplete() throws IOException
{
}
@Override
protected void onResponseComplete() throws IOException
{
if (debug != 0)
@ -445,6 +445,7 @@ public class ProxyServlet implements Servlet
continuation.complete();
}
@Override
protected void onResponseContent(Buffer content) throws IOException
{
if (debug != 0)
@ -452,10 +453,12 @@ public class ProxyServlet implements Servlet
content.writeTo(out);
}
@Override
protected void onResponseHeaderComplete() throws IOException
{
}
@Override
protected void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
{
if (debug != 0)
@ -467,6 +470,7 @@ public class ProxyServlet implements Servlet
response.setStatus(status);
}
@Override
protected void onResponseHeader(Buffer name, Buffer value) throws IOException
{
String s = name.toString().toLowerCase();
@ -481,11 +485,12 @@ public class ProxyServlet implements Servlet
_log.debug(debug + " " + name + "! " + value);
}
@Override
protected void onConnectionFailed(Throwable ex)
{
handleOnConnectionFailed(ex,request,response);
// it is possible this might trigger before the
// it is possible this might trigger before the
// continuation.suspend()
if (!continuation.isInitial())
{
@ -493,16 +498,17 @@ public class ProxyServlet implements Servlet
}
}
@Override
protected void onException(Throwable ex)
{
if (ex instanceof EofException)
{
LOG.ignore(ex);
_log.ignore(ex);
return;
}
handleOnException(ex,request,response);
// it is possible this might trigger before the
// it is possible this might trigger before the
// continuation.suspend()
if (!continuation.isInitial())
{
@ -510,6 +516,7 @@ public class ProxyServlet implements Servlet
}
}
@Override
protected void onExpire()
{
handleOnExpire(request,response);
@ -597,14 +604,14 @@ public class ProxyServlet implements Servlet
if (hasContent)
exchange.setRequestContentSource(in);
customizeExchange(exchange, request);
customizeExchange(exchange, request);
/*
* we need to set the timeout on the continuation to take into
* account the timeout of the HttpClient and the HttpExchange
*/
long ctimeout = (_client.getTimeout() > exchange.getTimeout()) ? _client.getTimeout() : exchange.getTimeout();
// continuation fudge factor of 1000, underlying components
// should fail/expire first from exchange
if ( ctimeout == 0 )
@ -612,12 +619,12 @@ public class ProxyServlet implements Servlet
continuation.setTimeout(0); // ideally never times out
}
else
{
{
continuation.setTimeout(ctimeout + 1000);
}
customizeContinuation(continuation);
continuation.suspend(response);
_client.send(exchange);
@ -678,7 +685,7 @@ public class ProxyServlet implements Servlet
/*
* (non-Javadoc)
*
*
* @see javax.servlet.Servlet#getServletInfo()
*/
public String getServletInfo()
@ -689,7 +696,7 @@ public class ProxyServlet implements Servlet
/**
* Extension point for subclasses to customize an exchange. Useful for setting timeouts etc. The default implementation does nothing.
*
*
* @param exchange
* @param request
*/
@ -701,7 +708,7 @@ public class ProxyServlet implements Servlet
/**
* Extension point for subclasses to customize the Continuation after it's initial creation in the service method. Useful for setting timeouts etc. The
* default implementation does nothing.
*
*
* @param continuation
*/
protected void customizeContinuation(Continuation continuation)
@ -712,7 +719,7 @@ public class ProxyServlet implements Servlet
/**
* Extension point for custom handling of an HttpExchange's onConnectionFailed method. The default implementation delegates to
* {@link #handleOnException(Throwable, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)}
*
*
* @param ex
* @param request
* @param response
@ -725,15 +732,15 @@ public class ProxyServlet implements Servlet
/**
* Extension point for custom handling of an HttpExchange's onException method. The default implementation sets the response status to
* HttpServletResponse.SC_INTERNAL_SERVER_ERROR (503)
*
*
* @param ex
* @param request
* @param response
*/
protected void handleOnException(Throwable ex, HttpServletRequest request, HttpServletResponse response)
{
LOG.warn(ex.toString());
LOG.debug(ex);
_log.warn(ex.toString());
_log.debug(ex);
if (!response.isCommitted())
{
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
@ -743,7 +750,7 @@ public class ProxyServlet implements Servlet
/**
* Extension point for custom handling of an HttpExchange's onExpire method. The default implementation sets the response status to
* HttpServletResponse.SC_GATEWAY_TIMEOUT (504)
*
*
* @param request
* @param response
*/
@ -757,7 +764,7 @@ public class ProxyServlet implements Servlet
/**
* Transparent Proxy.
*
*
* This convenience extension to ProxyServlet configures the servlet as a transparent proxy. The servlet is configured with init parameters:
* <ul>
* <li>ProxyTo - a URI like http://host:80/context to which the request is proxied.
@ -765,7 +772,7 @@ public class ProxyServlet implements Servlet
* </ul>
* For example, if a request was received at /foo/bar and the ProxyTo was http://host:80/context and the Prefix was /foo, then the request would be proxied
* to http://host:80/context/bar
*
*
*/
public static class Transparent extends ProxyServlet
{

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,30 +123,35 @@ public class Main
// if no non-option inis, add the start.ini and start.d
if (!ini)
{
List<String> ini_args=new ArrayList<String>();
File start_ini = new File(_jettyHome,"start.ini");
if (start_ini.exists())
ini_args.addAll(loadStartIni(start_ini));
File start_d = new File(_jettyHome,"start.d");
if (start_d.isDirectory())
{
File[] inis = start_d.listFiles(new FilenameFilter()
{
public boolean accept(File dir, String name)
{
return name.toLowerCase().endsWith(".ini");
}
});
Arrays.sort(inis);
for (File i : inis)
ini_args.addAll(loadStartIni(i));
}
arguments.addAll(0,ini_args);
arguments.addAll(0,parseStartIniFiles());
}
return arguments;
}
List<String> parseStartIniFiles()
{
List<String> ini_args=new ArrayList<String>();
File start_ini = new File(_jettyHome,"start.ini");
if (start_ini.exists())
ini_args.addAll(loadStartIni(start_ini));
File start_d = new File(_jettyHome,"start.d");
if (start_d.isDirectory())
{
File[] inis = start_d.listFiles(new FilenameFilter()
{
public boolean accept(File dir, String name)
{
return name.toLowerCase().endsWith(".ini");
}
});
Arrays.sort(inis);
for (File i : inis)
ini_args.addAll(loadStartIni(i));
}
return ini_args;
}
public List<String> processCommandLine(List<String> arguments) throws Exception
{
@ -1075,7 +1080,7 @@ public class Main
}
catch (IOException e)
{
// usageExit(e,ERR_UNKNOWN);
usageExit(e,ERR_UNKNOWN);
}
finally
{

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,92 +12,224 @@ import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
* An AggregateLifeCycle is an AbstractLifeCycle with a collection of dependent beans.
* An AggregateLifeCycle is an {@link LifeCycle} implementation for a collection of contained beans.
* <p>
* Beans can be added the AggregateLifeCycle either as managed beans or as unmanaged beans. A managed bean is started, stopped and destroyed with the aggregate.
* An umanaged bean is associated with the aggregate for the purposes of {@link #dump()}, but it's lifecycle must be managed externally.
* <p>
* When a bean is added, if it is a {@link LifeCycle} and it is already started, then it is assumed to be an unmanaged bean.
* Otherwise the methods {@link #addBean(LifeCycle, boolean)}, {@link #manage(LifeCycle)} and {@link #unmanage(LifeCycle)} can be used to
* explicitly control the life cycle relationship.
* <p>
* If adding a bean that is shared between multiple {@link AggregateLifeCycle} instances, then it should be started before being added, so it is unmanged, or
* the API must be used to explicitly set it as unmanaged.
* <p>
* Dependent beans are started and stopped with the {@link LifeCycle} and if they are destroyed if they are also {@link Destroyable}.
*
*/
public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable, Dumpable
{
private static final Logger LOG = Log.getLogger(AggregateLifeCycle.class);
private final List<Object> _dependentBeans=new CopyOnWriteArrayList<Object>();
private final List<Bean> _beans=new CopyOnWriteArrayList<Bean>();
private boolean _started=false;
public void destroy()
private class Bean
{
for (Object o : _dependentBeans)
Bean(Object b)
{
if (o instanceof Destroyable)
{
((Destroyable)o).destroy();
}
_bean=b;
}
_dependentBeans.clear();
final Object _bean;
volatile boolean _managed=true;
}
/* ------------------------------------------------------------ */
/**
* Start the managed lifecycle beans in the order they were added.
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
*/
@Override
protected void doStart() throws Exception
{
for (Object o:_dependentBeans)
for (Bean b:_beans)
{
if (o instanceof LifeCycle)
((LifeCycle)o).start();
if (b._managed && b._bean instanceof LifeCycle)
{
LifeCycle l=(LifeCycle)b._bean;
if (!l.isRunning())
l.start();
}
}
// indicate that we are started, so that addBean will start other beans added.
_started=true;
super.doStart();
}
/* ------------------------------------------------------------ */
/**
* Stop the joined lifecycle beans in the reverse order they were added.
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
*/
@Override
protected void doStop() throws Exception
{
_started=false;
super.doStop();
List<Object> reverse = new ArrayList<Object>(_dependentBeans);
List<Bean> reverse = new ArrayList<Bean>(_beans);
Collections.reverse(reverse);
for (Object o:reverse)
for (Bean b:reverse)
{
if (o instanceof LifeCycle)
((LifeCycle)o).stop();
if (b._managed && b._bean instanceof LifeCycle)
{
LifeCycle l=(LifeCycle)b._bean;
if (l.isRunning())
l.stop();
}
}
}
/* ------------------------------------------------------------ */
/**
* Destroy the joined Destroyable beans in the reverse order they were added.
* @see org.eclipse.jetty.util.component.Destroyable#destroy()
*/
public void destroy()
{
List<Bean> reverse = new ArrayList<Bean>(_beans);
Collections.reverse(reverse);
for (Bean b:reverse)
{
if (b._bean instanceof Destroyable && b._managed)
{
Destroyable d=(Destroyable)b._bean;
d.destroy();
}
}
_beans.clear();
}
/* ------------------------------------------------------------ */
/** Is the bean contained in the aggregate.
* @param bean
* @return True if the aggregate contains the bean
*/
public boolean contains(Object bean)
{
for (Bean b:_beans)
if (b._bean==bean)
return true;
return false;
}
/* ------------------------------------------------------------ */
/** Is the bean joined to the aggregate.
* @param bean
* @return True if the aggregate contains the bean and it is joined
*/
public boolean isManaged(Object bean)
{
for (Bean b:_beans)
if (b._bean==bean)
return b._managed;
return false;
}
/* ------------------------------------------------------------ */
/**
* Add an associated bean.
* The bean will be added to this LifeCycle and if it is also a
* {@link LifeCycle} instance, it will be
* started/stopped. Any beans that are also
* {@link Destroyable}, will be destroyed with the server.
* If the bean is a {@link LifeCycle}, then it will be managed if it is not
* already started and umanaged if it is already started. The {@link #addBean(Object, boolean)}
* method should be used if this is not correct, or the {@link #manage(Object)} and {@link #unmanage(Object)}
* methods may be used after an add to change the status.
* @param o the bean object to add
* @return true if the bean was added or false if it has already been added.
*/
public boolean addBean(Object o)
{
if (o == null)
// beans are joined unless they are started lifecycles
return addBean(o,!((o instanceof LifeCycle)&&((LifeCycle)o).isStarted()));
}
/* ------------------------------------------------------------ */
/** Add an associated lifecycle.
* @param o The lifecycle to add
* @param managed True if the LifeCycle is to be joined, otherwise it will be disjoint.
* @return
*/
public boolean addBean(Object o, boolean managed)
{
if (contains(o))
return false;
boolean added=false;
if (!_dependentBeans.contains(o))
{
_dependentBeans.add(o);
added=true;
}
try
Bean b = new Bean(o);
b._managed=managed;
_beans.add(b);
if (o instanceof LifeCycle)
{
if (isStarted() && o instanceof LifeCycle)
((LifeCycle)o).start();
LifeCycle l=(LifeCycle)o;
// Start the bean if we are started
if (managed && _started)
{
try
{
l.start();
}
catch(Exception e)
{
throw new RuntimeException (e);
}
}
}
catch (Exception e)
return true;
}
/* ------------------------------------------------------------ */
/**
* Manage a bean by this aggregate, so that it is started/stopped/destroyed with the
* aggregate lifecycle.
* @param bean The bean to manage (must already have been added).
*/
public void manage(Object bean)
{
for (Bean b :_beans)
{
throw new RuntimeException (e);
if (b._bean==bean)
{
b._managed=true;
return;
}
}
return added;
throw new IllegalArgumentException();
}
/* ------------------------------------------------------------ */
/**
* Unmanage a bean by this aggregate, so that it is not started/stopped/destroyed with the
* aggregate lifecycle.
* @param bean The bean to manage (must already have been added).
*/
public void unmanage(Object bean)
{
for (Bean b :_beans)
{
if (b._bean==bean)
{
b._managed=false;
return;
}
}
throw new IllegalArgumentException();
}
/* ------------------------------------------------------------ */
/** Get dependent beans
* @return List of beans.
*/
public Collection<Object> getBeans()
{
return _dependentBeans;
return getBeans(Object.class);
}
/* ------------------------------------------------------------ */
@ -109,19 +241,17 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable
public <T> List<T> getBeans(Class<T> clazz)
{
ArrayList<T> beans = new ArrayList<T>();
Iterator<?> iter = _dependentBeans.iterator();
while (iter.hasNext())
for (Bean b:_beans)
{
Object o = iter.next();
if (clazz.isInstance(o))
beans.add((T)o);
if (clazz.isInstance(b._bean))
beans.add((T)(b._bean));
}
return beans;
}
/* ------------------------------------------------------------ */
/** Get dependent bean of a specific class.
/** Get dependent beans of a specific class.
* If more than one bean of the type exist, the first is returned.
* @see #addBean(Object)
* @param clazz
@ -129,23 +259,13 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable
*/
public <T> T getBean(Class<T> clazz)
{
Iterator<?> iter = _dependentBeans.iterator();
T t=null;
int count=0;
while (iter.hasNext())
for (Bean b:_beans)
{
Object o = iter.next();
if (clazz.isInstance(o))
{
count++;
if (t==null)
t=(T)o;
}
if (clazz.isInstance(b._bean))
return (T)b._bean;
}
if (count>1 && LOG.isDebugEnabled())
LOG.debug("getBean({}) 1 of {}",clazz.getName(),count);
return t;
return null;
}
/* ------------------------------------------------------------ */
@ -154,7 +274,7 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable
*/
public void removeBeans ()
{
_dependentBeans.clear();
_beans.clear();
}
/* ------------------------------------------------------------ */
@ -163,9 +283,17 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable
*/
public boolean removeBean (Object o)
{
if (o == null)
return false;
return _dependentBeans.remove(o);
Iterator<Bean> i = _beans.iterator();
while(i.hasNext())
{
Bean b=i.next();
if (b._bean==o)
{
_beans.remove(b);
return true;
}
}
return false;
}
/* ------------------------------------------------------------ */
@ -218,7 +346,32 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable
public void dump(Appendable out,String indent) throws IOException
{
dumpThis(out);
dump(out,indent,_dependentBeans);
int size=_beans.size();
if (size==0)
return;
int i=0;
for (Bean b : _beans)
{
i++;
if (b._managed)
{
out.append(indent).append(" +- ");
if (b._bean instanceof Dumpable)
((Dumpable)b._bean).dump(out,indent+(i==size?" ":" | "));
else
out.append(String.valueOf(b._bean)).append("\n");
}
else
{
out.append(indent).append(" +~ ");
out.append(String.valueOf(b._bean)).append("\n");
}
}
if (i!=size)
out.append(indent).append(" |\n");
}
/* ------------------------------------------------------------ */

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;
for (Logger log : Log.getLoggers().values())
{
this._level = this._configuredLevel;
// restore all cached log configured levels
for(StdErrLog log: __loggers.values())
{
log._level = log._configuredLevel;
}
if (log instanceof StdErrLog)
((StdErrLog)log).setLevel(((StdErrLog)log)._configuredLevel);
}
}
}
@ -570,67 +559,18 @@ public class StdErrLog implements Logger
}
}
/**
* A more robust form of name blank test. Will return true for null names, and names that have only whitespace
*
* @param name
* the name to test
* @return true for null or blank name, false if any non-whitespace character is found.
*/
private static boolean isBlank(String name)
{
if (name == null)
{
return true;
}
int size = name.length();
char c;
for (int i = 0; i < size; i++)
{
c = name.charAt(i);
if (!Character.isWhitespace(c))
{
return false;
}
}
return true;
}
/**
* Get a Child Logger relative to this Logger.
*
* @param name
* the child name
* @return the appropriate child logger (if name specified results in a new unique child)
* Create a Child Logger of this Logger.
*/
public Logger getLogger(String name)
protected Logger newLogger(String fullname)
{
if (isBlank(name))
{
return this;
}
String fullname = name;
if (!isBlank(_name))
{
fullname = _name + "." + name;
}
StdErrLog logger = __loggers.get(fullname);
if (logger == null)
{
StdErrLog sel = new StdErrLog(fullname);
// Preserve configuration for new loggers configuration
sel.setPrintLongNames(_printLongNames);
// Let Level come from configured Properties instead - sel.setLevel(_level);
sel.setSource(_source);
sel._stderr = this._stderr;
logger = __loggers.putIfAbsent(fullname,sel);
if (logger == null)
{
logger = sel;
}
}
StdErrLog logger = new StdErrLog(fullname);
// Preserve configuration for new loggers configuration
logger.setPrintLongNames(_printLongNames);
// Let Level come from configured Properties instead - sel.setLevel(_level);
logger.setSource(_source);
logger._stderr = this._stderr;
return logger;
}

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;
@ -73,7 +72,7 @@ import org.eclipse.jetty.util.security.Password;
public class SslContextFactory extends AbstractLifeCycle
{
private static final Logger LOG = Log.getLogger(SslContextFactory.class);
public static final String DEFAULT_KEYMANAGERFACTORY_ALGORITHM =
(Security.getProperty("ssl.KeyManagerFactory.algorithm") == null ?
"SunX509" : Security.getProperty("ssl.KeyManagerFactory.algorithm"));
@ -96,7 +95,7 @@ public class SslContextFactory extends AbstractLifeCycle
// private final Set<String> _excludeProtocols = new HashSet<String>(Collections.singleton("SSLv2Hello"));
/** Included protocols. */
private Set<String> _includeProtocols = null;
/** Excluded cipher suites. */
private final Set<String> _excludeCipherSuites = new HashSet<String>();
/** Included cipher suites. */
@ -178,7 +177,7 @@ public class SslContextFactory extends AbstractLifeCycle
/** SSL context */
private SSLContext _context;
private boolean _trustAll;
/* ------------------------------------------------------------ */
@ -225,7 +224,7 @@ public class SslContextFactory extends AbstractLifeCycle
_trustStore==null && _trustStoreInputStream == null && _trustStorePath == null )
{
TrustManager[] trust_managers=null;
if (_trustAll)
{
LOG.debug("No keystore or trust store configured. ACCEPTING UNTRUSTED CERTIFICATES!!!!!");
@ -247,7 +246,7 @@ public class SslContextFactory extends AbstractLifeCycle
};
trust_managers = new TrustManager[] { trustAllCerts };
}
SecureRandom secureRandom = (_secureRandomAlgorithm == null)?null:SecureRandom.getInstance(_secureRandomAlgorithm);
_context = SSLContext.getInstance(_sslProtocol);
_context.init(null, trust_managers, secureRandom);
@ -255,7 +254,7 @@ public class SslContextFactory extends AbstractLifeCycle
else
{
// verify that keystore and truststore
// parameters are set up correctly
// parameters are set up correctly
checkKeyStore();
KeyStore keyStore = loadKeyStore();
@ -293,7 +292,7 @@ public class SslContextFactory extends AbstractLifeCycle
_context.init(keyManagers,trustManagers,secureRandom);
SSLEngine engine=newSslEngine();
LOG.info("Enabled Protocols {} of {}",Arrays.asList(engine.getEnabledProtocols()),Arrays.asList(engine.getSupportedProtocols()));
if (LOG.isDebugEnabled())
LOG.debug("Enabled Ciphers {} of {}",Arrays.asList(engine.getEnabledCipherSuites()),Arrays.asList(engine.getSupportedCipherSuites()));
@ -334,7 +333,7 @@ public class SslContextFactory extends AbstractLifeCycle
checkNotStarted();
_excludeProtocols.addAll(Arrays.asList(protocol));
}
/* ------------------------------------------------------------ */
/**
* @return The array of protocol names to include in
@ -380,7 +379,7 @@ public class SslContextFactory extends AbstractLifeCycle
_excludeCipherSuites.clear();
_excludeCipherSuites.addAll(Arrays.asList(cipherSuites));
}
/* ------------------------------------------------------------ */
/**
* @param cipher Cipher names to add to {@link SSLEngine#setEnabledCipherSuites(String[])}
@ -429,7 +428,7 @@ public class SslContextFactory extends AbstractLifeCycle
{
return _keyStorePath;
}
/* ------------------------------------------------------------ */
/**
* @param keyStorePath
@ -878,7 +877,7 @@ public class SslContextFactory extends AbstractLifeCycle
{
return (_keyManagerFactoryAlgorithm);
}
/* ------------------------------------------------------------ */
/**
* @param algorithm
@ -1094,7 +1093,7 @@ public class SslContextFactory extends AbstractLifeCycle
/* ------------------------------------------------------------ */
protected TrustManager[] getTrustManagers(KeyStore trustStore, Collection<? extends CRL> crls) throws Exception
{
{
TrustManager[] managers = null;
if (trustStore != null)
{
@ -1156,15 +1155,15 @@ public class SslContextFactory extends AbstractLifeCycle
* used as truststore.
* @throws IllegalStateException if SslContextFactory configuration can't be used.
*/
public void checkKeyStore()
public void checkKeyStore()
{
if (_context != null)
return; //nothing to check if using preconfigured context
if (_keyStore == null && _keyStoreInputStream == null && _keyStorePath == null)
throw new IllegalStateException("SSL doesn't have a valid keystore");
// if the keystore has been configured but there is no
// truststore configured, use the keystore as the truststore
if (_trustStore == null && _trustStoreInputStream == null && _trustStorePath == null)
@ -1209,7 +1208,7 @@ public class SslContextFactory extends AbstractLifeCycle
public String[] selectProtocols(String[] enabledProtocols, String[] supportedProtocols)
{
Set<String> selected_protocols = new HashSet<String>();
// Set the starting protocols - either from the included or enabled list
if (_includeProtocols!=null)
{
@ -1220,15 +1219,15 @@ public class SslContextFactory extends AbstractLifeCycle
}
else
selected_protocols.addAll(Arrays.asList(enabledProtocols));
// Remove any excluded protocols
if (_excludeProtocols != null)
selected_protocols.removeAll(_excludeProtocols);
return selected_protocols.toArray(new String[selected_protocols.size()]);
}
/* ------------------------------------------------------------ */
/**
* Select cipher suites to be used by the connector
@ -1241,7 +1240,7 @@ public class SslContextFactory extends AbstractLifeCycle
public String[] selectCipherSuites(String[] enabledCipherSuites, String[] supportedCipherSuites)
{
Set<String> selected_ciphers = new HashSet<String>();
// Set the starting ciphers - either from the included or enabled list
if (_includeCipherSuites!=null)
{
@ -1252,8 +1251,8 @@ public class SslContextFactory extends AbstractLifeCycle
}
else
selected_ciphers.addAll(Arrays.asList(enabledCipherSuites));
// Remove any excluded ciphers
if (_excludeCipherSuites != null)
selected_ciphers.removeAll(_excludeCipherSuites);
@ -1450,7 +1449,7 @@ public class SslContextFactory extends AbstractLifeCycle
{
SSLServerSocketFactory factory = _context.getServerSocketFactory();
SSLServerSocket socket =
SSLServerSocket socket =
(SSLServerSocket) (host==null ?
factory.createServerSocket(port,backlog):
factory.createServerSocket(port,backlog,InetAddress.getByName(host)));
@ -1467,14 +1466,14 @@ public class SslContextFactory extends AbstractLifeCycle
return socket;
}
/* ------------------------------------------------------------ */
public SSLSocket newSslSocket() throws IOException
{
SSLSocketFactory factory = _context.getSocketFactory();
SSLSocket socket = (SSLSocket)factory.createSocket();
if (getWantClientAuth())
socket.setWantClientAuth(getWantClientAuth());
if (getNeedClientAuth())
@ -1482,23 +1481,23 @@ public class SslContextFactory extends AbstractLifeCycle
socket.setEnabledCipherSuites(selectCipherSuites(
socket.getEnabledCipherSuites(),
socket.getSupportedCipherSuites()));
socket.getSupportedCipherSuites()));
socket.setEnabledProtocols(selectProtocols(socket.getEnabledProtocols(),socket.getSupportedProtocols()));
return socket;
}
/* ------------------------------------------------------------ */
public SSLEngine newSslEngine(String host,int port)
{
SSLEngine sslEngine=isSessionCachingEnabled()
?_context.createSSLEngine(host, port)
:_context.createSSLEngine();
customize(sslEngine);
return sslEngine;
}
/* ------------------------------------------------------------ */
public SSLEngine newSslEngine()
{
@ -1518,8 +1517,18 @@ public class SslContextFactory extends AbstractLifeCycle
sslEngine.setEnabledCipherSuites(selectCipherSuites(
sslEngine.getEnabledCipherSuites(),
sslEngine.getSupportedCipherSuites()));
sslEngine.setEnabledProtocols(selectProtocols(sslEngine.getEnabledProtocols(),sslEngine.getSupportedProtocols()));
}
/* ------------------------------------------------------------ */
public String toString()
{
return String.format("%s@%x(%s,%s)#%s",
getClass().getSimpleName(),
hashCode(),
_keyStorePath,
_trustStorePath,
getState());
}
}

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()
{
@ -159,6 +260,11 @@ public class AggregateLifeCycleTest
System.err.println("--");
a2.addBean(aa0);
a0.dumpStdErr();
System.err.println("--");
a0.unmanage(aa);
a2.unmanage(aa0);
a0.dumpStdErr();
}
}

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()
{
@ -37,7 +20,7 @@ public class NamedLogTest
red.generateLogs();
green.generateLogs();
blue.generateLogs();
output.assertContains(Red.class.getName());
output.assertContains(Green.class.getName());
output.assertContains(Blue.class.getName());

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;
@ -127,7 +125,7 @@ public class WebSocketLoadD13Test
{
this.outbound = outbound;
}
public void onMessage(String data)
{
try
@ -155,7 +153,7 @@ public class WebSocketLoadD13Test
private final CountDownLatch latch;
private final SocketEndPoint _endp;
private final WebSocketGeneratorRFC6455 _generator;
private final WebSocketParserD13 _parser;
private final WebSocketParserRFC6455 _parser;
private final WebSocketParser.FrameHandler _handler = new WebSocketParser.FrameHandler()
{
public void onFrame(byte flags, byte opcode, Buffer buffer)
@ -168,7 +166,7 @@ public class WebSocketLoadD13Test
}
};
private volatile Buffer _response;
public WebSocketClient(String host, int port, int readTimeout, CountDownLatch latch, int iterations) throws IOException
{
this.latch = latch;
@ -177,11 +175,11 @@ public class WebSocketLoadD13Test
output = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "ISO-8859-1"));
input = new BufferedReader(new InputStreamReader(socket.getInputStream(), "ISO-8859-1"));
this.iterations = iterations;
_endp=new SocketEndPoint(socket);
_generator = new WebSocketGeneratorRFC6455(new WebSocketBuffers(32*1024),_endp,new FixedMaskGen());
_parser = new WebSocketParserD13(new WebSocketBuffers(32*1024),_endp,_handler,false);
_parser = new WebSocketParserRFC6455(new WebSocketBuffers(32*1024),_endp,_handler,false);
}
private void open() throws IOException
@ -216,9 +214,9 @@ public class WebSocketLoadD13Test
byte[] data = message.getBytes(StringUtil.__UTF8);
_generator.addFrame((byte)0x8,WebSocketConnectionRFC6455.OP_TEXT,data,0,data.length);
_generator.flush();
//System.err.println("-> "+message);
_response=null;
while(_response==null)
_parser.parseNext();

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;
@ -78,7 +78,7 @@ public class WebSocketMessageRFC6455Test
}
};
wsHandler.getWebSocketFactory().setBufferSize(8192);
wsHandler.getWebSocketFactory().setMaxIdleTime(1000);
wsHandler.getWebSocketFactory().setMaxIdleTime(1000);
wsHandler.setHandler(new DefaultHandler());
__server.setHandler(wsHandler);
__server.start();
@ -91,13 +91,13 @@ public class WebSocketMessageRFC6455Test
__server.join();
}
@Test
public void testHash()
{
assertEquals("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",WebSocketConnectionRFC6455.hashKey("dGhlIHNhbXBsZSBub25jZQ=="));
}
@Test
public void testServerSendBigStringMessage() throws Exception
{
@ -119,7 +119,7 @@ public class WebSocketMessageRFC6455Test
socket.setSoTimeout(1000);
InputStream input = socket.getInputStream();
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
skipTo("Sec-WebSocket-Accept: ",input);
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
@ -127,7 +127,7 @@ public class WebSocketMessageRFC6455Test
assertTrue(__serverWebSocket.awaitConnected(1000));
assertNotNull(__serverWebSocket.connection);
// Server sends a big message
StringBuilder message = new StringBuilder();
String text = "0123456789ABCDEF";
@ -167,7 +167,7 @@ public class WebSocketMessageRFC6455Test
socket.setSoTimeout(1000);
InputStream input = socket.getInputStream();
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
skipTo("Sec-WebSocket-Accept: ",input);
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
@ -175,7 +175,7 @@ public class WebSocketMessageRFC6455Test
assertTrue(__serverWebSocket.awaitConnected(1000));
assertNotNull(__serverWebSocket.connection);
assertEquals(0x81,input.read());
assertEquals(0x0f,input.read());
lookFor("sent on connect",input);
@ -312,8 +312,8 @@ public class WebSocketMessageRFC6455Test
assertTrue(__serverWebSocket.awaitConnected(1000));
assertNotNull(__serverWebSocket.connection);
// Server sends a big message
String text = "0123456789ABCDEF ";
text=text+text+text+text;
@ -324,15 +324,15 @@ public class WebSocketMessageRFC6455Test
deflater.setInput(data);
deflater.finish();
byte[] buf=new byte[data.length];
buf[0]=(byte)((byte)0x7e);
buf[1]=(byte)(data.length>>8);
buf[2]=(byte)(data.length&0xff);
int l=deflater.deflate(buf,3,buf.length-3);
assertTrue(deflater.finished());
output.write(0xC1);
output.write((byte)(0x80|(0xff&(l+3))));
output.write(0x00);
@ -341,41 +341,41 @@ public class WebSocketMessageRFC6455Test
output.write(0x00);
output.write(buf,0,l+3);
output.flush();
assertEquals(0x40+WebSocketConnectionRFC6455.OP_TEXT,input.read());
assertEquals(0x20+3,input.read());
assertEquals(0x7e,input.read());
assertEquals(0x02,input.read());
assertEquals(0x20,input.read());
byte[] raw = new byte[32];
assertEquals(32,input.read(raw));
Inflater inflater = new Inflater();
inflater.setInput(raw);
byte[] result = new byte[544];
assertEquals(544,inflater.inflate(result));
assertEquals(TypeUtil.toHexString(data,0,544),TypeUtil.toHexString(result));
assertEquals((byte)0xC0,(byte)input.read());
assertEquals(0x21+3,input.read());
assertEquals(0x7e,input.read());
assertEquals(0x02,input.read());
assertEquals(0x21,input.read());
assertEquals(32,input.read(raw));
inflater.reset();
inflater.setInput(raw);
result = new byte[545];
assertEquals(545,inflater.inflate(result));
assertEquals(TypeUtil.toHexString(data,544,545),TypeUtil.toHexString(result));
}
@Test
public void testServerEcho() throws Exception
{
@ -403,10 +403,10 @@ public class WebSocketMessageRFC6455Test
output.write(bytes[i]^0xff);
output.flush();
// Make sure the read times out if there are problems with the implementation
socket.setSoTimeout(1000);
socket.setSoTimeout(1000);
InputStream input = socket.getInputStream();
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
skipTo("Sec-WebSocket-Accept: ",input);
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
@ -414,12 +414,12 @@ public class WebSocketMessageRFC6455Test
assertTrue(__serverWebSocket.awaitConnected(1000));
assertNotNull(__serverWebSocket.connection);
assertEquals(0x84,input.read());
assertEquals(0x0f,input.read());
lookFor("this is an echo",input);
}
@Test
public void testBlockedConsumer() throws Exception
{
@ -436,7 +436,7 @@ public class WebSocketMessageRFC6455Test
mesg[5]=(byte)0xff;
for (int i=0;i<bytes.length;i++)
mesg[6+i]=(byte)(bytes[i]^0xff);
final int count = 100000;
output.write(
@ -489,7 +489,7 @@ public class WebSocketMessageRFC6455Test
}
}
}.start();
// Send enough messages to fill receive buffer
long max=0;
long start=System.currentTimeMillis();
@ -500,7 +500,7 @@ public class WebSocketMessageRFC6455Test
{
// System.err.println(">>> "+i);
output.flush();
long now=System.currentTimeMillis();
long duration=now-start;
start=now;
@ -518,13 +518,13 @@ public class WebSocketMessageRFC6455Test
assertEquals(count+1,__textCount.get()); // all messages
assertTrue(max>2000); // was blocked
}
@Test
public void testBlockedProducer() throws Exception
{
final Socket socket = new Socket("localhost", __connector.getLocalPort());
OutputStream output = socket.getOutputStream();
final int count = 100000;
output.write(
@ -581,8 +581,8 @@ public class WebSocketMessageRFC6455Test
}
}
}.start();
// Send enough messages to fill receive buffer
long max=0;
long start=System.currentTimeMillis();
@ -593,7 +593,7 @@ public class WebSocketMessageRFC6455Test
if (i%100==0)
{
output.flush();
long now=System.currentTimeMillis();
long duration=now-start;
start=now;
@ -601,10 +601,10 @@ public class WebSocketMessageRFC6455Test
max=duration;
}
}
while(totalB.get()<(count*(mesg.length()+2)))
Thread.sleep(100);
assertEquals(count*(mesg.length()+2),totalB.get()); // all messages
assertTrue(max>1000); // was blocked
}
@ -635,7 +635,7 @@ public class WebSocketMessageRFC6455Test
output.flush();
InputStream input = socket.getInputStream();
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
skipTo("Sec-WebSocket-Accept: ",input);
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
@ -668,7 +668,7 @@ public class WebSocketMessageRFC6455Test
socket.setSoTimeout(1000);
InputStream input = socket.getInputStream();
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
skipTo("Sec-WebSocket-Accept: ",input);
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
@ -676,10 +676,10 @@ public class WebSocketMessageRFC6455Test
assertTrue(__serverWebSocket.awaitConnected(1000));
assertNotNull(__serverWebSocket.connection);
__serverWebSocket.getConnection().setMaxTextMessageSize(10*1024);
__serverWebSocket.getConnection().setAllowFrameFragmentation(true);
output.write(0x81);
output.write(0x80|0x7E);
output.write((byte)((16*1024)>>8));
@ -692,7 +692,7 @@ public class WebSocketMessageRFC6455Test
for (int i=0;i<(16*1024);i++)
output.write('X');
output.flush();
assertEquals(0x80|WebSocketConnectionRFC6455.OP_CLOSE,input.read());
assertEquals(33,input.read());
@ -720,7 +720,7 @@ public class WebSocketMessageRFC6455Test
socket.setSoTimeout(1000);
InputStream input = socket.getInputStream();
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
skipTo("Sec-WebSocket-Accept: ",input);
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
@ -728,9 +728,9 @@ public class WebSocketMessageRFC6455Test
assertTrue(__serverWebSocket.awaitConnected(1000));
assertNotNull(__serverWebSocket.connection);
__serverWebSocket.getConnection().setMaxTextMessageSize(15);
output.write(0x01);
output.write(0x8a);
output.write(0xff);
@ -779,7 +779,7 @@ public class WebSocketMessageRFC6455Test
socket.setSoTimeout(100000);
InputStream input = socket.getInputStream();
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
skipTo("Sec-WebSocket-Accept: ",input);
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
@ -787,9 +787,9 @@ public class WebSocketMessageRFC6455Test
assertTrue(__serverWebSocket.awaitConnected(1000));
assertNotNull(__serverWebSocket.connection);
__serverWebSocket.getConnection().setMaxTextMessageSize(15);
output.write(0x01);
output.write(0x94);
output.write(0xff);
@ -800,9 +800,9 @@ public class WebSocketMessageRFC6455Test
for (int i=0;i<bytes.length;i++)
output.write(bytes[i]^0xff);
output.flush();
assertEquals(0x80|WebSocketConnectionRFC6455.OP_CLOSE,input.read());
assertEquals(30,input.read());
int code=(0xff&input.read())*0x100+(0xff&input.read());
@ -829,7 +829,7 @@ public class WebSocketMessageRFC6455Test
socket.setSoTimeout(1000);
InputStream input = socket.getInputStream();
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
skipTo("Sec-WebSocket-Accept: ",input);
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
@ -838,7 +838,7 @@ public class WebSocketMessageRFC6455Test
assertTrue(__serverWebSocket.awaitConnected(1000));
assertNotNull(__serverWebSocket.connection);
__serverWebSocket.getConnection().setMaxBinaryMessageSize(1024);
output.write(WebSocketConnectionRFC6455.OP_BINARY);
output.write(0x8a);
output.write(0xff);
@ -859,12 +859,12 @@ public class WebSocketMessageRFC6455Test
for (int i=0;i<bytes.length;i++)
output.write(bytes[i]^0xff);
output.flush();
assertEquals(0x80+WebSocketConnectionRFC6455.OP_BINARY,input.read());
assertEquals(20,input.read());
lookFor("01234567890123456789",input);
}
@Test
public void testMaxBinarySize() throws Exception
{
@ -884,7 +884,7 @@ public class WebSocketMessageRFC6455Test
socket.setSoTimeout(100000);
InputStream input = socket.getInputStream();
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
skipTo("Sec-WebSocket-Accept: ",input);
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
@ -892,9 +892,9 @@ public class WebSocketMessageRFC6455Test
assertTrue(__serverWebSocket.awaitConnected(1000));
assertNotNull(__serverWebSocket.connection);
__serverWebSocket.getConnection().setMaxBinaryMessageSize(15);
output.write(0x02);
output.write(0x8a);
output.write(0xff);
@ -916,20 +916,20 @@ public class WebSocketMessageRFC6455Test
output.write(bytes[i]^0xff);
output.flush();
assertEquals(0x80|WebSocketConnectionRFC6455.OP_CLOSE,input.read());
assertEquals(19,input.read());
int code=(0xff&input.read())*0x100+(0xff&input.read());
assertEquals(WebSocketConnectionRFC6455.CLOSE_MESSAGE_TOO_LARGE,code);
lookFor("Message size > 15",input);
}
@Test
public void testCloseIn() throws Exception
{
int[][] tests =
int[][] tests =
{
{-1,0,-1},
{-1,0,-1},
@ -960,7 +960,7 @@ public class WebSocketMessageRFC6455Test
"",
"mesg"
};
String[] resp =
{
"",
@ -1007,14 +1007,14 @@ public class WebSocketMessageRFC6455Test
int code=tests[t][0];
String m=mesg[t];
output.write(0x88);
output.write(0x80 + (code<=0?0:(2+m.length())));
output.write(0x00);
output.write(0x00);
output.write(0x00);
output.write(0x00);
if (code>0)
{
output.write(code/0x100);
@ -1022,12 +1022,12 @@ public class WebSocketMessageRFC6455Test
output.write(m.getBytes());
}
output.flush();
__serverWebSocket.awaitDisconnected(1000);
byte[] buf = new byte[128];
int len = input.read(buf);
assertEquals(tst,2+tests[t][1],len);
assertEquals(tst,(byte)0x88,buf[0]);
@ -1035,7 +1035,7 @@ public class WebSocketMessageRFC6455Test
{
code=(0xff&buf[2])*0x100+(0xff&buf[3]);
assertEquals(tst,tests[t][2],code);
if (len>4)
{
m = new String(buf,4,len-4,"UTF-8");
@ -1044,19 +1044,19 @@ public class WebSocketMessageRFC6455Test
}
else
assertEquals(tst,tests[t][2],-1);
len = input.read(buf);
assertEquals(tst,-1,len);
}
}
@Test
public void testCloseOut() throws Exception
{
int[][] tests =
int[][] tests =
{
{-1,0,-1},
{-1,0,-1},
@ -1127,7 +1127,7 @@ public class WebSocketMessageRFC6455Test
{
int code=(0xff&buf[2])*0x100+(0xff&buf[3]);
assertEquals(tst,tests[t][2],code);
if (len>4)
{
String m = new String(buf,4,len-4,"UTF-8");
@ -1136,7 +1136,7 @@ public class WebSocketMessageRFC6455Test
}
else
assertEquals(tst,tests[t][2],-1);
try
{
output.write(0x88);
@ -1152,12 +1152,12 @@ public class WebSocketMessageRFC6455Test
System.err.println("socket "+socket);
throw e;
}
len = input.read(buf);
assertEquals(tst,-1,len);
}
}
}
@Test
public void testNotUTF8() throws Exception
@ -1225,7 +1225,7 @@ public class WebSocketMessageRFC6455Test
socket.setSoTimeout(100000);
InputStream input = socket.getInputStream();
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
skipTo("Sec-WebSocket-Accept: ",input);
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
@ -1233,9 +1233,9 @@ public class WebSocketMessageRFC6455Test
assertTrue(__serverWebSocket.awaitConnected(1000));
assertNotNull(__serverWebSocket.connection);
__serverWebSocket.getConnection().setMaxBinaryMessageSize(15);
output.write(0x02);
output.write(0x94);
output.write(0xff);
@ -1246,7 +1246,7 @@ public class WebSocketMessageRFC6455Test
for (int i=0;i<bytes.length;i++)
output.write(bytes[i]^0xff);
output.flush();
assertEquals(0x80|WebSocketConnectionRFC6455.OP_CLOSE,input.read());
assertEquals(19,input.read());
int code=(0xff&input.read())*0x100+(0xff&input.read());
@ -1283,7 +1283,7 @@ public class WebSocketMessageRFC6455Test
assertTrue(__serverWebSocket.awaitConnected(1000));
assertNotNull(__serverWebSocket.connection);
assertEquals(0x81,input.read());
assertEquals(0x0f,input.read());
lookFor("sent on connect",input);
@ -1302,8 +1302,8 @@ public class WebSocketMessageRFC6455Test
output.write(0xff);
output.write(0xff);
output.flush();
assertTrue(__serverWebSocket.awaitDisconnected(5000));
try
{
@ -1346,12 +1346,12 @@ public class WebSocketMessageRFC6455Test
assertTrue(__serverWebSocket.awaitConnected(1000));
assertNotNull(__serverWebSocket.connection);
assertEquals(0x81,input.read());
assertEquals(0x0f,input.read());
lookFor("sent on connect",input);
socket.close();
assertTrue(__serverWebSocket.awaitDisconnected(500));
try
@ -1362,7 +1362,7 @@ public class WebSocketMessageRFC6455Test
catch(IOException e)
{
assertTrue(true);
}
}
}
@Test
@ -1395,19 +1395,19 @@ public class WebSocketMessageRFC6455Test
assertTrue(__serverWebSocket.awaitConnected(1000));
assertNotNull(__serverWebSocket.connection);
assertEquals(0x81,input.read());
assertEquals(0x0f,input.read());
lookFor("sent on connect",input);
socket.shutdownOutput();
assertTrue(__serverWebSocket.awaitDisconnected(500));
assertEquals(0x88,input.read());
assertEquals(0x00,input.read());
assertEquals(-1,input.read());
// look for broken pipe
try
{
@ -1420,24 +1420,24 @@ public class WebSocketMessageRFC6455Test
// expected
}
}
@Test
public void testParserAndGenerator() throws Exception
{
String message = "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF";
final AtomicReference<String> received = new AtomicReference<String>();
ByteArrayEndPoint endp = new ByteArrayEndPoint(new byte[0],4096);
WebSocketGeneratorRFC6455 gen = new WebSocketGeneratorRFC6455(new WebSocketBuffers(8096),endp,null);
byte[] data = message.getBytes(StringUtil.__UTF8);
gen.addFrame((byte)0x8,(byte)0x4,data,0,data.length);
endp = new ByteArrayEndPoint(endp.getOut().asArray(),4096);
WebSocketParserD13 parser = new WebSocketParserD13(new WebSocketBuffers(8096),endp,new WebSocketParser.FrameHandler()
WebSocketParserRFC6455 parser = new WebSocketParserRFC6455(new WebSocketBuffers(8096),endp,new WebSocketParser.FrameHandler()
{
public void onFrame(byte flags, byte opcode, Buffer buffer)
{
@ -1449,12 +1449,12 @@ public class WebSocketMessageRFC6455Test
}
},false);
parser.parseNext();
assertEquals(message,received.get());
}
@Test
public void testParserAndGeneratorMasked() throws Exception
{
@ -1463,14 +1463,14 @@ public class WebSocketMessageRFC6455Test
ByteArrayEndPoint endp = new ByteArrayEndPoint(new byte[0],4096);
MaskGen maskGen = new RandomMaskGen();
WebSocketGeneratorRFC6455 gen = new WebSocketGeneratorRFC6455(new WebSocketBuffers(8096),endp,maskGen);
byte[] data = message.getBytes(StringUtil.__UTF8);
gen.addFrame((byte)0x8,(byte)0x1,data,0,data.length);
endp = new ByteArrayEndPoint(endp.getOut().asArray(),4096);
WebSocketParserD13 parser = new WebSocketParserD13(new WebSocketBuffers(8096),endp,new WebSocketParser.FrameHandler()
WebSocketParserRFC6455 parser = new WebSocketParserRFC6455(new WebSocketBuffers(8096),endp,new WebSocketParser.FrameHandler()
{
public void onFrame(byte flags, byte opcode, Buffer buffer)
{
@ -1481,13 +1481,13 @@ public class WebSocketMessageRFC6455Test
{
}
},true);
parser.parseNext();
assertEquals(message,received.get());
}
private void lookFor(String string,InputStream in)
throws IOException
{
@ -1535,7 +1535,7 @@ public class WebSocketMessageRFC6455Test
state=0;
}
}
private static class TestWebSocket implements WebSocket.OnFrame, WebSocket.OnBinaryMessage, WebSocket.OnTextMessage
{
@ -1556,7 +1556,7 @@ public class WebSocketMessageRFC6455Test
{
this.connection = connection;
}
public void onOpen(Connection connection)
{
if (_onConnect)
@ -1582,14 +1582,14 @@ public class WebSocketMessageRFC6455Test
{
return disconnected.await(time, TimeUnit.MILLISECONDS);
}
public void onClose(int code,String message)
{
disconnected.countDown();
}
public boolean onFrame(byte flags, byte opcode, byte[] data, int offset, int length)
{
{
if (_echo)
{
switch(opcode)
@ -1598,7 +1598,7 @@ public class WebSocketMessageRFC6455Test
case WebSocketConnectionRFC6455.OP_PING:
case WebSocketConnectionRFC6455.OP_PONG:
break;
default:
try
{
@ -1642,7 +1642,7 @@ public class WebSocketMessageRFC6455Test
e.printStackTrace();
}
}
if (_aggregate)
{
try

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;
@ -45,7 +47,7 @@ public class WebSocketParserRFC6455Test
{
super(4096);
}
public void sendMask()
{
super.poke(putIndex(),_mask,0,4);
@ -63,7 +65,7 @@ public class WebSocketParserRFC6455Test
{
super.put(b);
}
@Override
public void put(byte b)
{
@ -87,10 +89,10 @@ public class WebSocketParserRFC6455Test
{
return put(b,0,b.length);
}
};
@Before
public void setUp() throws Exception
{
@ -98,10 +100,10 @@ public class WebSocketParserRFC6455Test
_endPoint = new ByteArrayEndPoint();
_endPoint.setNonBlocking(true);
_handler = new Handler();
_parser=new WebSocketParserD13(buffers, _endPoint,_handler,true);
_parser=new WebSocketParserRFC6455(buffers, _endPoint,_handler,true);
_parser.setFakeFragments(false);
_in = new MaskedByteArrayBuffer();
_endPoint.setIn(_in);
}
@ -127,7 +129,7 @@ public class WebSocketParserRFC6455Test
_parser.returnBuffer();
assertTrue(_parser.getBuffer()==null);
}
@Test
public void testShortText() throws Exception
{
@ -147,7 +149,7 @@ public class WebSocketParserRFC6455Test
_parser.returnBuffer();
assertTrue(_parser.getBuffer()==null);
}
@Test
public void testShortUtf8() throws Exception
{
@ -169,7 +171,7 @@ public class WebSocketParserRFC6455Test
assertTrue(_parser.isBufferEmpty());
assertTrue(_parser.getBuffer()==null);
}
@Test
public void testMediumText() throws Exception
{
@ -177,9 +179,9 @@ public class WebSocketParserRFC6455Test
for (int i=0;i<4;i++)
string = string+string;
string += ". The end.";
byte[] bytes = string.getBytes(StringUtil.__UTF8);
_in.putUnmasked((byte)0x81);
_in.putUnmasked((byte)(0x80|0x7E));
_in.putUnmasked((byte)(bytes.length>>8));
@ -197,21 +199,21 @@ public class WebSocketParserRFC6455Test
assertTrue(_parser.isBufferEmpty());
assertTrue(_parser.getBuffer()==null);
}
@Test
public void testLongText() throws Exception
{
WebSocketBuffers buffers = new WebSocketBuffers(0x20000);
ByteArrayEndPoint endPoint = new ByteArrayEndPoint();
WebSocketParserD13 parser=new WebSocketParserD13(buffers, endPoint,_handler,false);
WebSocketParserRFC6455 parser=new WebSocketParserRFC6455(buffers, endPoint,_handler,false);
ByteArrayBuffer in = new ByteArrayBuffer(0x20000);
endPoint.setIn(in);
String string = "Hell\uFF4f Big W\uFF4Frld ";
for (int i=0;i<12;i++)
string = string+string;
string += ". The end.";
byte[] bytes = string.getBytes("UTF-8");
_in.sendMask();
@ -269,7 +271,7 @@ public class WebSocketParserRFC6455Test
{
// Buffers are only 1024, so this frame is too large
_parser.setFakeFragments(false);
_in.putUnmasked((byte)0x81);
_in.putUnmasked((byte)(0x80|0x7E));
_in.putUnmasked((byte)(2048>>8));
@ -280,8 +282,8 @@ public class WebSocketParserRFC6455Test
assertTrue(progress>0);
assertEquals(WebSocketConnectionRFC6455.CLOSE_POLICY_VIOLATION,_handler._code);
for (int i=0;i<2048;i++)
_in.put((byte)'a');
progress =_parser.parseNext();
@ -289,7 +291,7 @@ public class WebSocketParserRFC6455Test
assertTrue(progress>0);
assertEquals(0,_handler._data.size());
assertEquals(0,_handler._utf8.length());
_handler._code=0;
_in.putUnmasked((byte)0x81);
@ -310,7 +312,7 @@ public class WebSocketParserRFC6455Test
{
// Buffers are only 1024, so this frame will be fake fragmented
_parser.setFakeFragments(true);
_in.putUnmasked((byte)0x81);
_in.putUnmasked((byte)(0x80|0x7E));
_in.putUnmasked((byte)(2048>>8));
@ -318,7 +320,7 @@ public class WebSocketParserRFC6455Test
_in.sendMask();
for (int i=0;i<2048;i++)
_in.put((byte)('a'+i%26));
int progress =_parser.parseNext();
assertTrue(progress>0);
@ -355,21 +357,21 @@ public class WebSocketParserRFC6455Test
_parser.returnBuffer();
assertTrue(_parser.isBufferEmpty());
assertTrue(_parser.getBuffer()==null);
_in.clear();
_in.put(bytes);
_endPoint.setIn(_in);
progress =_parser.parseNext();
assertTrue(progress>0);
_endPoint.shutdownInput();
progress =_parser.parseNext();
assertEquals(-1,progress);
}
private class Handler implements WebSocketParser.FrameHandler
{
Utf8StringBuilder _utf8 = new Utf8StringBuilder();

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