Merge of jetty-7 into jetty-8

Conflicts:
	VERSION.txt
	example-jetty-embedded/pom.xml
	jetty-aggregate/jetty-all-server/pom.xml
	jetty-aggregate/jetty-all/pom.xml
	jetty-aggregate/jetty-client/pom.xml
	jetty-aggregate/jetty-plus/pom.xml
	jetty-aggregate/jetty-server/pom.xml
	jetty-aggregate/jetty-servlet/pom.xml
	jetty-aggregate/jetty-webapp/pom.xml
	jetty-aggregate/pom.xml
	jetty-ajp/pom.xml
	jetty-annotations/pom.xml
	jetty-client/pom.xml
	jetty-continuation/pom.xml
	jetty-deploy/pom.xml
	jetty-distribution/pom.xml
	jetty-http/pom.xml
	jetty-io/pom.xml
	jetty-jaspi/pom.xml
	jetty-jmx/pom.xml
	jetty-jndi/pom.xml
	jetty-jsp-2.1/pom.xml
	jetty-nested/pom.xml
	jetty-osgi/jetty-osgi-boot-jsp/pom.xml
	jetty-osgi/jetty-osgi-boot-logback/pom.xml
	jetty-osgi/jetty-osgi-boot-warurl/pom.xml
	jetty-osgi/jetty-osgi-boot/META-INF/MANIFEST.MF
	jetty-osgi/jetty-osgi-boot/pom.xml
	jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiAppProvider.java
	jetty-osgi/jetty-osgi-equinoxtools/META-INF/MANIFEST.MF
	jetty-osgi/jetty-osgi-equinoxtools/pom.xml
	jetty-osgi/jetty-osgi-equinoxtools/src/main/java/org/eclipse/jetty/osgi/equinoxtools/console/EquinoxConsoleContinuationServlet.java
	jetty-osgi/jetty-osgi-httpservice/pom.xml
	jetty-osgi/jetty-osgi-servletbridge/pom.xml
	jetty-osgi/pom.xml
	jetty-osgi/test-jetty-osgi/pom.xml
	jetty-overlay-deployer/pom.xml
	jetty-plus/pom.xml
	jetty-policy/pom.xml
	jetty-rewrite/pom.xml
	jetty-security/pom.xml
	jetty-server/pom.xml
	jetty-servlet/pom.xml
	jetty-servlets/pom.xml
	jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java
	jetty-start/pom.xml
	jetty-util/pom.xml
	jetty-webapp/pom.xml
	jetty-websocket/pom.xml
	jetty-xml/pom.xml
	pom.xml
	test-continuation-jetty6/pom.xml
	test-continuation/pom.xml
	test-jetty-nested/pom.xml
	test-jetty-servlet/pom.xml
	test-jetty-webapp/pom.xml
	tests/pom.xml
	tests/test-integration/pom.xml
	tests/test-loginservice/pom.xml
	tests/test-sessions/pom.xml
	tests/test-sessions/test-hash-sessions/pom.xml
	tests/test-sessions/test-jdbc-sessions/pom.xml
	tests/test-sessions/test-sessions-common/pom.xml
	tests/test-webapps/pom.xml
	tests/test-webapps/test-webapp-rfc2616/pom.xml
This commit is contained in:
Jan Bartel 2011-07-11 12:05:58 +10:00
commit 86f7e76c4d
104 changed files with 3731 additions and 1135 deletions

View File

@ -1,3 +1,6 @@
jetty-8.0.0.RC0
+ Merge from jetty-7.4.3
jetty-8.0.0.M3 jetty-8.0.0.M3
+ 324505 Implement API login + 324505 Implement API login
+ 335500 request.getParts() throws a NullPointerException + 335500 request.getParts() throws a NullPointerException
@ -5,6 +8,42 @@ jetty-8.0.0.M3
+ 346180 jsp-2.2 support + 346180 jsp-2.2 support
+ Updated to jetty-7.4.2.v20110526 + Updated to jetty-7.4.2.v20110526
jetty-7.4.4.v20110707 July 7th 2011
+ 308851 Converted all jetty-client module tests to JUnit 4
+ 345268 JDBCSessionManager does not work with maxInactiveInterval = -1
+ 350397 SelectChannelConnector does not shutdown gracefully
+ 350634 Reverted FileResource constructor changes
+ 351039 Forward dispatch should retain locale
+ 351199 HttpServletResponse.encodeURL() wrongly encodes an url without path when cookies are disabled
+ JETTY-1153 Default charset/encoding of HTTP POST requests
+ JETTY-1380 Jetty Rewrite example does not work in Hightide
jetty-7.4.3.v20110701 01 July 2011
+ 295832 ProxyServlet more extensible and configurable
+ 302566 GZIP handler for embedded Jetty servers
+ 308851 Converted HttpExchangeTest and related tests to JUnit 4
+ 324704 JDBC Session Manager reloading session
+ 332200 Eliminate expected exceptions from log while using org.eclipse.jetty.jmx bundle
+ 347468 o.e.j.deploy.binding.GlobalWebappConfigBindingTest fails on Windows platform
+ 347617 Dynamically install/update/remove OSGi bundles discovered in the contexts folder
+ 347717 start.jar destroys dependent child of --exec
+ 347889 OSGi should follow directive visibility:=reexport for META-INF/web-fragments and resources
+ 347898 Close channel on JVM exceptions
+ 348652 jetty.sh starts two unix processes
+ 348935 Close A tag in directory listing
+ 349344 Passing empty query string to UrlEncoded#decodeTo(String, MultiMap, String) does not yield an empty map
+ 349738 set buffer sizes for http client in proxy servlet
+ 349870 proxy servlet protect continuation against fast failing exchanges
+ 349896 SCEP supports zero maxIdleTime
+ 349897 draft -09 websockets
+ 349997 MBeanContainer uses weak references
+ 350533 Add "Origin" to the list of allowed headers in CrossOriginFilter
+ 350634 Cleanup FileResource construction
+ 350642 Don't close SCEP during NIOBuffer manipulation
+ JETTY-1342 Recreate selector in change task
+ JETTY-1385 NPE in jetty client's HTttpExchange.setRequestContentSource(InputStream)
+ JETTY-1390 RewriteHandler handles encoded URIs
jetty-7.4.2.v20110526 jetty-7.4.2.v20110526
+ 334443 Improve the ability to specify extra class paths using the Jetty Maven Plugin + 334443 Improve the ability to specify extra class paths using the Jetty Maven Plugin
+ 336220 tmp directory is not set if you reload a webapp with jetty-maven-plugin + 336220 tmp directory is not set if you reload a webapp with jetty-maven-plugin

View File

@ -6,7 +6,7 @@
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>example-jetty-embedded</artifactId> <artifactId>example-jetty-embedded</artifactId>
<name>Example :: Embedded Jetty Examples</name> <name>Example :: Jetty Embedded</name>
<description>Jetty Embedded Examples</description> <description>Jetty Embedded Examples</description>
<build> <build>
<plugins> <plugins>
@ -48,5 +48,16 @@
<artifactId>jetty-websocket</artifactId> <artifactId>jetty-websocket</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>test-jetty-servlet</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -50,7 +50,6 @@ public class ManyConnectors
cf.setKeyStore(jetty_home + "/etc/keystore"); cf.setKeyStore(jetty_home + "/etc/keystore");
cf.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); cf.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
cf.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); cf.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
server.addConnector(ssl_connector);
server.setConnectors(new Connector[] server.setConnectors(new Connector[]
{ connector0, connector1, ssl_connector }); { connector0, connector1, ssl_connector });

View File

@ -0,0 +1,126 @@
// ========================================================================
// 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.embedded;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.zip.GZIPInputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.GzipHandler;
import org.eclipse.jetty.testing.HttpTester;
import org.eclipse.jetty.util.IO;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class GzipHandlerTest
{
private static String __content =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis felis nunc. "+
"Quisque suscipit mauris et ante auctor ornare rhoncus lacus aliquet. Pellentesque "+
"habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. "+
"Vestibulum sit amet felis augue, vel convallis dolor. Cras accumsan vehicula diam "+
"at faucibus. Etiam in urna turpis, sed congue mi. Morbi et lorem eros. Donec vulputate "+
"velit in risus suscipit lobortis. Aliquam id urna orci, nec sollicitudin ipsum. "+
"Cras a orci turpis. Donec suscipit vulputate cursus. Mauris nunc tellus, fermentum "+
"eu auctor ut, mollis at diam. Quisque porttitor ultrices metus, vitae tincidunt massa "+
"sollicitudin a. Vivamus porttitor libero eget purus hendrerit cursus. Integer aliquam "+
"consequat mauris quis luctus. Cras enim nibh, dignissim eu faucibus ac, mollis nec neque. "+
"Aliquam purus mauris, consectetur nec convallis lacinia, porta sed ante. Suspendisse "+
"et cursus magna. Donec orci enim, molestie a lobortis eu, imperdiet vitae neque.";
private Server _server;
private LocalConnector _connector;
@Before
public void init() throws Exception
{
_server = new Server();
_connector = new LocalConnector();
_server.addConnector(_connector);
Handler testHandler = new AbstractHandler()
{
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException,
ServletException
{
PrintWriter writer = response.getWriter();
writer.write(__content);
writer.close();
baseRequest.setHandled(true);
}
};
GzipHandler gzipHandler = new GzipHandler();
gzipHandler.setHandler(testHandler);
_server.setHandler(gzipHandler);
_server.start();
}
@After
public void destroy() throws Exception
{
_server.stop();
_server.join();
}
@Test
public void testGzipHandler() throws Exception
{
// generated and parsed test
HttpTester request = new HttpTester();
HttpTester response = new HttpTester();
request.setMethod("GET");
request.setVersion("HTTP/1.0");
request.setHeader("Host","tester");
request.setHeader("accept-encoding","gzip");
request.setURI("/");
ByteArrayBuffer reqsBuff = new ByteArrayBuffer(request.generate().getBytes());
ByteArrayBuffer respBuff = _connector.getResponses(reqsBuff, false);
response.parse(respBuff.asArray());
assertTrue(response.getMethod()==null);
assertTrue(response.getHeader("Content-Encoding").equalsIgnoreCase("gzip"));
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes()));
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
IO.copy(testIn,testOut);
assertEquals(__content, testOut.toString("UTF8"));
}
}

BIN
icon.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -586,7 +586,7 @@ public class HttpExchange
public void setRequestContentSource(InputStream stream) public void setRequestContentSource(InputStream stream)
{ {
_requestContentSource = stream; _requestContentSource = stream;
if (_requestContentSource.markSupported()) if (_requestContentSource != null && _requestContentSource.markSupported())
_requestContentSource.mark(Integer.MAX_VALUE); _requestContentSource.mark(Integer.MAX_VALUE);
} }

View File

@ -14,6 +14,10 @@
package org.eclipse.jetty.client; package org.eclipse.jetty.client;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.IOException; import java.io.IOException;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
@ -22,8 +26,6 @@ import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import junit.framework.TestCase;
import org.eclipse.jetty.io.Buffer; import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Request;
@ -32,17 +34,20 @@ import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector; import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.StdErrLog; import org.eclipse.jetty.util.log.StdErrLog;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/** /**
* @version $Revision$ $Date$ * @version $Revision$ $Date$
*/ */
public abstract class AbstractHttpExchangeCancelTest extends TestCase public abstract class AbstractHttpExchangeCancelTest
{ {
private Server server; private Server server;
private Connector connector; private Connector connector;
@Override @Before
protected void setUp() throws Exception public void setUp() throws Exception
{ {
server = new Server(); server = new Server();
connector = new SelectChannelConnector(); connector = new SelectChannelConnector();
@ -51,13 +56,15 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase
server.start(); server.start();
} }
@Override @After
protected void tearDown() throws Exception public void tearDown() throws Exception
{ {
server.stop(); server.stop();
server.join(); server.join();
} }
/* ------------------------------------------------------------ */
@Test
public void testHttpExchangeCancelOnSend1() throws Exception public void testHttpExchangeCancelOnSend1() throws Exception
{ {
// One of the first things that HttpClient.send() does // One of the first things that HttpClient.send() does
@ -93,6 +100,8 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase
assertFalse(exchange.isAssociated()); assertFalse(exchange.isAssociated());
} }
/* ------------------------------------------------------------ */
@Test
public void testHttpExchangeCancelOnSend2() throws Exception public void testHttpExchangeCancelOnSend2() throws Exception
{ {
// One of the first things that HttpClient.send() does // One of the first things that HttpClient.send() does
@ -129,6 +138,8 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase
assertFalse(exchange.isAssociated()); assertFalse(exchange.isAssociated());
} }
/* ------------------------------------------------------------ */
@Test
public void testHttpExchangeCancelOnRequestCommitted() throws Exception public void testHttpExchangeCancelOnRequestCommitted() throws Exception
{ {
TestHttpExchange exchange = new TestHttpExchange() TestHttpExchange exchange = new TestHttpExchange()
@ -152,6 +163,8 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase
assertFalse(exchange.isAssociated()); assertFalse(exchange.isAssociated());
} }
/* ------------------------------------------------------------ */
@Test
public void testHttpExchangeCancelOnRequestComplete() throws Exception public void testHttpExchangeCancelOnRequestComplete() throws Exception
{ {
TestHttpExchange exchange = new TestHttpExchange() TestHttpExchange exchange = new TestHttpExchange()
@ -175,6 +188,8 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase
assertFalse(exchange.isAssociated()); assertFalse(exchange.isAssociated());
} }
/* ------------------------------------------------------------ */
@Test
public void testHttpExchangeCancelOnResponseStatus() throws Exception public void testHttpExchangeCancelOnResponseStatus() throws Exception
{ {
TestHttpExchange exchange = new TestHttpExchange() TestHttpExchange exchange = new TestHttpExchange()
@ -198,6 +213,8 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase
assertFalse(exchange.isAssociated()); assertFalse(exchange.isAssociated());
} }
/* ------------------------------------------------------------ */
@Test
public void testHttpExchangeCancelOnResponseHeader() throws Exception public void testHttpExchangeCancelOnResponseHeader() throws Exception
{ {
TestHttpExchange exchange = new TestHttpExchange() TestHttpExchange exchange = new TestHttpExchange()
@ -221,6 +238,8 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase
assertFalse(exchange.isAssociated()); assertFalse(exchange.isAssociated());
} }
/* ------------------------------------------------------------ */
@Test
public void testHttpExchangeCancelOnResponseHeadersComplete() throws Exception public void testHttpExchangeCancelOnResponseHeadersComplete() throws Exception
{ {
TestHttpExchange exchange = new TestHttpExchange() TestHttpExchange exchange = new TestHttpExchange()
@ -244,6 +263,8 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase
assertFalse(exchange.isAssociated()); assertFalse(exchange.isAssociated());
} }
/* ------------------------------------------------------------ */
@Test
public void testHttpExchangeCancelOnResponseContent() throws Exception public void testHttpExchangeCancelOnResponseContent() throws Exception
{ {
TestHttpExchange exchange = new TestHttpExchange() TestHttpExchange exchange = new TestHttpExchange()
@ -267,6 +288,8 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase
assertFalse(exchange.isAssociated()); assertFalse(exchange.isAssociated());
} }
/* ------------------------------------------------------------ */
@Test
public void testHttpExchangeCancelOnResponseComplete() throws Exception public void testHttpExchangeCancelOnResponseComplete() throws Exception
{ {
TestHttpExchange exchange = new TestHttpExchange() TestHttpExchange exchange = new TestHttpExchange()
@ -290,6 +313,8 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase
assertEquals(HttpExchange.STATUS_COMPLETED, status); assertEquals(HttpExchange.STATUS_COMPLETED, status);
} }
/* ------------------------------------------------------------ */
@Test
public void testHttpExchangeOnServerException() throws Exception public void testHttpExchangeOnServerException() throws Exception
{ {
try try
@ -313,6 +338,8 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase
} }
} }
/* ------------------------------------------------------------ */
@Test
public void testHttpExchangeOnExpire() throws Exception public void testHttpExchangeOnExpire() throws Exception
{ {
HttpClient httpClient = getHttpClient(); HttpClient httpClient = getHttpClient();
@ -338,15 +365,19 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase
assertFalse(exchange.isAssociated()); assertFalse(exchange.isAssociated());
} }
/* ------------------------------------------------------------ */
protected abstract HttpClient getHttpClient(); protected abstract HttpClient getHttpClient();
/* ------------------------------------------------------------ */
protected Address newAddress() protected Address newAddress()
{ {
return new Address("localhost", connector.getLocalPort()); return new Address("localhost", connector.getLocalPort());
} }
/* ------------------------------------------------------------ */
private static class EmptyHandler extends AbstractHandler private static class EmptyHandler extends AbstractHandler
{ {
/* ------------------------------------------------------------ */
public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
{ {
request.setHandled(true); request.setHandled(true);
@ -382,28 +413,33 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase
} }
} }
/* ------------------------------------------------------------ */
protected static class TestHttpExchange extends ContentExchange protected static class TestHttpExchange extends ContentExchange
{ {
private boolean responseCompleted; private boolean responseCompleted;
private boolean failed = false; private boolean failed = false;
private boolean expired = false; private boolean expired = false;
/* ------------------------------------------------------------ */
protected TestHttpExchange() protected TestHttpExchange()
{ {
super(true); super(true);
} }
/* ------------------------------------------------------------ */
@Override @Override
protected synchronized void onResponseComplete() throws IOException protected synchronized void onResponseComplete() throws IOException
{ {
this.responseCompleted = true; this.responseCompleted = true;
} }
/* ------------------------------------------------------------ */
public synchronized boolean isResponseCompleted() public synchronized boolean isResponseCompleted()
{ {
return responseCompleted; return responseCompleted;
} }
/* ------------------------------------------------------------ */
@Override @Override
protected synchronized void onException(Throwable ex) protected synchronized void onException(Throwable ex)
{ {
@ -414,17 +450,20 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase
failed = true; failed = true;
} }
/* ------------------------------------------------------------ */
public synchronized boolean isFailed() public synchronized boolean isFailed()
{ {
return failed; return failed;
} }
/* ------------------------------------------------------------ */
@Override @Override
protected synchronized void onExpire() protected synchronized void onExpire()
{ {
this.expired = true; this.expired = true;
} }
/* ------------------------------------------------------------ */
public synchronized boolean isExpired() public synchronized boolean isExpired()
{ {
return expired; return expired;

View File

@ -14,6 +14,8 @@
package org.eclipse.jetty.client; package org.eclipse.jetty.client;
import static org.junit.Assert.assertNull;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
@ -22,13 +24,15 @@ import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import junit.framework.TestCase; import org.junit.Test;
/* ------------------------------------------------------------ */
/** /**
* @version $Revision$ $Date$ * @version $Revision$ $Date$
*/ */
public class AsyncCallbackHttpExchangeTest extends TestCase public class AsyncCallbackHttpExchangeTest
{ {
/* ------------------------------------------------------------ */
/** /**
* If the HttpExchange callbacks are called holding the lock on HttpExchange, * If the HttpExchange callbacks are called holding the lock on HttpExchange,
* it will be impossible for the callback to perform some work asynchronously * it will be impossible for the callback to perform some work asynchronously
@ -37,6 +41,7 @@ public class AsyncCallbackHttpExchangeTest extends TestCase
* *
* @throws Exception if the test fails * @throws Exception if the test fails
*/ */
@Test
public void testAsyncCallback() throws Exception public void testAsyncCallback() throws Exception
{ {
ExecutorService executor = Executors.newCachedThreadPool(); ExecutorService executor = Executors.newCachedThreadPool();
@ -56,22 +61,26 @@ public class AsyncCallbackHttpExchangeTest extends TestCase
} }
} }
/* ------------------------------------------------------------ */
private class TestHttpExchange extends HttpExchange private class TestHttpExchange extends HttpExchange
{ {
private final ExecutorService executor; private final ExecutorService executor;
private final AtomicReference<Exception> failure; private final AtomicReference<Exception> failure;
/* ------------------------------------------------------------ */
private TestHttpExchange(ExecutorService executor, AtomicReference<Exception> failure) private TestHttpExchange(ExecutorService executor, AtomicReference<Exception> failure)
{ {
this.executor = executor; this.executor = executor;
this.failure = failure; this.failure = failure;
} }
/* ------------------------------------------------------------ */
@Override @Override
protected void onRequestCommitted() throws IOException protected void onRequestCommitted() throws IOException
{ {
Future<Integer> future = executor.submit(new Callable<Integer>() Future<Integer> future = executor.submit(new Callable<Integer>()
{ {
/* ------------------------------------------------------------ */
public Integer call() throws Exception public Integer call() throws Exception
{ {
// Method getStatus() reads synchronized state // Method getStatus() reads synchronized state

View File

@ -16,7 +16,7 @@ package org.eclipse.jetty.client;
public class AsyncSslHttpExchangeTest extends SslHttpExchangeTest public class AsyncSslHttpExchangeTest extends SslHttpExchangeTest
{ {
@Override @Override
protected void setUp() throws Exception public void setUp() throws Exception
{ {
_scheme="https://"; _scheme="https://";
startServer(); startServer();
@ -28,5 +28,4 @@ public class AsyncSslHttpExchangeTest extends SslHttpExchangeTest
_httpClient.setMaxConnectionsPerAddress(2); _httpClient.setMaxConnectionsPerAddress(2);
_httpClient.start(); _httpClient.start();
} }
} }

View File

@ -13,11 +13,16 @@
package org.eclipse.jetty.client; package org.eclipse.jetty.client;
import org.junit.Before;
/* ------------------------------------------------------------ */
public class AsyncSslSecurityListenerTest extends SslSecurityListenerTest public class AsyncSslSecurityListenerTest extends SslSecurityListenerTest
{ {
/* ------------------------------------------------------------ */
@Before
@Override @Override
protected void setUp() throws Exception public void setUp() throws Exception
{ {
_type = HttpClient.CONNECTOR_SELECT_CHANNEL; _type = HttpClient.CONNECTOR_SELECT_CHANNEL;
super.setUp(); super.setUp();

View File

@ -14,7 +14,11 @@
package org.eclipse.jetty.client; package org.eclipse.jetty.client;
import org.junit.After;
import org.junit.Before;
/* ------------------------------------------------------------ */
/** /**
* @version $Revision$ $Date$ * @version $Revision$ $Date$
*/ */
@ -22,8 +26,10 @@ public class BlockingHttpExchangeCancelTest extends AbstractHttpExchangeCancelTe
{ {
private HttpClient httpClient; private HttpClient httpClient;
/* ------------------------------------------------------------ */
@Before
@Override @Override
protected void setUp() throws Exception public void setUp() throws Exception
{ {
super.setUp(); super.setUp();
httpClient = new HttpClient(); httpClient = new HttpClient();
@ -31,13 +37,16 @@ public class BlockingHttpExchangeCancelTest extends AbstractHttpExchangeCancelTe
httpClient.start(); httpClient.start();
} }
/* ------------------------------------------------------------ */
@After
@Override @Override
protected void tearDown() throws Exception public void tearDown() throws Exception
{ {
httpClient.stop(); httpClient.stop();
super.tearDown(); super.tearDown();
} }
/* ------------------------------------------------------------ */
@Override @Override
protected HttpClient getHttpClient() protected HttpClient getHttpClient()
{ {

View File

@ -1,5 +1,7 @@
package org.eclipse.jetty.client; package org.eclipse.jetty.client;
import static org.junit.Assert.assertEquals;
import java.io.IOException; import java.io.IOException;
import java.util.Enumeration; import java.util.Enumeration;
@ -7,26 +9,27 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import junit.framework.TestCase;
import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector; import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class CachedHeadersIsolationTest extends TestCase /* ------------------------------------------------------------ */
public class CachedHeadersIsolationTest
{ {
Server server; Server server;
HttpClient client; HttpClient client;
int port; int port;
@Override @Before
protected void setUp() throws Exception public void setUp() throws Exception
{ {
super.setUp();
server = new Server(); server = new Server();
Connector connector = new SelectChannelConnector(); Connector connector = new SelectChannelConnector();
@ -35,7 +38,7 @@ public class CachedHeadersIsolationTest extends TestCase
server.setHandler(new AbstractHandler() server.setHandler(new AbstractHandler()
{ {
/* ------------------------------------------------------------ */
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException,
ServletException ServletException
{ {
@ -58,14 +61,16 @@ public class CachedHeadersIsolationTest extends TestCase
} }
@Override /* ------------------------------------------------------------ */
protected void tearDown() throws Exception @After
public void tearDown() throws Exception
{ {
super.tearDown();
server.stop(); server.stop();
client.stop(); client.stop();
} }
/* ------------------------------------------------------------ */
@Test
public void testHeaderWhenReadEarly() throws Exception public void testHeaderWhenReadEarly() throws Exception
{ {
@ -88,6 +93,8 @@ public class CachedHeadersIsolationTest extends TestCase
assertEquals("Overwritten buffer","Value",e1.getResponseFields().getStringField("Name")); assertEquals("Overwritten buffer","Value",e1.getResponseFields().getStringField("Name"));
} }
/* ------------------------------------------------------------ */
@Test
public void testHeaderWhenReadLate() throws Exception public void testHeaderWhenReadLate() throws Exception
{ {

View File

@ -13,6 +13,9 @@
package org.eclipse.jetty.client; package org.eclipse.jetty.client;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -27,8 +30,6 @@ import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import junit.framework.TestCase;
import org.eclipse.jetty.client.security.Realm; import org.eclipse.jetty.client.security.Realm;
import org.eclipse.jetty.client.security.SimpleRealmResolver; import org.eclipse.jetty.client.security.SimpleRealmResolver;
import org.eclipse.jetty.http.HttpMethods; import org.eclipse.jetty.http.HttpMethods;
@ -45,9 +46,11 @@ import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.IO;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class ContentExchangeTest public class ContentExchangeTest
extends TestCase
{ {
private static String _content = private static String _content =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis felis nunc. "+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis felis nunc. "+
@ -71,6 +74,8 @@ public class ContentExchangeTest
private String _baseUrl; private String _baseUrl;
private String _requestContent; private String _requestContent;
/* ------------------------------------------------------------ */
@Before
public void setUp() public void setUp()
throws Exception throws Exception
{ {
@ -91,6 +96,8 @@ public class ContentExchangeTest
_baseUrl = _protocol+"://localhost:"+port+ "/"; _baseUrl = _protocol+"://localhost:"+port+ "/";
} }
/* ------------------------------------------------------------ */
@After
public void tearDown() public void tearDown()
throws Exception throws Exception
{ {
@ -101,6 +108,8 @@ public class ContentExchangeTest
} }
} }
/* ------------------------------------------------------------ */
@Test
public void testPut() throws Exception public void testPut() throws Exception
{ {
startClient(_realm); startClient(_realm);
@ -124,6 +133,8 @@ public class ContentExchangeTest
assertEquals(_content,content); assertEquals(_content,content);
} }
/* ------------------------------------------------------------ */
@Test
public void testGet() throws Exception public void testGet() throws Exception
{ {
startClient(_realm); startClient(_realm);
@ -148,6 +159,8 @@ public class ContentExchangeTest
assertEquals(_content,content); assertEquals(_content,content);
} }
/* ------------------------------------------------------------ */
@Test
public void testHead() throws Exception public void testHead() throws Exception
{ {
startClient(_realm); startClient(_realm);
@ -166,6 +179,8 @@ public class ContentExchangeTest
assertEquals(HttpStatus.OK_200,responseStatus); assertEquals(HttpStatus.OK_200,responseStatus);
} }
/* ------------------------------------------------------------ */
@Test
public void testPost() throws Exception public void testPost() throws Exception
{ {
startClient(_realm); startClient(_realm);
@ -186,6 +201,7 @@ public class ContentExchangeTest
assertEquals(_content,_requestContent); assertEquals(_content,_requestContent);
} }
/* ------------------------------------------------------------ */
protected void configureServer(Server server) protected void configureServer(Server server)
throws Exception throws Exception
{ {
@ -209,6 +225,7 @@ public class ContentExchangeTest
} }
/* ------------------------------------------------------------ */
protected void startClient(Realm realm) protected void startClient(Realm realm)
throws Exception throws Exception
{ {
@ -221,12 +238,14 @@ public class ContentExchangeTest
_client.start(); _client.start();
} }
/* ------------------------------------------------------------ */
protected void configureClient(HttpClient client) protected void configureClient(HttpClient client)
throws Exception throws Exception
{ {
client.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL); client.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
} }
/* ------------------------------------------------------------ */
protected void stopClient() protected void stopClient()
throws Exception throws Exception
{ {
@ -237,41 +256,49 @@ public class ContentExchangeTest
} }
} }
/* ------------------------------------------------------------ */
protected String getBasePath() protected String getBasePath()
{ {
return _docRoot.getAbsolutePath(); return _docRoot.getAbsolutePath();
} }
/* ------------------------------------------------------------ */
protected String getBaseUrl() protected String getBaseUrl()
{ {
return _baseUrl; return _baseUrl;
} }
/* ------------------------------------------------------------ */
protected HttpClient getClient() protected HttpClient getClient()
{ {
return _client; return _client;
} }
/* ------------------------------------------------------------ */
protected Realm getRealm() protected Realm getRealm()
{ {
return _realm; return _realm;
} }
/* ------------------------------------------------------------ */
protected String getContent() protected String getContent()
{ {
return _content; return _content;
} }
/* ------------------------------------------------------------ */
protected void setProtocol(String protocol) protected void setProtocol(String protocol)
{ {
_protocol = protocol; _protocol = protocol;
} }
/* ------------------------------------------------------------ */
protected void setRealm(Realm realm) protected void setRealm(Realm realm)
{ {
_realm = realm; _realm = realm;
} }
/* ------------------------------------------------------------ */
public static void copyStream(InputStream in, OutputStream out) public static void copyStream(InputStream in, OutputStream out)
{ {
try try
@ -293,13 +320,16 @@ public class ContentExchangeTest
} }
} }
/* ------------------------------------------------------------ */
protected class TestHandler extends AbstractHandler { protected class TestHandler extends AbstractHandler {
private final String resourcePath; private final String resourcePath;
/* ------------------------------------------------------------ */
public TestHandler(String repositoryPath) { public TestHandler(String repositoryPath) {
this.resourcePath = repositoryPath; this.resourcePath = repositoryPath;
} }
/* ------------------------------------------------------------ */
public void handle(String target, Request baseRequest, public void handle(String target, Request baseRequest,
HttpServletRequest request, HttpServletResponse response) HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException throws IOException, ServletException

View File

@ -13,6 +13,8 @@
package org.eclipse.jetty.client; package org.eclipse.jetty.client;
import static org.junit.Assert.assertEquals;
import java.io.IOException; import java.io.IOException;
import javax.servlet.ServletException; import javax.servlet.ServletException;
@ -31,94 +33,126 @@ import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.servlet.DefaultServlet; import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlet.ServletHolder;
import org.junit.Test;
/* ------------------------------------------------------------ */
public class ErrorStatusTest public class ErrorStatusTest
extends ContentExchangeTest extends ContentExchangeTest
{ {
/* ------------------------------------------------------------ */
@Test
public void testPutBadRequest() public void testPutBadRequest()
throws Exception throws Exception
{ {
doPutFail(HttpStatus.BAD_REQUEST_400); doPutFail(HttpStatus.BAD_REQUEST_400);
} }
/* ------------------------------------------------------------ */
@Test
public void testPutUnauthorized() public void testPutUnauthorized()
throws Exception throws Exception
{ {
doPutFail(HttpStatus.UNAUTHORIZED_401); doPutFail(HttpStatus.UNAUTHORIZED_401);
} }
/* ------------------------------------------------------------ */
@Test
public void testPutForbidden() public void testPutForbidden()
throws Exception throws Exception
{ {
doPutFail(HttpStatus.FORBIDDEN_403); doPutFail(HttpStatus.FORBIDDEN_403);
} }
/* ------------------------------------------------------------ */
@Test
public void testPutNotFound() public void testPutNotFound()
throws Exception throws Exception
{ {
doPutFail(HttpStatus.NOT_FOUND_404); doPutFail(HttpStatus.NOT_FOUND_404);
} }
/* ------------------------------------------------------------ */
@Test
public void testPutServerError() public void testPutServerError()
throws Exception throws Exception
{ {
doPutFail(HttpStatus.INTERNAL_SERVER_ERROR_500); doPutFail(HttpStatus.INTERNAL_SERVER_ERROR_500);
} }
/* ------------------------------------------------------------ */
@Test
public void testGetBadRequest() public void testGetBadRequest()
throws Exception throws Exception
{ {
doGetFail(HttpStatus.BAD_REQUEST_400); doGetFail(HttpStatus.BAD_REQUEST_400);
} }
/* ------------------------------------------------------------ */
@Test
public void testGetUnauthorized() public void testGetUnauthorized()
throws Exception throws Exception
{ {
doGetFail(HttpStatus.UNAUTHORIZED_401); doGetFail(HttpStatus.UNAUTHORIZED_401);
} }
/* ------------------------------------------------------------ */
@Test
public void testGetNotFound() public void testGetNotFound()
throws Exception throws Exception
{ {
doGetFail(HttpStatus.NOT_FOUND_404); doGetFail(HttpStatus.NOT_FOUND_404);
} }
/* ------------------------------------------------------------ */
@Test
public void testGetServerError() public void testGetServerError()
throws Exception throws Exception
{ {
doGetFail(HttpStatus.INTERNAL_SERVER_ERROR_500); doGetFail(HttpStatus.INTERNAL_SERVER_ERROR_500);
} }
/* ------------------------------------------------------------ */
@Test
public void testPostBadRequest() public void testPostBadRequest()
throws Exception throws Exception
{ {
doPostFail(HttpStatus.BAD_REQUEST_400); doPostFail(HttpStatus.BAD_REQUEST_400);
} }
/* ------------------------------------------------------------ */
@Test
public void testPostUnauthorized() public void testPostUnauthorized()
throws Exception throws Exception
{ {
doPostFail(HttpStatus.UNAUTHORIZED_401); doPostFail(HttpStatus.UNAUTHORIZED_401);
} }
/* ------------------------------------------------------------ */
@Test
public void testPostForbidden() public void testPostForbidden()
throws Exception throws Exception
{ {
doPostFail(HttpStatus.FORBIDDEN_403); doPostFail(HttpStatus.FORBIDDEN_403);
} }
/* ------------------------------------------------------------ */
@Test
public void testPostNotFound() public void testPostNotFound()
throws Exception throws Exception
{ {
doPostFail(HttpStatus.NOT_FOUND_404); doPostFail(HttpStatus.NOT_FOUND_404);
} }
/* ------------------------------------------------------------ */
@Test
public void testPostServerError() public void testPostServerError()
throws Exception throws Exception
{ {
doPostFail(HttpStatus.INTERNAL_SERVER_ERROR_500); doPostFail(HttpStatus.INTERNAL_SERVER_ERROR_500);
} }
/* ------------------------------------------------------------ */
protected void doPutFail(int status) protected void doPutFail(int status)
throws Exception throws Exception
{ {
@ -140,6 +174,7 @@ public class ErrorStatusTest
assertEquals(status, responseStatus); assertEquals(status, responseStatus);
} }
/* ------------------------------------------------------------ */
protected void doGetFail(int status) protected void doGetFail(int status)
throws Exception throws Exception
{ {
@ -164,6 +199,7 @@ public class ErrorStatusTest
assertEquals(status, responseStatus); assertEquals(status, responseStatus);
} }
/* ------------------------------------------------------------ */
protected void doPostFail(int status) protected void doPostFail(int status)
throws Exception throws Exception
{ {
@ -185,6 +221,7 @@ public class ErrorStatusTest
assertEquals(status, responseStatus); assertEquals(status, responseStatus);
} }
/* ------------------------------------------------------------ */
protected void configureServer(Server server) protected void configureServer(Server server)
throws Exception throws Exception
{ {
@ -208,7 +245,9 @@ public class ErrorStatusTest
server.setHandler( handlers ); server.setHandler( handlers );
} }
/* ------------------------------------------------------------ */
protected static class StatusHandler extends AbstractHandler { protected static class StatusHandler extends AbstractHandler {
/* ------------------------------------------------------------ */
public void handle(String target, Request baseRequest, public void handle(String target, Request baseRequest,
HttpServletRequest request, HttpServletResponse response) HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException throws IOException, ServletException

View File

@ -20,7 +20,7 @@ import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
public class ExternalKeyStoreAsyncSslHttpExchangeTest extends SslHttpExchangeTest public class ExternalKeyStoreAsyncSslHttpExchangeTest extends SslHttpExchangeTest
{ {
@Override @Override
protected void setUp() throws Exception public void setUp() throws Exception
{ {
_scheme = "https://"; _scheme = "https://";
startServer(); startServer();

View File

@ -13,6 +13,11 @@
package org.eclipse.jetty.client; package org.eclipse.jetty.client;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -26,8 +31,6 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import junit.framework.TestCase;
import org.eclipse.jetty.client.security.ProxyAuthorization; import org.eclipse.jetty.client.security.ProxyAuthorization;
import org.eclipse.jetty.http.HttpHeaders; import org.eclipse.jetty.http.HttpHeaders;
import org.eclipse.jetty.http.HttpMethods; import org.eclipse.jetty.http.HttpMethods;
@ -44,11 +47,15 @@ import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.toolchain.test.Stress; import org.eclipse.jetty.toolchain.test.Stress;
import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/* ------------------------------------------------------------ */
/** /**
* Functional testing for HttpExchange. * Functional testing for HttpExchange.
*/ */
public class HttpExchangeTest extends TestCase public class HttpExchangeTest
{ {
protected int _maxConnectionsPerAddress = 2; protected int _maxConnectionsPerAddress = 2;
protected String _scheme = "http://"; protected String _scheme = "http://";
@ -58,8 +65,9 @@ public class HttpExchangeTest extends TestCase
protected Connector _connector; protected Connector _connector;
protected AtomicInteger _count = new AtomicInteger(); protected AtomicInteger _count = new AtomicInteger();
@Override /* ------------------------------------------------------------ */
protected void setUp() throws Exception @Before
public void setUp() throws Exception
{ {
startServer(); startServer();
_httpClient=new HttpClient(); _httpClient=new HttpClient();
@ -71,20 +79,25 @@ public class HttpExchangeTest extends TestCase
_httpClient.start(); _httpClient.start();
} }
@Override /* ------------------------------------------------------------ */
protected void tearDown() throws Exception @After
public void tearDown() throws Exception
{ {
_httpClient.stop(); _httpClient.stop();
Thread.sleep(500); Thread.sleep(500);
stopServer(); stopServer();
} }
/* ------------------------------------------------------------ */
@Test
public void testResetNewExchange() throws Exception public void testResetNewExchange() throws Exception
{ {
HttpExchange exchange = new HttpExchange(); HttpExchange exchange = new HttpExchange();
exchange.reset(); exchange.reset();
} }
/* ------------------------------------------------------------ */
@Test
public void testPerf() throws Exception public void testPerf() throws Exception
{ {
sender(1,false); sender(1,false);
@ -104,6 +117,7 @@ public class HttpExchangeTest extends TestCase
} }
} }
/* ------------------------------------------------------------ */
/** /**
* Test sending data through the exchange. * Test sending data through the exchange.
* *
@ -124,12 +138,15 @@ public class HttpExchangeTest extends TestCase
{ {
String result="pending"; String result="pending";
int len=0; int len=0;
/* ------------------------------------------------------------ */
@Override @Override
protected void onRequestCommitted() protected void onRequestCommitted()
{ {
result="committed"; result="committed";
} }
/* ------------------------------------------------------------ */
@Override @Override
protected void onRequestComplete() throws IOException protected void onRequestComplete() throws IOException
{ {
@ -137,16 +154,19 @@ public class HttpExchangeTest extends TestCase
} }
@Override @Override
/* ------------------------------------------------------------ */
protected void onResponseStatus(Buffer version, int status, Buffer reason) protected void onResponseStatus(Buffer version, int status, Buffer reason)
{ {
result="status"; result="status";
} }
/* ------------------------------------------------------------ */
@Override @Override
protected void onResponseHeader(Buffer name, Buffer value) protected void onResponseHeader(Buffer name, Buffer value)
{ {
} }
/* ------------------------------------------------------------ */
@Override @Override
protected void onResponseHeaderComplete() throws IOException protected void onResponseHeaderComplete() throws IOException
{ {
@ -154,12 +174,14 @@ public class HttpExchangeTest extends TestCase
super.onResponseHeaderComplete(); super.onResponseHeaderComplete();
} }
/* ------------------------------------------------------------ */
@Override @Override
protected void onResponseContent(Buffer content) protected void onResponseContent(Buffer content)
{ {
len+=content.length(); len+=content.length();
} }
/* ------------------------------------------------------------ */
@Override @Override
protected void onResponseComplete() protected void onResponseComplete()
{ {
@ -173,6 +195,7 @@ public class HttpExchangeTest extends TestCase
complete.countDown(); complete.countDown();
} }
/* ------------------------------------------------------------ */
@Override @Override
protected void onConnectionFailed(Throwable ex) protected void onConnectionFailed(Throwable ex)
{ {
@ -182,6 +205,7 @@ public class HttpExchangeTest extends TestCase
super.onConnectionFailed(ex); super.onConnectionFailed(ex);
} }
/* ------------------------------------------------------------ */
@Override @Override
protected void onException(Throwable ex) protected void onException(Throwable ex)
{ {
@ -191,6 +215,7 @@ public class HttpExchangeTest extends TestCase
super.onException(ex); super.onException(ex);
} }
/* ------------------------------------------------------------ */
@Override @Override
protected void onExpire() protected void onExpire()
{ {
@ -200,6 +225,7 @@ public class HttpExchangeTest extends TestCase
super.onExpire(); super.onExpire();
} }
/* ------------------------------------------------------------ */
@Override @Override
public String toString() public String toString()
{ {
@ -228,6 +254,8 @@ public class HttpExchangeTest extends TestCase
assertEquals("nb="+nb+" close="+close,0,latch.getCount()); assertEquals("nb="+nb+" close="+close,0,latch.getCount());
} }
/* ------------------------------------------------------------ */
@Test
public void testPostWithContentExchange() throws Exception public void testPostWithContentExchange() throws Exception
{ {
for (int i=0;i<20;i++) for (int i=0;i<20;i++)
@ -246,6 +274,8 @@ public class HttpExchangeTest extends TestCase
} }
} }
/* ------------------------------------------------------------ */
@Test
public void testGetWithContentExchange() throws Exception public void testGetWithContentExchange() throws Exception
{ {
for (int i=0;i<10;i++) for (int i=0;i<10;i++)
@ -264,6 +294,8 @@ public class HttpExchangeTest extends TestCase
} }
} }
/* ------------------------------------------------------------ */
@Test
public void testLocalAddressAvailabilityWithContentExchange() throws Exception public void testLocalAddressAvailabilityWithContentExchange() throws Exception
{ {
for (int i=0;i<10;i++) for (int i=0;i<10;i++)
@ -287,6 +319,8 @@ public class HttpExchangeTest extends TestCase
} }
} }
/* ------------------------------------------------------------ */
@Test
public void testShutdownWithExchange() throws Exception public void testShutdownWithExchange() throws Exception
{ {
final AtomicReference<Throwable> throwable=new AtomicReference<Throwable>(); final AtomicReference<Throwable> throwable=new AtomicReference<Throwable>();
@ -304,6 +338,10 @@ public class HttpExchangeTest extends TestCase
throwable.set(x); throwable.set(x);
} }
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.client.HttpExchange#onConnectionFailed(java.lang.Throwable)
*/
@Override @Override
protected void onConnectionFailed(Throwable x) protected void onConnectionFailed(Throwable x)
{ {
@ -330,6 +368,8 @@ public class HttpExchangeTest extends TestCase
assertEquals(HttpExchange.STATUS_EXCEPTED, status); assertEquals(HttpExchange.STATUS_EXCEPTED, status);
} }
/* ------------------------------------------------------------ */
@Test
public void testBigPostWithContentExchange() throws Exception public void testBigPostWithContentExchange() throws Exception
{ {
int size =32; int size =32;
@ -370,6 +410,8 @@ public class HttpExchangeTest extends TestCase
assertEquals(HttpExchange.STATUS_COMPLETED, status); assertEquals(HttpExchange.STATUS_COMPLETED, status);
} }
/* ------------------------------------------------------------ */
@Test
public void testSlowPost() throws Exception public void testSlowPost() throws Exception
{ {
ContentExchange httpExchange=new ContentExchange() ContentExchange httpExchange=new ContentExchange()
@ -431,6 +473,8 @@ public class HttpExchangeTest extends TestCase
assertEquals(data,result); assertEquals(data,result);
} }
/* ------------------------------------------------------------ */
@Test
public void testProxy() throws Exception public void testProxy() throws Exception
{ {
if (_scheme.equals("https://")) if (_scheme.equals("https://"))
@ -460,6 +504,8 @@ public class HttpExchangeTest extends TestCase
} }
/* ------------------------------------------------------------ */
@Test
public void testReserveConnections () throws Exception public void testReserveConnections () throws Exception
{ {
final HttpDestination destination = _httpClient.getDestination (new Address("localhost", _port), _scheme.equalsIgnoreCase("https://")); final HttpDestination destination = _httpClient.getDestination (new Address("localhost", _port), _scheme.equalsIgnoreCase("https://"));
@ -485,10 +531,10 @@ public class HttpExchangeTest extends TestCase
//reserving one should now work //reserving one should now work
c = destination.reserveConnection(500); c = destination.reserveConnection(500);
assertNotNull(c); assertNotNull(c);
} }
public static void copyStrxeam(InputStream in, OutputStream out)
/* ------------------------------------------------------------ */
public static void copyStream(InputStream in, OutputStream out)
{ {
try try
{ {
@ -509,6 +555,7 @@ public class HttpExchangeTest extends TestCase
} }
} }
/* ------------------------------------------------------------ */
protected void newServer() throws Exception protected void newServer() throws Exception
{ {
_server=new Server(); _server=new Server();
@ -521,6 +568,7 @@ public class HttpExchangeTest extends TestCase
_server.setConnectors(new Connector[] { _connector }); _server.setConnectors(new Connector[] { _connector });
} }
/* ------------------------------------------------------------ */
protected void startServer() throws Exception protected void startServer() throws Exception
{ {
newServer(); newServer();
@ -587,6 +635,7 @@ public class HttpExchangeTest extends TestCase
_port=_connector.getLocalPort(); _port=_connector.getLocalPort();
} }
/* ------------------------------------------------------------ */
private void stopServer() throws Exception private void stopServer() throws Exception
{ {
_server.stop(); _server.stop();

View File

@ -13,6 +13,8 @@
package org.eclipse.jetty.client; package org.eclipse.jetty.client;
import static org.junit.Assert.assertEquals;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
@ -21,8 +23,6 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import junit.framework.TestCase;
import org.eclipse.jetty.client.security.Realm; import org.eclipse.jetty.client.security.Realm;
import org.eclipse.jetty.client.security.SimpleRealmResolver; import org.eclipse.jetty.client.security.SimpleRealmResolver;
import org.eclipse.jetty.http.HttpMethods; import org.eclipse.jetty.http.HttpMethods;
@ -31,13 +31,13 @@ import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector; import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/**
*/
public class HttpGetRedirectTest public class HttpGetRedirectTest
extends TestCase
{ {
private static String _content = private static String _content =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis felis nunc. "+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis felis nunc. "+
@ -62,6 +62,8 @@ public class HttpGetRedirectTest
private String _requestUrl2; private String _requestUrl2;
private RedirectHandler _handler; private RedirectHandler _handler;
/* ------------------------------------------------------------ */
@Before
public void setUp() public void setUp()
throws Exception throws Exception
{ {
@ -81,6 +83,8 @@ public class HttpGetRedirectTest
_handler._toURL=_protocol+"://localhost:"+connector.getLocalPort()+ "/moved.txt"; _handler._toURL=_protocol+"://localhost:"+connector.getLocalPort()+ "/moved.txt";
} }
/* ------------------------------------------------------------ */
@After
public void tearDown() public void tearDown()
throws Exception throws Exception
{ {
@ -91,6 +95,8 @@ public class HttpGetRedirectTest
} }
} }
/* ------------------------------------------------------------ */
@Test
public void testGet() throws Exception public void testGet() throws Exception
{ {
startClient(_realm); startClient(_realm);
@ -115,6 +121,7 @@ public class HttpGetRedirectTest
stopClient(); stopClient();
} }
/* ------------------------------------------------------------ */
protected void configureServer(Server server) protected void configureServer(Server server)
throws Exception throws Exception
{ {
@ -128,6 +135,7 @@ public class HttpGetRedirectTest
} }
/* ------------------------------------------------------------ */
protected void startClient(Realm realm) protected void startClient(Realm realm)
throws Exception throws Exception
{ {
@ -139,6 +147,7 @@ public class HttpGetRedirectTest
_client.start(); _client.start();
} }
/* ------------------------------------------------------------ */
protected void stopClient() protected void stopClient()
throws Exception throws Exception
{ {
@ -149,22 +158,26 @@ public class HttpGetRedirectTest
} }
} }
/* ------------------------------------------------------------ */
protected String getBasePath() protected String getBasePath()
{ {
return _docRoot.getAbsolutePath(); return _docRoot.getAbsolutePath();
} }
/* ------------------------------------------------------------ */
protected void setProtocol(String protocol) protected void setProtocol(String protocol)
{ {
_protocol = protocol; _protocol = protocol;
} }
/* ------------------------------------------------------------ */
protected void setRealm(Realm realm) protected void setRealm(Realm realm)
{ {
_realm = realm; _realm = realm;
} }
/* ------------------------------------------------------------ */
private static class RedirectHandler private static class RedirectHandler
extends AbstractHandler extends AbstractHandler
{ {
@ -174,6 +187,7 @@ public class HttpGetRedirectTest
private int _redirectCount = 0; private int _redirectCount = 0;
private String _toURL; private String _toURL;
/* ------------------------------------------------------------ */
public RedirectHandler( final int code, final String fromURI, final String toURL, final int maxRedirects ) public RedirectHandler( final int code, final String fromURI, final String toURL, final int maxRedirects )
{ {
this._code = code; this._code = code;
@ -186,6 +200,7 @@ public class HttpGetRedirectTest
} }
/* ------------------------------------------------------------ */
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException throws IOException, ServletException
{ {

View File

@ -14,6 +14,10 @@
package org.eclipse.jetty.client; package org.eclipse.jetty.client;
import org.junit.After;
import org.junit.Before;
/* ------------------------------------------------------------ */
/** /**
* @version $Revision$ $Date$ * @version $Revision$ $Date$
*/ */
@ -21,8 +25,10 @@ public class NonBlockingHttpExchangeCancelTest extends AbstractHttpExchangeCance
{ {
private HttpClient httpClient; private HttpClient httpClient;
/* ------------------------------------------------------------ */
@Before
@Override @Override
protected void setUp() throws Exception public void setUp() throws Exception
{ {
super.setUp(); super.setUp();
httpClient = new HttpClient(); httpClient = new HttpClient();
@ -30,13 +36,16 @@ public class NonBlockingHttpExchangeCancelTest extends AbstractHttpExchangeCance
httpClient.start(); httpClient.start();
} }
/* ------------------------------------------------------------ */
@After
@Override @Override
protected void tearDown() throws Exception public void tearDown() throws Exception
{ {
httpClient.stop(); httpClient.stop();
super.tearDown(); super.tearDown();
} }
/* ------------------------------------------------------------ */
@Override @Override
protected HttpClient getHttpClient() protected HttpClient getHttpClient()
{ {

View File

@ -34,6 +34,7 @@ import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.junit.Test;
public class SecuredErrorStatusTest public class SecuredErrorStatusTest
extends ErrorStatusTest extends ErrorStatusTest
@ -41,6 +42,8 @@ public class SecuredErrorStatusTest
private Realm _testRealm; private Realm _testRealm;
private Realm _dummyRealm; private Realm _dummyRealm;
/* ------------------------------------------------------------ */
@Test
@Override @Override
public void testPutUnauthorized() public void testPutUnauthorized()
throws Exception throws Exception
@ -52,6 +55,8 @@ public class SecuredErrorStatusTest
setRealm(_testRealm); setRealm(_testRealm);
} }
/* ------------------------------------------------------------ */
@Test
public void testPutWrongPassword() public void testPutWrongPassword()
throws Exception throws Exception
{ {
@ -62,6 +67,8 @@ public class SecuredErrorStatusTest
setRealm(_testRealm); setRealm(_testRealm);
} }
/* ------------------------------------------------------------ */
@Test
@Override @Override
public void testGetUnauthorized() public void testGetUnauthorized()
throws Exception throws Exception
@ -73,6 +80,8 @@ public class SecuredErrorStatusTest
setRealm(_testRealm); setRealm(_testRealm);
} }
/* ------------------------------------------------------------ */
@Test
public void testGetWrongPassword() public void testGetWrongPassword()
throws Exception throws Exception
{ {
@ -83,6 +92,7 @@ public class SecuredErrorStatusTest
setRealm(_testRealm); setRealm(_testRealm);
} }
/* ------------------------------------------------------------ */
@Override @Override
protected void configureServer(Server server) protected void configureServer(Server server)
throws Exception throws Exception
@ -91,16 +101,19 @@ public class SecuredErrorStatusTest
_testRealm = new Realm() _testRealm = new Realm()
{ {
/* ------------------------------------------------------------ */
public String getId() public String getId()
{ {
return "MyRealm"; return "MyRealm";
} }
/* ------------------------------------------------------------ */
public String getPrincipal() public String getPrincipal()
{ {
return "jetty"; return "jetty";
} }
/* ------------------------------------------------------------ */
public String getCredentials() public String getCredentials()
{ {
return "jetty"; return "jetty";
@ -109,16 +122,19 @@ public class SecuredErrorStatusTest
_dummyRealm = new Realm() _dummyRealm = new Realm()
{ {
/* ------------------------------------------------------------ */
public String getId() public String getId()
{ {
return "MyRealm"; return "MyRealm";
} }
/* ------------------------------------------------------------ */
public String getPrincipal() public String getPrincipal()
{ {
return "jetty"; return "jetty";
} }
/* ------------------------------------------------------------ */
public String getCredentials() public String getCredentials()
{ {
return "dummy"; return "dummy";

View File

@ -13,6 +13,9 @@
package org.eclipse.jetty.client; package org.eclipse.jetty.client;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -25,8 +28,6 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import junit.framework.TestCase;
import org.eclipse.jetty.client.security.Realm; import org.eclipse.jetty.client.security.Realm;
import org.eclipse.jetty.client.security.SimpleRealmResolver; import org.eclipse.jetty.client.security.SimpleRealmResolver;
import org.eclipse.jetty.http.HttpMethods; import org.eclipse.jetty.http.HttpMethods;
@ -45,16 +46,16 @@ import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector; import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/* ------------------------------------------------------------ */
/** /**
* Functional testing for HttpExchange. * Functional testing for HttpExchange.
*
*
*
*/ */
public class SecurityListenerTest extends TestCase public class SecurityListenerTest
{ {
private Server _server; private Server _server;
private int _port; private int _port;
private HttpClient _httpClient; private HttpClient _httpClient;
@ -62,8 +63,9 @@ public class SecurityListenerTest extends TestCase
private Realm _jettyRealm; private Realm _jettyRealm;
private static final String APP_CONTEXT = "localhost /"; private static final String APP_CONTEXT = "localhost /";
@Override /* ------------------------------------------------------------ */
protected void setUp() throws Exception @Before
public void setUp() throws Exception
{ {
startServer(); startServer();
_httpClient=new HttpClient(); _httpClient=new HttpClient();
@ -92,13 +94,16 @@ public class SecurityListenerTest extends TestCase
_httpClient.setRealmResolver( new SimpleRealmResolver(_jettyRealm) ); _httpClient.setRealmResolver( new SimpleRealmResolver(_jettyRealm) );
} }
@Override /* ------------------------------------------------------------ */
protected void tearDown() throws Exception @After
public void tearDown() throws Exception
{ {
stopServer(); stopServer();
_httpClient.stop(); _httpClient.stop();
} }
/* ------------------------------------------------------------ */
// @Test
public void xtestPerf() throws Exception public void xtestPerf() throws Exception
{ {
sender(1); sender(1);
@ -112,6 +117,7 @@ public class SecurityListenerTest extends TestCase
sender(10000); sender(10000);
} }
/* ------------------------------------------------------------ */
public void sender(final int nb) throws Exception public void sender(final int nb) throws Exception
{ {
final CountDownLatch latch=new CountDownLatch(nb); final CountDownLatch latch=new CountDownLatch(nb);
@ -204,6 +210,8 @@ public class SecurityListenerTest extends TestCase
// } // }
/* ------------------------------------------------------------ */
@Test
public void testDestinationSecurityCaching() throws Exception public void testDestinationSecurityCaching() throws Exception
{ {
final CyclicBarrier barrier = new CyclicBarrier(2); final CyclicBarrier barrier = new CyclicBarrier(2);
@ -248,6 +256,7 @@ public class SecurityListenerTest extends TestCase
} }
/* ------------------------------------------------------------ */
public static void copyStream(InputStream in, OutputStream out) public static void copyStream(InputStream in, OutputStream out)
{ {
try try
@ -269,6 +278,7 @@ public class SecurityListenerTest extends TestCase
} }
} }
/* ------------------------------------------------------------ */
private void startServer() throws Exception private void startServer() throws Exception
{ {
_server = new Server(); _server = new Server();
@ -332,7 +342,7 @@ public class SecurityListenerTest extends TestCase
_port = connector.getLocalPort(); _port = connector.getLocalPort();
} }
/* ------------------------------------------------------------ */
private void stopServer() throws Exception private void stopServer() throws Exception
{ {
_server.stop(); _server.stop();

View File

@ -21,7 +21,11 @@ import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ssl.SslSocketConnector; import org.eclipse.jetty.server.ssl.SslSocketConnector;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.toolchain.test.OS;
import org.eclipse.jetty.toolchain.test.Stress;
import org.junit.Assume; import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
/** /**
* Functional testing for HttpExchange. * Functional testing for HttpExchange.
@ -31,8 +35,10 @@ import org.junit.Assume;
*/ */
public class SslHttpExchangeTest extends HttpExchangeTest public class SslHttpExchangeTest extends HttpExchangeTest
{ {
/* ------------------------------------------------------------ */
@Before
@Override @Override
protected void setUp() throws Exception public void setUp() throws Exception
{ {
_scheme="https://"; _scheme="https://";
startServer(); startServer();
@ -46,6 +52,7 @@ public class SslHttpExchangeTest extends HttpExchangeTest
_httpClient.start(); _httpClient.start();
} }
/* ------------------------------------------------------------ */
@Override @Override
protected void newServer() protected void newServer()
{ {
@ -67,7 +74,9 @@ public class SslHttpExchangeTest extends HttpExchangeTest
_connector=connector; _connector=connector;
} }
private void IgnoreTestOnBuggyIBM() { /* ------------------------------------------------------------ */
private void IgnoreTestOnBuggyIBM()
{
// Use Junit 4.x to flag test as ignored if encountering IBM JVM // Use Junit 4.x to flag test as ignored if encountering IBM JVM
// Will show up in various junit reports as an ignored test as well. // Will show up in various junit reports as an ignored test as well.
Assume.assumeThat(System.getProperty("java.vendor").toLowerCase(),not(containsString("ibm"))); Assume.assumeThat(System.getProperty("java.vendor").toLowerCase(),not(containsString("ibm")));
@ -77,6 +86,7 @@ public class SslHttpExchangeTest extends HttpExchangeTest
/** /**
* @see org.eclipse.jetty.client.HttpExchangeTest#testGetWithContentExchange() * @see org.eclipse.jetty.client.HttpExchangeTest#testGetWithContentExchange()
*/ */
@Test
@Override @Override
public void testGetWithContentExchange() throws Exception public void testGetWithContentExchange() throws Exception
{ {
@ -89,9 +99,13 @@ public class SslHttpExchangeTest extends HttpExchangeTest
/** /**
* @see org.eclipse.jetty.client.HttpExchangeTest#testPerf() * @see org.eclipse.jetty.client.HttpExchangeTest#testPerf()
*/ */
@Test
@Override @Override
public void testPerf() throws Exception public void testPerf() throws Exception
{ {
// TODO needs to be further investigated
Assume.assumeTrue(!OS.IS_OSX || Stress.isEnabled());
// TODO Resolve problems on IBM JVM https://bugs.eclipse.org/bugs/show_bug.cgi?id=304532 // TODO Resolve problems on IBM JVM https://bugs.eclipse.org/bugs/show_bug.cgi?id=304532
IgnoreTestOnBuggyIBM(); IgnoreTestOnBuggyIBM();
super.testPerf(); super.testPerf();
@ -101,6 +115,7 @@ public class SslHttpExchangeTest extends HttpExchangeTest
/** /**
* @see org.eclipse.jetty.client.HttpExchangeTest#testPostWithContentExchange() * @see org.eclipse.jetty.client.HttpExchangeTest#testPostWithContentExchange()
*/ */
@Test
@Override @Override
public void testPostWithContentExchange() throws Exception public void testPostWithContentExchange() throws Exception
{ {
@ -113,6 +128,7 @@ public class SslHttpExchangeTest extends HttpExchangeTest
/** /**
* @see org.eclipse.jetty.client.HttpExchangeTest#testReserveConnections() * @see org.eclipse.jetty.client.HttpExchangeTest#testReserveConnections()
*/ */
@Test
@Override @Override
public void testReserveConnections() throws Exception public void testReserveConnections() throws Exception
{ {

View File

@ -34,13 +34,17 @@ import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.junit.Test;
/* ------------------------------------------------------------ */
public class SslSecuredErrorStatusTest public class SslSecuredErrorStatusTest
extends ErrorStatusTest extends ErrorStatusTest
{ {
private Realm _testRealm; private Realm _testRealm;
private Realm _dummyRealm; private Realm _dummyRealm;
/* ------------------------------------------------------------ */
@Test
public void testPutUnauthorized() public void testPutUnauthorized()
throws Exception throws Exception
{ {
@ -50,7 +54,9 @@ public class SslSecuredErrorStatusTest
setRealm(_testRealm); setRealm(_testRealm);
} }
/* ------------------------------------------------------------ */
@Test
public void testPutWrongPassword() public void testPutWrongPassword()
throws Exception throws Exception
{ {
@ -61,6 +67,8 @@ public class SslSecuredErrorStatusTest
setRealm(_testRealm); setRealm(_testRealm);
} }
/* ------------------------------------------------------------ */
@Test
public void testGetUnauthorized() public void testGetUnauthorized()
throws Exception throws Exception
{ {
@ -71,6 +79,8 @@ public class SslSecuredErrorStatusTest
setRealm(_testRealm); setRealm(_testRealm);
} }
/* ------------------------------------------------------------ */
@Test
public void testGetWrongPassword() public void testGetWrongPassword()
throws Exception throws Exception
{ {
@ -81,6 +91,7 @@ public class SslSecuredErrorStatusTest
setRealm(_testRealm); setRealm(_testRealm);
} }
/* ------------------------------------------------------------ */
protected void configureServer(Server server) protected void configureServer(Server server)
throws Exception throws Exception
{ {
@ -88,16 +99,19 @@ public class SslSecuredErrorStatusTest
_testRealm = new Realm() _testRealm = new Realm()
{ {
/* ------------------------------------------------------------ */
public String getId() public String getId()
{ {
return "MyRealm"; return "MyRealm";
} }
/* ------------------------------------------------------------ */
public String getPrincipal() public String getPrincipal()
{ {
return "jetty"; return "jetty";
} }
/* ------------------------------------------------------------ */
public String getCredentials() public String getCredentials()
{ {
return "jetty"; return "jetty";
@ -106,16 +120,19 @@ public class SslSecuredErrorStatusTest
_dummyRealm = new Realm() _dummyRealm = new Realm()
{ {
/* ------------------------------------------------------------ */
public String getId() public String getId()
{ {
return "MyRealm"; return "MyRealm";
} }
/* ------------------------------------------------------------ */
public String getPrincipal() public String getPrincipal()
{ {
return "jetty"; return "jetty";
} }
/* ------------------------------------------------------------ */
public String getCredentials() public String getCredentials()
{ {
return "dummy"; return "dummy";

View File

@ -13,6 +13,9 @@
package org.eclipse.jetty.client; package org.eclipse.jetty.client;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -28,8 +31,6 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import junit.framework.TestCase;
import org.eclipse.jetty.client.security.HashRealmResolver; import org.eclipse.jetty.client.security.HashRealmResolver;
import org.eclipse.jetty.client.security.Realm; import org.eclipse.jetty.client.security.Realm;
import org.eclipse.jetty.http.HttpMethods; import org.eclipse.jetty.http.HttpMethods;
@ -49,11 +50,15 @@ import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.ssl.SslSocketConnector; import org.eclipse.jetty.server.ssl.SslSocketConnector;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/* ------------------------------------------------------------ */
/** /**
* Functional testing. * Functional testing.
*/ */
public class SslSecurityListenerTest extends TestCase public class SslSecurityListenerTest
{ {
protected Server _server; protected Server _server;
protected int _port; protected int _port;
@ -62,8 +67,9 @@ public class SslSecurityListenerTest extends TestCase
protected int _type = HttpClient.CONNECTOR_SOCKET; protected int _type = HttpClient.CONNECTOR_SOCKET;
private static final String APP_CONTEXT = "localhost /"; private static final String APP_CONTEXT = "localhost /";
@Override /* ------------------------------------------------------------ */
protected void setUp() throws Exception @Before
public void setUp() throws Exception
{ {
startServer(); startServer();
_httpClient = new HttpClient(); _httpClient = new HttpClient();
@ -73,16 +79,19 @@ public class SslSecurityListenerTest extends TestCase
_jettyRealm = new Realm() _jettyRealm = new Realm()
{ {
/* ------------------------------------------------------------ */
public String getId() public String getId()
{ {
return "MyRealm"; return "MyRealm";
} }
/* ------------------------------------------------------------ */
public String getPrincipal() public String getPrincipal()
{ {
return "jetty"; return "jetty";
} }
/* ------------------------------------------------------------ */
public String getCredentials() public String getCredentials()
{ {
return "jetty"; return "jetty";
@ -94,8 +103,9 @@ public class SslSecurityListenerTest extends TestCase
_httpClient.setRealmResolver(resolver); _httpClient.setRealmResolver(resolver);
} }
@Override /* ------------------------------------------------------------ */
protected void tearDown() throws Exception @After
public void tearDown() throws Exception
{ {
Thread.sleep(1000); Thread.sleep(1000);
_httpClient.stop(); _httpClient.stop();
@ -103,6 +113,8 @@ public class SslSecurityListenerTest extends TestCase
stopServer(); stopServer();
} }
/* ------------------------------------------------------------ */
@Test
public void testSslGet() throws Exception public void testSslGet() throws Exception
{ {
// TODO Resolve problems on IBM JVM https://bugs.eclipse.org/bugs/show_bug.cgi?id=304532 // TODO Resolve problems on IBM JVM https://bugs.eclipse.org/bugs/show_bug.cgi?id=304532
@ -117,6 +129,7 @@ public class SslSecurityListenerTest extends TestCase
ContentExchange httpExchange = new ContentExchange(true) ContentExchange httpExchange = new ContentExchange(true)
{ {
/* ------------------------------------------------------------ */
@Override @Override
protected void onResponseComplete() throws IOException protected void onResponseComplete() throws IOException
{ {
@ -138,6 +151,7 @@ public class SslSecurityListenerTest extends TestCase
} }
/* ------------------------------------------------------------ */
protected void startServer() throws Exception protected void startServer() throws Exception
{ {
_server = new Server(); _server = new Server();
@ -180,7 +194,7 @@ public class SslSecurityListenerTest extends TestCase
Handler testHandler = new AbstractHandler() Handler testHandler = new AbstractHandler()
{ {
/* ------------------------------------------------------------ */
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{ {
// System.err.println("passed authentication!\n"+((Request)request).getConnection().getRequestFields()); // System.err.println("passed authentication!\n"+((Request)request).getConnection().getRequestFields());
@ -216,6 +230,7 @@ public class SslSecurityListenerTest extends TestCase
_port = connector.getLocalPort(); _port = connector.getLocalPort();
} }
/* ------------------------------------------------------------ */
public static void copyStream(InputStream in, OutputStream out) public static void copyStream(InputStream in, OutputStream out)
{ {
try try
@ -237,6 +252,7 @@ public class SslSecurityListenerTest extends TestCase
} }
} }
/* ------------------------------------------------------------ */
private void stopServer() throws Exception private void stopServer() throws Exception
{ {
_server.stop(); _server.stop();

View File

@ -13,6 +13,8 @@
package org.eclipse.jetty.client; package org.eclipse.jetty.client;
import static org.junit.Assert.assertEquals;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
@ -21,8 +23,6 @@ import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import junit.framework.TestCase;
import org.eclipse.jetty.http.HttpMethods; import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.io.Buffer; import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.Connection;
@ -34,11 +34,15 @@ import org.eclipse.jetty.websocket.WebSocket;
import org.eclipse.jetty.websocket.WebSocketBuffers; import org.eclipse.jetty.websocket.WebSocketBuffers;
import org.eclipse.jetty.websocket.WebSocketConnectionD00; import org.eclipse.jetty.websocket.WebSocketConnectionD00;
import org.eclipse.jetty.websocket.WebSocketHandler; import org.eclipse.jetty.websocket.WebSocketHandler;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/* ------------------------------------------------------------ */
/** /**
* Functional testing for HttpExchange. * Functional testing for HttpExchange.
*/ */
public class WebSocketUpgradeTest extends TestCase public class WebSocketUpgradeTest
{ {
protected Server _server; protected Server _server;
protected int _port; protected int _port;
@ -49,8 +53,9 @@ public class WebSocketUpgradeTest extends TestCase
protected TestWebSocket _websocket; protected TestWebSocket _websocket;
final BlockingQueue<Object> _results = new ArrayBlockingQueue<Object>(100); final BlockingQueue<Object> _results = new ArrayBlockingQueue<Object>(100);
@Override /* ------------------------------------------------------------ */
protected void setUp() throws Exception @Before
public void setUp() throws Exception
{ {
startServer(); startServer();
_httpClient=new HttpClient(); _httpClient=new HttpClient();
@ -62,25 +67,29 @@ public class WebSocketUpgradeTest extends TestCase
_httpClient.start(); _httpClient.start();
} }
@Override /* ------------------------------------------------------------ */
protected void tearDown() throws Exception @After
public void tearDown() throws Exception
{ {
_httpClient.stop(); _httpClient.stop();
Thread.sleep(500); Thread.sleep(500);
stopServer(); stopServer();
} }
/* ------------------------------------------------------------ */
@Test
public void testGetWithContentExchange() throws Exception public void testGetWithContentExchange() throws Exception
{ {
final WebSocket clientWS = new WebSocket.OnTextMessage() final WebSocket clientWS = new WebSocket.OnTextMessage()
{ {
Connection _connection; Connection _connection;
/* ------------------------------------------------------------ */
public void onClose(int closeCode, String message) public void onClose(int closeCode, String message)
{ {
} }
/* ------------------------------------------------------------ */
public void onOpen(Connection connection) public void onOpen(Connection connection)
{ {
_connection=connection; _connection=connection;
@ -88,6 +97,7 @@ public class WebSocketUpgradeTest extends TestCase
_results.add(_connection); _results.add(_connection);
} }
/* ------------------------------------------------------------ */
public void onMessage(String data) public void onMessage(String data)
{ {
_results.add("clientWS.onMessage"); _results.add("clientWS.onMessage");
@ -126,6 +136,7 @@ public class WebSocketUpgradeTest extends TestCase
return connection; return connection;
} }
/* ------------------------------------------------------------ */
private void waitFor(int results) private void waitFor(int results)
{ {
try try
@ -176,6 +187,7 @@ public class WebSocketUpgradeTest extends TestCase
} }
/* ------------------------------------------------------------ */
protected void newServer() throws Exception protected void newServer() throws Exception
{ {
_server=new Server(); _server=new Server();
@ -186,11 +198,13 @@ public class WebSocketUpgradeTest extends TestCase
_server.setConnectors(new Connector[] { _connector }); _server.setConnectors(new Connector[] { _connector });
} }
/* ------------------------------------------------------------ */
protected void startServer() throws Exception protected void startServer() throws Exception
{ {
newServer(); newServer();
_handler= new WebSocketHandler() _handler= new WebSocketHandler()
{ {
/* ------------------------------------------------------------ */
public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol) public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol)
{ {
_websocket = new TestWebSocket(); _websocket = new TestWebSocket();
@ -203,18 +217,19 @@ public class WebSocketUpgradeTest extends TestCase
_port=_connector.getLocalPort(); _port=_connector.getLocalPort();
} }
/* ------------------------------------------------------------ */
private void stopServer() throws Exception private void stopServer() throws Exception
{ {
_server.stop(); _server.stop();
_server.join(); _server.join();
} }
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
class TestWebSocket implements WebSocket.OnTextMessage class TestWebSocket implements WebSocket.OnTextMessage
{ {
Connection _connection; Connection _connection;
/* ------------------------------------------------------------ */
public void onOpen(Connection connection) public void onOpen(Connection connection)
{ {
_connection=connection; _connection=connection;
@ -223,18 +238,21 @@ public class WebSocketUpgradeTest extends TestCase
_results.add(this); _results.add(this);
} }
/* ------------------------------------------------------------ */
public void onMessage(final String data) public void onMessage(final String data)
{ {
_results.add("serverWS.onMessage"); _results.add("serverWS.onMessage");
_results.add(data); _results.add(data);
} }
/* ------------------------------------------------------------ */
public void onClose(int code, String message) public void onClose(int code, String message)
{ {
_results.add("onDisconnect"); _results.add("onDisconnect");
_webSockets.remove(this); _webSockets.remove(this);
} }
/* ------------------------------------------------------------ */
public void sendMessage(String msg) throws IOException public void sendMessage(String msg) throws IOException
{ {
_connection.sendMessage(msg); _connection.sendMessage(msg);

View File

@ -83,7 +83,7 @@ public class GlobalWebappConfigBinding implements AppLifeCycle.Binding
Log.warn("Binding: global context binding is enabled but no jetty-web.xml file has been registered"); Log.warn("Binding: global context binding is enabled but no jetty-web.xml file has been registered");
} }
Resource globalContextSettings = new FileResource(new URL(_jettyXml)); Resource globalContextSettings = Resource.newResource(_jettyXml);
if (globalContextSettings.exists()) if (globalContextSettings.exists())
{ {

View File

@ -18,11 +18,13 @@ package org.eclipse.jetty.deploy.bindings;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.*;
import java.io.File; import java.io.File;
import java.util.List;
import org.eclipse.jetty.deploy.providers.ScanningAppProvider; import org.eclipse.jetty.deploy.providers.ScanningAppProvider;
import org.eclipse.jetty.deploy.test.XmlConfiguredJetty; import org.eclipse.jetty.deploy.test.XmlConfiguredJetty;
import org.eclipse.jetty.toolchain.test.IO; import org.eclipse.jetty.toolchain.test.IO;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.toolchain.test.PathAssert;
import org.eclipse.jetty.toolchain.test.TestingDir; import org.eclipse.jetty.toolchain.test.TestingDir;
import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.webapp.WebAppContext;
import org.junit.After; import org.junit.After;
@ -62,13 +64,20 @@ public class GlobalWebappConfigBindingTest
@Test @Test
public void testServerAndSystemClassesOverride() throws Exception public void testServerAndSystemClassesOverride() throws Exception
{ {
IO.copy(MavenTestingUtils.getTestResourceFile("context-binding-test-1.xml"),new File(jetty.getJettyHome(),"context-binding-test-1.xml")); File srcXml = MavenTestingUtils.getTestResourceFile("context-binding-test-1.xml");
File destXml = new File(jetty.getJettyHome(),"context-binding-test-1.xml");
IO.copy(srcXml,destXml);
PathAssert.assertFileExists("Context Binding XML",destXml);
jetty.addConfiguration("binding-test-contexts-1.xml"); jetty.addConfiguration("binding-test-contexts-1.xml");
jetty.load(); jetty.load();
jetty.start(); jetty.start();
WebAppContext context = jetty.getWebAppContexts().get(0); List<WebAppContext> contexts = jetty.getWebAppContexts();
Assert.assertThat("List of Contexts", contexts, hasSize(greaterThan(0)));
WebAppContext context = contexts.get(0);
Assert.assertNotNull("Context should not be null",context); Assert.assertNotNull("Context should not be null",context);
String defaultClasses[] = context.getDefaultServerClasses(); String defaultClasses[] = context.getDefaultServerClasses();

View File

@ -21,10 +21,12 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.jetty.deploy.AppProvider; import org.eclipse.jetty.deploy.AppProvider;
import org.eclipse.jetty.deploy.DeploymentManager; import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.deploy.test.XmlConfiguredJetty; import org.eclipse.jetty.deploy.test.XmlConfiguredJetty;
import org.eclipse.jetty.toolchain.test.OS;
import org.eclipse.jetty.toolchain.test.TestingDir; import org.eclipse.jetty.toolchain.test.TestingDir;
import org.eclipse.jetty.util.Scanner; import org.eclipse.jetty.util.Scanner;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.junit.After; import org.junit.After;
import org.junit.Assume;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
@ -137,6 +139,10 @@ public class ScanningAppProviderRuntimeUpdatesTest
@Test @Test
public void testAfterStartupThenUpdateContext() throws Exception public void testAfterStartupThenUpdateContext() throws Exception
{ {
// This test will not work on Windows as second war file would
// not be written over the first one because of a file lock
Assume.assumeTrue(!OS.IS_WINDOWS);
jetty.copyWebapp("foo-webapp-1.war","foo.war"); jetty.copyWebapp("foo-webapp-1.war","foo.war");
jetty.copyContext("foo.xml","foo.xml"); jetty.copyContext("foo.xml","foo.xml");

View File

@ -123,7 +123,7 @@ public class XmlConfiguredJetty
properties.setProperty("test.workdir",workishDir.getAbsolutePath()); properties.setProperty("test.workdir",workishDir.getAbsolutePath());
// Write out configuration for use by ConfigurationManager. // Write out configuration for use by ConfigurationManager.
File testConfig = MavenTestingUtils.getTargetFile("xml-configured-jetty.properties"); File testConfig = new File(_jettyHome, "xml-configured-jetty.properties");
FileOutputStream out = new FileOutputStream(testConfig); FileOutputStream out = new FileOutputStream(testConfig);
properties.store(out,"Generated by " + XmlConfiguredJetty.class.getName()); properties.store(out,"Generated by " + XmlConfiguredJetty.class.getName());
for (Object key:properties.keySet()) for (Object key:properties.keySet())

View File

@ -36,7 +36,7 @@
<Call name="addLifeCycleBinding"> <Call name="addLifeCycleBinding">
<Arg> <Arg>
<New class="org.eclipse.jetty.deploy.bindings.GlobalWebappConfigBinding"> <New class="org.eclipse.jetty.deploy.bindings.GlobalWebappConfigBinding">
<Set name="jettyXml">file://<SystemProperty name="jetty.home" />/context-binding-test-1.xml</Set> <Set name="jettyXml"><SystemProperty name="jetty.home" />/context-binding-test-1.xml</Set>
</New> </New>
</Arg> </Arg>
</Call> </Call>
@ -52,7 +52,7 @@
<Set name="configurationManager"> <Set name="configurationManager">
<New class="org.eclipse.jetty.deploy.FileConfigurationManager"> <New class="org.eclipse.jetty.deploy.FileConfigurationManager">
<Set name="file"> <Set name="file">
<Property name="test.targetdir" default="target" />/xml-configured-jetty.properties <SystemProperty name="jetty.home"/>/xml-configured-jetty.properties
</Set> </Set>
</New> </New>
</Set> </Set>

View File

@ -20,7 +20,7 @@
<Set name="configurationManager"> <Set name="configurationManager">
<New class="org.eclipse.jetty.deploy.FileConfigurationManager"> <New class="org.eclipse.jetty.deploy.FileConfigurationManager">
<Set name="file"> <Set name="file">
<Property name="test.targetdir" default="target" />/xml-configured-jetty.properties <SystemProperty name="jetty.home"/>/xml-configured-jetty.properties
</Set> </Set>
</New> </New>
</Set> </Set>

View File

@ -444,7 +444,7 @@ case "$ACTION" in
chown "$JETTY_USER" "$JETTY_PID" chown "$JETTY_USER" "$JETTY_PID"
# FIXME: Broken solution: wordsplitting, pathname expansion, arbitrary command execution, etc. # FIXME: Broken solution: wordsplitting, pathname expansion, arbitrary command execution, etc.
su - "$JETTY_USER" -c " su - "$JETTY_USER" -c "
${RUN_CMD[*]} --daemon & exec ${RUN_CMD[*]} --daemon &
disown \$! disown \$!
echo \$! > '$JETTY_PID'" echo \$! > '$JETTY_PID'"
else else

View File

@ -17,6 +17,12 @@
<artifactId>jetty-io</artifactId> <artifactId>jetty-io</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>${servlet.spec.groupId}</groupId>
<artifactId>${servlet.spec.artifactId}</artifactId>
<version>${servlet.spec.version}</version>
<scope>provided</scope>
</dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>

View File

@ -0,0 +1,394 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// 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.gzip;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.Set;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.eclipse.jetty.util.StringUtil;
/* ------------------------------------------------------------ */
/**
*/
public class GzipResponseWrapper extends HttpServletResponseWrapper
{
private HttpServletRequest _request;
private Set<String> _mimeTypes;
private int _bufferSize=8192;
private int _minGzipSize=256;
private PrintWriter _writer;
private GzipStream _gzStream;
private long _contentLength=-1;
private boolean _noGzip;
/**
* Instantiates a new gzip response wrapper.
*
* @param request the request
* @param response the response
*/
public GzipResponseWrapper(HttpServletRequest request, HttpServletResponse response)
{
super(response);
_request=request;
}
/* ------------------------------------------------------------ */
/**
* Sets the mime types.
*
* @param mimeTypes the new mime types
*/
public void setMimeTypes(Set<String> mimeTypes)
{
_mimeTypes = mimeTypes;
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.ServletResponseWrapper#setBufferSize(int)
*/
public void setBufferSize(int bufferSize)
{
_bufferSize = bufferSize;
}
/* ------------------------------------------------------------ */
/**
* Sets the min gzip size.
*
* @param minGzipSize the new min gzip size
*/
public void setMinGzipSize(int minGzipSize)
{
_minGzipSize = minGzipSize;
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.ServletResponseWrapper#setContentType(java.lang.String)
*/
public void setContentType(String ct)
{
super.setContentType(ct);
if (ct!=null)
{
int colon=ct.indexOf(";");
if (colon>0)
ct=ct.substring(0,colon);
}
if ((_gzStream==null || _gzStream._out==null) &&
(_mimeTypes==null && "application/gzip".equalsIgnoreCase(ct) ||
_mimeTypes!=null && (ct==null||!_mimeTypes.contains(StringUtil.asciiToLowerCase(ct)))))
{
noGzip();
}
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.http.HttpServletResponseWrapper#setStatus(int, java.lang.String)
*/
public void setStatus(int sc, String sm)
{
super.setStatus(sc,sm);
if (sc<200||sc>=300)
noGzip();
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.http.HttpServletResponseWrapper#setStatus(int)
*/
public void setStatus(int sc)
{
super.setStatus(sc);
if (sc<200||sc>=300)
noGzip();
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.ServletResponseWrapper#setContentLength(int)
*/
public void setContentLength(int length)
{
_contentLength=length;
if (_gzStream!=null)
_gzStream.setContentLength(length);
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.http.HttpServletResponseWrapper#addHeader(java.lang.String, java.lang.String)
*/
public void addHeader(String name, String value)
{
if ("content-length".equalsIgnoreCase(name))
{
_contentLength=Long.parseLong(value);
if (_gzStream!=null)
_gzStream.setContentLength(_contentLength);
}
else if ("content-type".equalsIgnoreCase(name))
{
setContentType(value);
}
else if ("content-encoding".equalsIgnoreCase(name))
{
super.addHeader(name,value);
if (!isCommitted())
{
noGzip();
}
}
else
super.addHeader(name,value);
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.http.HttpServletResponseWrapper#setHeader(java.lang.String, java.lang.String)
*/
public void setHeader(String name, String value)
{
if ("content-length".equalsIgnoreCase(name))
{
_contentLength=Long.parseLong(value);
if (_gzStream!=null)
_gzStream.setContentLength(_contentLength);
}
else if ("content-type".equalsIgnoreCase(name))
{
setContentType(value);
}
else if ("content-encoding".equalsIgnoreCase(name))
{
super.setHeader(name,value);
if (!isCommitted())
{
noGzip();
}
}
else
super.setHeader(name,value);
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.http.HttpServletResponseWrapper#setIntHeader(java.lang.String, int)
*/
public void setIntHeader(String name, int value)
{
if ("content-length".equalsIgnoreCase(name))
{
_contentLength=value;
if (_gzStream!=null)
_gzStream.setContentLength(_contentLength);
}
else
super.setIntHeader(name,value);
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.ServletResponseWrapper#flushBuffer()
*/
public void flushBuffer() throws IOException
{
if (_writer!=null)
_writer.flush();
if (_gzStream!=null)
_gzStream.finish();
else
getResponse().flushBuffer();
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.ServletResponseWrapper#reset()
*/
public void reset()
{
super.reset();
if (_gzStream!=null)
_gzStream.resetBuffer();
_writer=null;
_gzStream=null;
_noGzip=false;
_contentLength=-1;
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.ServletResponseWrapper#resetBuffer()
*/
public void resetBuffer()
{
super.resetBuffer();
if (_gzStream!=null)
_gzStream.resetBuffer();
_writer=null;
_gzStream=null;
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.http.HttpServletResponseWrapper#sendError(int, java.lang.String)
*/
public void sendError(int sc, String msg) throws IOException
{
resetBuffer();
super.sendError(sc,msg);
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.http.HttpServletResponseWrapper#sendError(int)
*/
public void sendError(int sc) throws IOException
{
resetBuffer();
super.sendError(sc);
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.http.HttpServletResponseWrapper#sendRedirect(java.lang.String)
*/
public void sendRedirect(String location) throws IOException
{
resetBuffer();
super.sendRedirect(location);
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.ServletResponseWrapper#getOutputStream()
*/
public ServletOutputStream getOutputStream() throws IOException
{
if (_gzStream==null)
{
if (getResponse().isCommitted() || _noGzip)
return getResponse().getOutputStream();
_gzStream=newGzipStream(_request,(HttpServletResponse)getResponse(),_contentLength,_bufferSize,_minGzipSize);
}
else if (_writer!=null)
throw new IllegalStateException("getWriter() called");
return _gzStream;
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.ServletResponseWrapper#getWriter()
*/
public PrintWriter getWriter() throws IOException
{
if (_writer==null)
{
if (_gzStream!=null)
throw new IllegalStateException("getOutputStream() called");
if (getResponse().isCommitted() || _noGzip)
return getResponse().getWriter();
_gzStream=newGzipStream(_request,(HttpServletResponse)getResponse(),_contentLength,_bufferSize,_minGzipSize);
_writer=newWriter(_gzStream,getCharacterEncoding());
}
return _writer;
}
/* ------------------------------------------------------------ */
/**
* No gzip.
*/
public void noGzip()
{
_noGzip=true;
if (_gzStream!=null)
{
try
{
_gzStream.doNotGzip();
}
catch (IOException e)
{
throw new IllegalStateException(e);
}
}
}
/* ------------------------------------------------------------ */
/**
* Finish.
*
* @throws IOException Signals that an I/O exception has occurred.
*/
public void finish() throws IOException
{
if (_writer!=null && !_gzStream._closed)
_writer.flush();
if (_gzStream!=null)
_gzStream.finish();
}
/* ------------------------------------------------------------ */
/**
* Allows derived implementations to replace GzipStream implementation.
*
* @param request the request
* @param response the response
* @param contentLength the content length
* @param bufferSize the buffer size
* @param minGzipSize the min gzip size
* @return the gzip stream
* @throws IOException Signals that an I/O exception has occurred.
*/
protected GzipStream newGzipStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minGzipSize) throws IOException
{
return new GzipStream(request,response,contentLength,bufferSize,minGzipSize);
}
/* ------------------------------------------------------------ */
/**
* Allows derived implementations to replace PrintWriter implementation.
*
* @param out the out
* @param encoding the encoding
* @return the prints the writer
* @throws UnsupportedEncodingException the unsupported encoding exception
*/
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
{
return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
}
}

View File

@ -0,0 +1,300 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// 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.gzip;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.util.ByteArrayOutputStream2;
/* ------------------------------------------------------------ */
/**
*/
public class GzipStream extends ServletOutputStream
{
protected HttpServletRequest _request;
protected HttpServletResponse _response;
protected OutputStream _out;
protected ByteArrayOutputStream2 _bOut;
protected GZIPOutputStream _gzOut;
protected boolean _closed;
protected int _bufferSize;
protected int _minGzipSize;
protected long _contentLength;
/**
* Instantiates a new gzip stream.
*
* @param request the request
* @param response the response
* @param contentLength the content length
* @param bufferSize the buffer size
* @param minGzipSize the min gzip size
* @throws IOException Signals that an I/O exception has occurred.
*/
public GzipStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minGzipSize) throws IOException
{
_request=request;
_response=response;
_contentLength=contentLength;
_bufferSize=bufferSize;
_minGzipSize=minGzipSize;
if (minGzipSize==0)
doGzip();
}
/**
* Reset buffer.
*/
public void resetBuffer()
{
if (_response.isCommitted())
throw new IllegalStateException("Committed");
_closed=false;
_out=null;
_bOut=null;
if (_gzOut!=null)
_response.setHeader("Content-Encoding",null);
_gzOut=null;
}
/**
* Sets the content length.
*
* @param length the new content length
*/
public void setContentLength(long length)
{
_contentLength=length;
}
/* ------------------------------------------------------------ */
/**
* @see java.io.OutputStream#flush()
*/
public void flush() throws IOException
{
if (_out==null || _bOut!=null)
{
if (_contentLength>0 && _contentLength<_minGzipSize)
doNotGzip();
else
doGzip();
}
_out.flush();
}
/* ------------------------------------------------------------ */
/**
* @see java.io.OutputStream#close()
*/
public void close() throws IOException
{
if (_closed)
return;
if (_request.getAttribute("javax.servlet.include.request_uri")!=null)
flush();
else
{
if (_bOut!=null)
{
if (_contentLength<0)
_contentLength=_bOut.getCount();
if (_contentLength<_minGzipSize)
doNotGzip();
else
doGzip();
}
else if (_out==null)
{
doNotGzip();
}
if (_gzOut!=null)
_gzOut.close();
else
_out.close();
_closed=true;
}
}
/**
* Finish.
*
* @throws IOException Signals that an I/O exception has occurred.
*/
public void finish() throws IOException
{
if (!_closed)
{
if (_out==null || _bOut!=null)
{
if (_contentLength>0 && _contentLength<_minGzipSize)
doNotGzip();
else
doGzip();
}
if (_gzOut!=null && !_closed)
{
_closed=true;
_gzOut.close();
}
}
}
/* ------------------------------------------------------------ */
/**
* @see java.io.OutputStream#write(int)
*/
public void write(int b) throws IOException
{
checkOut(1);
_out.write(b);
}
/* ------------------------------------------------------------ */
/**
* @see java.io.OutputStream#write(byte[])
*/
public void write(byte b[]) throws IOException
{
checkOut(b.length);
_out.write(b);
}
/* ------------------------------------------------------------ */
/**
* @see java.io.OutputStream#write(byte[], int, int)
*/
public void write(byte b[], int off, int len) throws IOException
{
checkOut(len);
_out.write(b,off,len);
}
/**
* Sets the content encoding gzip.
*
* @return true, if successful
*/
protected boolean setContentEncodingGzip()
{
_response.setHeader("Content-Encoding", "gzip");
return _response.containsHeader("Content-Encoding");
}
/**
* Do gzip.
*
* @throws IOException Signals that an I/O exception has occurred.
*/
public void doGzip() throws IOException
{
if (_gzOut==null)
{
if (_response.isCommitted())
throw new IllegalStateException();
if (setContentEncodingGzip())
{
_out=_gzOut=new GZIPOutputStream(_response.getOutputStream(),_bufferSize);
if (_bOut!=null)
{
_out.write(_bOut.getBuf(),0,_bOut.getCount());
_bOut=null;
}
}
else
doNotGzip();
}
}
/**
* Do not gzip.
*
* @throws IOException Signals that an I/O exception has occurred.
*/
public void doNotGzip() throws IOException
{
if (_gzOut!=null)
throw new IllegalStateException();
if (_out==null || _bOut!=null )
{
_out=_response.getOutputStream();
if (_contentLength>=0)
{
if(_contentLength<Integer.MAX_VALUE)
_response.setContentLength((int)_contentLength);
else
_response.setHeader("Content-Length",Long.toString(_contentLength));
}
if (_bOut!=null)
_out.write(_bOut.getBuf(),0,_bOut.getCount());
_bOut=null;
}
}
/**
* Check out.
*
* @param length the length
* @throws IOException Signals that an I/O exception has occurred.
*/
private void checkOut(int length) throws IOException
{
if (_closed)
throw new IOException("CLOSED");
if (_out==null)
{
if (_response.isCommitted() || (_contentLength>=0 && _contentLength<_minGzipSize))
doNotGzip();
else if (length>_minGzipSize)
doGzip();
else
_out=_bOut=new ByteArrayOutputStream2(_bufferSize);
}
else if (_bOut!=null)
{
if (_response.isCommitted() || (_contentLength>=0 && _contentLength<_minGzipSize))
doNotGzip();
else if (length>=(_bOut.getBuf().length -_bOut.getCount()))
doGzip();
}
}
/**
* Allows derived implementations to replace PrintWriter implementation.
*/
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
{
return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
}
}

View File

@ -169,13 +169,13 @@ public interface EndPoint
* the {@link java.net.Socket#getSoTimeout()} for blocking connections, * the {@link java.net.Socket#getSoTimeout()} for blocking connections,
* but {@link AsyncEndPoint} implementations must use other mechanisms * but {@link AsyncEndPoint} implementations must use other mechanisms
* to implement the max idle time. * to implement the max idle time.
* @return the max idle time in ms. * @return the max idle time in ms or if ms <= 0 implies an infinite timeout
*/ */
public int getMaxIdleTime(); public int getMaxIdleTime();
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Set the max idle time. /** Set the max idle time.
* @param timeMs the max idle time in MS. * @param timeMs the max idle time in MS. Timeout <= 0 implies an infinite timeout
* @throws IOException if the timeout cannot be set. * @throws IOException if the timeout cannot be set.
*/ */
public void setMaxIdleTime(int timeMs) throws IOException; public void setMaxIdleTime(int timeMs) throws IOException;

View File

@ -154,49 +154,39 @@ public class ChannelEndPoint implements EndPoint
final NIOBuffer nbuf = (NIOBuffer)buf; final NIOBuffer nbuf = (NIOBuffer)buf;
final ByteBuffer bbuf=nbuf.getByteBuffer(); final ByteBuffer bbuf=nbuf.getByteBuffer();
//noinspection SynchronizationOnLocalVariableOrMethodParameter //noinspection SynchronizationOnLocalVariableOrMethodParameter
synchronized(bbuf)
try
{ {
try synchronized(bbuf)
{
bbuf.position(buffer.putIndex());
len=_channel.read(bbuf);
if (len<0 && isOpen() && !isInputShutdown())
{
try
{
shutdownInput();
}
catch(IOException x)
{
Log.ignore(x);
try
{
close();
}
catch (IOException xx)
{
Log.ignore(xx);
}
}
}
}
catch (IOException x)
{ {
try try
{ {
close(); bbuf.position(buffer.putIndex());
len=_channel.read(bbuf);
} }
catch (IOException xx) finally
{ {
Log.ignore(xx); buffer.setPutIndex(bbuf.position());
bbuf.position(0);
} }
throw x;
} }
finally
if (len<0 && isOpen() && !isInputShutdown())
shutdownInput();
}
catch (IOException x)
{
try
{ {
buffer.setPutIndex(bbuf.position()); close();
bbuf.position(0);
} }
catch (IOException xx)
{
Log.ignore(xx);
}
if (len>=0)
throw x;
} }
} }
else else

View File

@ -326,7 +326,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
try try
{ {
updateKey(); updateKey();
this.wait(end-now); this.wait(timeoutMs>=0?(end-now):10000);
} }
catch (InterruptedException e) catch (InterruptedException e)
{ {
@ -337,7 +337,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
now=_selectSet.getNow(); now=_selectSet.getNow();
} }
if (_readBlocked && now>=end) if (_readBlocked && timeoutMs>0 && now>=end)
return false; return false;
} }
} }
@ -371,7 +371,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
try try
{ {
updateKey(); updateKey();
this.wait(end-now); this.wait(timeoutMs>=0?(end-now):10000);
} }
catch (InterruptedException e) catch (InterruptedException e)
{ {
@ -381,7 +381,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{ {
now=_selectSet.getNow(); now=_selectSet.getNow();
} }
if (_writeBlocked && now>=end) if (_writeBlocked && timeoutMs>0 && now>=end)
return false; return false;
} }
} }

View File

@ -434,6 +434,10 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
key.attach(endpoint); key.attach(endpoint);
endpoint.schedule(); endpoint.schedule();
} }
else if (change instanceof ChangeTask)
{
((Runnable)change).run();
}
else if (change instanceof Runnable) else if (change instanceof Runnable)
{ {
dispatch((Runnable)change); dispatch((Runnable)change);
@ -441,6 +445,10 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
else else
throw new IllegalArgumentException(change.toString()); throw new IllegalArgumentException(change.toString());
} }
catch (CancelledKeyException e)
{
Log.ignore(e);
}
catch (Throwable e) catch (Throwable e)
{ {
if (e instanceof ThreadDeath) if (e instanceof ThreadDeath)
@ -450,17 +458,14 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
Log.warn(e); Log.warn(e);
else else
Log.debug(e); Log.debug(e);
if(ch!=null && key==null) try
{ {
try ch.close();
{ }
ch.close(); catch(IOException e2)
} {
catch(IOException e2) Log.debug(e2);
{
Log.debug(e2);
}
} }
} }
} }
@ -518,6 +523,8 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
// Look for things to do // Look for things to do
for (SelectionKey key: selector.selectedKeys()) for (SelectionKey key: selector.selectedKeys())
{ {
SocketChannel channel=null;
try try
{ {
if (!key.isValid()) if (!key.isValid())
@ -538,7 +545,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
else if (key.isConnectable()) else if (key.isConnectable())
{ {
// Complete a connection of a registered channel // Complete a connection of a registered channel
SocketChannel channel = (SocketChannel)key.channel(); channel = (SocketChannel)key.channel();
boolean connected=false; boolean connected=false;
try try
{ {
@ -566,7 +573,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
else else
{ {
// Wrap readable registered channel in an endpoint // Wrap readable registered channel in an endpoint
SocketChannel channel = (SocketChannel)key.channel(); channel = (SocketChannel)key.channel();
SelectChannelEndPoint endpoint = createEndPoint(channel,key); SelectChannelEndPoint endpoint = createEndPoint(channel,key);
key.attach(endpoint); key.attach(endpoint);
if (key.isReadable()) if (key.isReadable())
@ -585,6 +592,16 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
else else
Log.ignore(e); Log.ignore(e);
try
{
if (channel!=null)
channel.close();
}
catch(IOException e2)
{
Log.debug(e2);
}
if (key != null && !(key.channel() instanceof ServerSocketChannel) && key.isValid()) if (key != null && !(key.channel() instanceof ServerSocketChannel) && key.isValid())
key.cancel(); key.cancel();
} }
@ -839,6 +856,14 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
} }
catch(Exception e) catch(Exception e)
{ {
addChange(new ChangeTask()
{
public void run()
{
renewSelector();
}
});
renewSelector(); renewSelector();
} }
} }
@ -1011,4 +1036,11 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
_deferringInterestedOps0 = deferringInterestedOps0; _deferringInterestedOps0 = deferringInterestedOps0;
} }
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
private interface ChangeTask extends Runnable
{}
} }

View File

@ -46,6 +46,20 @@
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
<repositories>
<repository>
<id>repository.apache.org</id>
<name>Apache Snapshot Repository</name>
<layout>default</layout>
<url>http://repository.apache.org/content/groups/snapshots/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
<dependencies> <dependencies>
<dependency> <dependency>

View File

@ -17,6 +17,7 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -32,6 +33,7 @@ import org.eclipse.jetty.util.component.Container;
import org.eclipse.jetty.util.component.Container.Relationship; import org.eclipse.jetty.util.component.Container.Relationship;
import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.ShutdownThread; import org.eclipse.jetty.util.thread.ShutdownThread;
/** /**
@ -39,10 +41,12 @@ import org.eclipse.jetty.util.thread.ShutdownThread;
*/ */
public class MBeanContainer extends AbstractLifeCycle implements Container.Listener, Dumpable public class MBeanContainer extends AbstractLifeCycle implements Container.Listener, Dumpable
{ {
private final static Logger __log = Log.getLogger(MBeanContainer.class.getName());
private final MBeanServer _server; private final MBeanServer _server;
private final WeakHashMap<Object, ObjectName> _beans = new WeakHashMap<Object, ObjectName>(); private final WeakHashMap<Object, ObjectName> _beans = new WeakHashMap<Object, ObjectName>();
private final HashMap<String, Integer> _unique = new HashMap<String, Integer>(); private final HashMap<String, Integer> _unique = new HashMap<String, Integer>();
private final MultiMap<ObjectName> _relations = new MultiMap<ObjectName>(); private final WeakHashMap<ObjectName,List<Container.Relationship>> _relations = new WeakHashMap<ObjectName,List<Container.Relationship>>();
private String _domain = null; private String _domain = null;
/** /**
@ -89,7 +93,7 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
} }
catch (Exception e) catch (Exception e)
{ {
Log.ignore(e); __log.ignore(e);
} }
} }
@ -130,6 +134,7 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
*/ */
public synchronized void add(Relationship relationship) public synchronized void add(Relationship relationship)
{ {
__log.debug("add {}",relationship);
ObjectName parent = _beans.get(relationship.getParent()); ObjectName parent = _beans.get(relationship.getParent());
if (parent == null) if (parent == null)
{ {
@ -145,7 +150,15 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
} }
if (parent != null && child != null) if (parent != null && child != null)
_relations.add(parent, relationship); {
List<Container.Relationship> rels = _relations.get(parent);
if (rels==null)
{
rels=new ArrayList<Container.Relationship>();
_relations.put(parent,rels);
}
rels.add(relationship);
}
} }
/** /**
@ -155,11 +168,23 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
*/ */
public synchronized void remove(Relationship relationship) public synchronized void remove(Relationship relationship)
{ {
__log.debug("remove {}",relationship);
ObjectName parent = _beans.get(relationship.getParent()); ObjectName parent = _beans.get(relationship.getParent());
ObjectName child = _beans.get(relationship.getChild()); ObjectName child = _beans.get(relationship.getChild());
if (parent != null && child != null) if (parent != null && child != null)
_relations.removeValue(parent, relationship); {
List<Container.Relationship> rels = _relations.get(parent);
if (rels!=null)
{
for (Iterator<Container.Relationship> i=rels.iterator();i.hasNext();)
{
Container.Relationship r = i.next();
if (relationship.equals(r) || r.getChild()==null)
i.remove();
}
}
}
} }
/** /**
@ -169,14 +194,15 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
*/ */
public synchronized void removeBean(Object obj) public synchronized void removeBean(Object obj)
{ {
__log.debug("removeBean {}",obj);
ObjectName bean = _beans.remove(obj); ObjectName bean = _beans.remove(obj);
if (bean != null) if (bean != null)
{ {
List<?> beanRelations = _relations.getValues(bean); List<Container.Relationship> beanRelations= _relations.remove(bean);
if (beanRelations != null && beanRelations.size() > 0) if (beanRelations != null)
{ {
Log.debug("Unregister {}", beanRelations); __log.debug("Unregister {}", beanRelations);
List<?> removeList = new ArrayList<Object>(beanRelations); List<?> removeList = new ArrayList<Object>(beanRelations);
for (Object r : removeList) for (Object r : removeList)
{ {
@ -188,15 +214,15 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
try try
{ {
_server.unregisterMBean(bean); _server.unregisterMBean(bean);
Log.debug("Unregistered {}", bean); __log.debug("Unregistered {}", bean);
} }
catch (javax.management.InstanceNotFoundException e) catch (javax.management.InstanceNotFoundException e)
{ {
Log.ignore(e); __log.ignore(e);
} }
catch (Exception e) catch (Exception e)
{ {
Log.warn(e); __log.warn(e);
} }
} }
} }
@ -208,6 +234,7 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
*/ */
public synchronized void addBean(Object obj) public synchronized void addBean(Object obj)
{ {
__log.debug("addBean {}",obj);
try try
{ {
if (obj == null || _beans.containsKey(obj)) if (obj == null || _beans.containsKey(obj))
@ -271,13 +298,13 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
} }
ObjectInstance oinstance = _server.registerMBean(mbean, oname); ObjectInstance oinstance = _server.registerMBean(mbean, oname);
Log.debug("Registered {}", oinstance.getObjectName()); __log.debug("Registered {}", oinstance.getObjectName());
_beans.put(obj, oinstance.getObjectName()); _beans.put(obj, oinstance.getObjectName());
} }
catch (Exception e) catch (Exception e)
{ {
Log.warn("bean: " + obj, e); __log.warn("bean: " + obj, e);
} }
} }

View File

@ -139,7 +139,12 @@ public class ObjectMBean implements DynamicMBean
} }
catch (ClassNotFoundException e) catch (ClassNotFoundException e)
{ {
if (e.toString().endsWith("MBean")) // The code below was modified to fix bug 332200.
// The issue was caused by additional information
// added to the message after the class name when
// Jetty is running in Apache Felix.
String klass = e.getMessage().split("[ ]", 2)[0];
if (klass.endsWith("MBean"))
Log.ignore(e); Log.ignore(e);
else else
Log.warn(e); Log.warn(e);

View File

@ -16,6 +16,19 @@ Import-Package: javax.mail;version="1.4.0";resolution:=optional,
javax.transaction.xa;version="1.1.0";resolution:=optional, javax.transaction.xa;version="1.1.0";resolution:=optional,
org.eclipse.jetty.nested;version="8.0.0";resolution:=optional, org.eclipse.jetty.nested;version="8.0.0";resolution:=optional,
org.eclipse.jetty.annotations;version="8.0.0";resolution:=optional, org.eclipse.jetty.annotations;version="8.0.0";resolution:=optional,
org.eclipse.jetty.deploy;version="8.0.0",
org.eclipse.jetty.deploy.providers;version="8.0.0",
org.eclipse.jetty.http;version="8.0.0",
org.eclipse.jetty.nested;version="8.0.0";resolution:=optional,
org.eclipse.jetty.server;version="8.0.0",
org.eclipse.jetty.server.handler;version="8.0.0",
org.eclipse.jetty.servlet;version="8.0.0",
org.eclipse.jetty.util;version="8.0.0",
org.eclipse.jetty.util.component;version="8.0.0",
org.eclipse.jetty.util.log;version="8.0.0",
org.eclipse.jetty.util.resource;version="8.0.0",
org.eclipse.jetty.webapp;version="8.0.0",
org.eclipse.jetty.xml;version="8.0.0",
org.osgi.framework, org.osgi.framework,
org.osgi.service.cm;version="1.2.0", org.osgi.service.cm;version="1.2.0",
org.osgi.service.packageadmin, org.osgi.service.packageadmin,
@ -29,25 +42,8 @@ Import-Package: javax.mail;version="1.4.0";resolution:=optional,
org.xml.sax.helpers org.xml.sax.helpers
Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-Classpath: . Bundle-Classpath: .
Require-Bundle: org.eclipse.jetty.ajp;bundle-version="[8.0,9)";resolution:=optional,
org.eclipse.jetty.annotations;bundle-version="[8.0,9)";resolution:=optional,
org.eclipse.jetty.client;bundle-version="[8.0,9)";resolution:=optional,
org.eclipse.jetty.continuation;bundle-version="[7.0,9)";resolution:=optional,
org.eclipse.jetty.deploy;bundle-version="[8.0,9)",
org.eclipse.jetty.http;bundle-version="[8.0,9)",
org.eclipse.jetty.io;bundle-version="[8.0,9)",
org.eclipse.jetty.jmx;bundle-version="[8.0,9)";resolution:=optional,
org.eclipse.jetty.jndi;bundle-version="[8.0,9)";resolution:=optional,
org.eclipse.jetty.plus;bundle-version="[8.0,9.0)";resolution:=optional,
org.eclipse.jetty.rewrite;bundle-version="[8.0,9)";resolution:=optional,
org.eclipse.jetty.security;bundle-version="[8.0,9)";resolution:=optional,
org.eclipse.jetty.server;bundle-version="[8.0,9)",
org.eclipse.jetty.servlet;bundle-version="[8.0,9)",
org.eclipse.jetty.servlets;bundle-version="[8.0,9)";resolution:=optional,
org.eclipse.jetty.util;bundle-version="[8.0,9)",
org.eclipse.jetty.webapp;bundle-version="[8.0,9)",
org.eclipse.jetty.websocket;bundle-version="[8.0,9)";resolution:=optional,
org.eclipse.jetty.xml;bundle-version="[8.0,9)"
Export-Package: org.eclipse.jetty.osgi.boot;version="8.0.0", Export-Package: org.eclipse.jetty.osgi.boot;version="8.0.0",
org.eclipse.jetty.osgi.nested;version="8.0.0",
org.eclipse.jetty.osgi.boot.utils;version="8.0.0", org.eclipse.jetty.osgi.boot.utils;version="8.0.0",
org.eclipse.jetty.osgi.annotations;version="8.0.0" org.eclipse.jetty.osgi.annotations;version="8.0.0"
DynamicImport-Package: org.eclipse.jetty.*;version="[8.0,9)"

View File

@ -16,7 +16,10 @@
<Arg> <Arg>
<New id="NestedConnector" class="org.eclipse.jetty.nested.NestedConnector"> <New id="NestedConnector" class="org.eclipse.jetty.nested.NestedConnector">
<Set name="statsOn">false</Set> <Set name="statsOn">false</Set>
<Set name="confidentialPort">8443</Set> <Set name="forwarded">true</Set>
<Set name="forwardedHostHeader">x-forwarded_for</Set>
<Set name="forwardedCipherSuiteHeader">sslclientcipher</Set>
<Set name="forwardedSslSessionIdHeader">sslsessionid</Set>
<Call name="addLifeCycleListener"> <Call name="addLifeCycleListener">
<Arg> <Arg>
<New class="org.eclipse.jetty.osgi.nested.NestedConnectorListener" id="NestedConnectorListener"> <New class="org.eclipse.jetty.osgi.nested.NestedConnectorListener" id="NestedConnectorListener">

View File

@ -53,7 +53,7 @@
<phase>process-resources</phase> <phase>process-resources</phase>
<configuration> <configuration>
<tasks> <tasks>
<delete file="target/classes/META-INF/MANIFEST.MF" /> <!--delete file="target/classes/META-INF/MANIFEST.MF" /-->
<copy todir="target/classes/jettyhome"> <copy todir="target/classes/jettyhome">
<fileset dir="jettyhome"> <fileset dir="jettyhome">
<exclude name="**/*.log" /> <exclude name="**/*.log" />
@ -105,7 +105,7 @@
</executions> </executions>
<configuration> <configuration>
<instructions> <instructions>
<Bundle-SymbolicName>org.eclipse.jetty.osgi.boot;singleton:=true</Bundle-SymbolicName> <Bundle-SymbolicName>org.eclipse.jetty.osgi.boot</Bundle-SymbolicName>
<Export-Package>org.eclipse.jetty.osgi.boot;version="${parsedVersion.osgiVersion}",org.eclipse.jetty.osgi.boot.utils,org.eclipse.jetty.osgi.nested;version="${parsedVersion.osgiVersion}"</Export-Package> <Export-Package>org.eclipse.jetty.osgi.boot;version="${parsedVersion.osgiVersion}",org.eclipse.jetty.osgi.boot.utils,org.eclipse.jetty.osgi.nested;version="${parsedVersion.osgiVersion}"</Export-Package>
<Bundle-Activator>org.eclipse.jetty.osgi.boot.JettyBootstrapActivator</Bundle-Activator> <Bundle-Activator>org.eclipse.jetty.osgi.boot.JettyBootstrapActivator</Bundle-Activator>
<!-- disable the uses directive: jetty will accomodate pretty much any versions <!-- disable the uses directive: jetty will accomodate pretty much any versions

View File

@ -70,6 +70,7 @@ public class JettyBootstrapActivator implements BundleActivator
private JettyContextHandlerServiceTracker _jettyContextHandlerTracker; private JettyContextHandlerServiceTracker _jettyContextHandlerTracker;
private PackageAdminServiceTracker _packageAdminServiceTracker; private PackageAdminServiceTracker _packageAdminServiceTracker;
private BundleTracker _webBundleTracker; private BundleTracker _webBundleTracker;
private BundleContext _bundleContext;
// private ServiceRegistration _jettyServerFactoryService; // private ServiceRegistration _jettyServerFactoryService;
private JettyServerServiceTracker _jettyServerServiceTracker; private JettyServerServiceTracker _jettyServerServiceTracker;
@ -86,6 +87,7 @@ public class JettyBootstrapActivator implements BundleActivator
public void start(BundleContext context) throws Exception public void start(BundleContext context) throws Exception
{ {
INSTANCE = this; INSTANCE = this;
_bundleContext = context;
// track other bundles and fragments attached to this bundle that we // track other bundles and fragments attached to this bundle that we
// should activate. // should activate.
@ -298,18 +300,28 @@ public class JettyBootstrapActivator implements BundleActivator
*/ */
private static void checkBundleActivated() private static void checkBundleActivated()
{ {
if (INSTANCE == null) { if (INSTANCE == null)
Bundle thisBundle = FrameworkUtil.getBundle(JettyBootstrapActivator.class); {
try Bundle thisBundle = FrameworkUtil.getBundle(JettyBootstrapActivator.class);
{ try
thisBundle.start(); {
} thisBundle.start();
catch (BundleException e) }
{ catch (BundleException e)
//nevermind. {
} // nevermind.
} }
}
}
/**
* @return The bundle context for this bundle.
*/
public static BundleContext getBundleContext()
{
checkBundleActivated();
return INSTANCE._bundleContext;
} }
} }

View File

@ -17,17 +17,26 @@ package org.eclipse.jetty.osgi.boot;
import java.io.File; import java.io.File;
import java.io.FilenameFilter; import java.io.FilenameFilter;
import java.io.IOException; import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set;
import org.eclipse.jetty.deploy.App; import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.AppProvider; import org.eclipse.jetty.deploy.AppProvider;
import org.eclipse.jetty.deploy.DeploymentManager; import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.deploy.providers.ContextProvider; import org.eclipse.jetty.deploy.providers.ContextProvider;
import org.eclipse.jetty.deploy.providers.ScanningAppProvider; import org.eclipse.jetty.deploy.providers.ScanningAppProvider;
import org.eclipse.jetty.osgi.boot.utils.internal.PackageAdminServiceTracker;
import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.Scanner;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.webapp.WebAppContext;
import org.osgi.framework.Bundle; import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
/** /**
* AppProvider for OSGi. Supports the configuration of ContextHandlers and * AppProvider for OSGi. Supports the configuration of ContextHandlers and
@ -42,6 +51,12 @@ import org.osgi.framework.Bundle;
* it supports the deployment of WebAppContexts. Except for the scanning of the * it supports the deployment of WebAppContexts. Except for the scanning of the
* webapps directory. * webapps directory.
* </p> * </p>
* <p>
* When the parameter autoInstallOSGiBundles is set to true, OSGi bundles that
* are located in the monitored directory are installed and started after the
* framework as finished auto-starting all the other bundles.
* Warning: only use this for development.
* </p>
*/ */
public class OSGiAppProvider extends ScanningAppProvider implements AppProvider public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
{ {
@ -51,7 +66,12 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
private String _defaultsDescriptor; private String _defaultsDescriptor;
private String _tldBundles; private String _tldBundles;
private String[] _configurationClasses; private String[] _configurationClasses;
private boolean _autoInstallOSGiBundles = true;
//Keep track of the bundles that were installed and that are waiting for the
//framework to complete its initialization.
Set<Bundle> _pendingBundlesToStart = null;
/** /**
* When a context file corresponds to a deployed bundle and is changed we * When a context file corresponds to a deployed bundle and is changed we
* reload the corresponding bundle. * reload the corresponding bundle.
@ -59,10 +79,15 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
private static class Filter implements FilenameFilter private static class Filter implements FilenameFilter
{ {
OSGiAppProvider _enclosedInstance; OSGiAppProvider _enclosedInstance;
public boolean accept(File dir, String name) public boolean accept(File dir, String name)
{ {
if (!new File(dir,name).isDirectory()) File file = new File(dir,name);
if (fileMightBeAnOSGiBundle(file))
{
return true;
}
if (!file.isDirectory())
{ {
String contextName = getDeployedAppName(name); String contextName = getDeployedAppName(name);
if (contextName != null) if (contextName != null)
@ -352,6 +377,24 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
_extractWars=extract; _extractWars=extract;
} }
/**
* @return true when this app provider locates osgi bundles and features in
* its monitored directory and installs them. By default true if there is a folder to monitor.
*/
public boolean isAutoInstallOSGiBundles()
{
return _autoInstallOSGiBundles;
}
/**
* &lt;autoInstallOSGiBundles&gt;true&lt;/autoInstallOSGiBundles&gt;
* @param installingOSGiBundles
*/
public void setAutoInstallOSGiBundles(boolean installingOSGiBundles)
{
_autoInstallOSGiBundles=installingOSGiBundles;
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
@ -361,6 +404,10 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
* directory, then the ContextXmlDir is examined to see if a foo.xml file * directory, then the ContextXmlDir is examined to see if a foo.xml file
* exists. If it does, then this deployer will not deploy the webapp and the * exists. If it does, then this deployer will not deploy the webapp and the
* ContextProvider should be used to act on the foo.xml file. * ContextProvider should be used to act on the foo.xml file.
* </p>
* <p>
* Also if this directory contains some osgi bundles, it will install them.
* </p>
* *
* @see ContextProvider * @see ContextProvider
* @param contextsDir * @param contextsDir
@ -405,5 +452,273 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
return _configurationClasses; return _configurationClasses;
} }
/**
* Overridden to install the OSGi bundles found in the monitored folder.
*/
protected void doStart() throws Exception
{
if (isAutoInstallOSGiBundles())
{
if (getMonitoredDirResource() == null)
{
setAutoInstallOSGiBundles(false);
Log.info("Disable autoInstallOSGiBundles as there is not contexts folder to monitor.");
}
else
{
File scandir = null;
try
{
scandir = getMonitoredDirResource().getFile();
if (!scandir.exists() || !scandir.isDirectory())
{
setAutoInstallOSGiBundles(false);
Log.warn("Disable autoInstallOSGiBundles as the contexts folder '" + scandir.getAbsolutePath() + " does not exist.");
scandir = null;
}
}
catch (IOException ioe)
{
setAutoInstallOSGiBundles(false);
Log.warn("Disable autoInstallOSGiBundles as the contexts folder '" + getMonitoredDirResource().getURI() + " does not exist.");
scandir = null;
}
if (scandir != null)
{
for (File file : scandir.listFiles())
{
if (fileMightBeAnOSGiBundle(file))
{
installBundle(file, false);
}
}
}
}
}
super.doStart();
if (isAutoInstallOSGiBundles())
{
Scanner.ScanCycleListener scanCycleListner = new AutoStartWhenFrameworkHasCompleted(this);
super.addScannerListener(scanCycleListner);
}
}
/**
* When the file is a jar or a folder, we look if it looks like an OSGi bundle.
* In that case we install it and start it.
* <p>
* Really a simple trick to get going quickly with development.
* </p>
*/
@Override
protected void fileAdded(String filename) throws Exception
{
File file = new File(filename);
if (isAutoInstallOSGiBundles() && file.exists() && fileMightBeAnOSGiBundle(file))
{
installBundle(file, true);
}
else
{
super.fileAdded(filename);
}
}
/**
* @param file
* @return
*/
private static boolean fileMightBeAnOSGiBundle(File file)
{
if (file.isDirectory())
{
if (new File(file,"META-INF/MANIFEST.MF").exists())
{
return true;
}
}
else if (file.getName().endsWith(".jar"))
{
return true;
}
return false;
}
@Override
protected void fileChanged(String filename) throws Exception
{
File file = new File(filename);
if (isAutoInstallOSGiBundles() && fileMightBeAnOSGiBundle(file))
{
updateBundle(file);
}
else
{
super.fileChanged(filename);
}
}
@Override
protected void fileRemoved(String filename) throws Exception
{
File file = new File(filename);
if (isAutoInstallOSGiBundles() && fileMightBeAnOSGiBundle(file))
{
uninstallBundle(file);
}
else
{
super.fileRemoved(filename);
}
}
/**
* Returns a bundle according to its location.
* In the version 1.6 of org.osgi.framework, BundleContext.getBundle(String) is what we want.
* However to support older versions of OSGi. We use our own local refrence mechanism.
* @param location
* @return
*/
protected Bundle getBundle(BundleContext bc, String location)
{
//not available in older versions of OSGi:
//return bc.getBundle(location);
for (Bundle b : bc.getBundles())
{
if (b.getLocation().equals(location))
{
return b;
}
}
return null;
}
protected synchronized Bundle installBundle(File file, boolean start)
{
try
{
BundleContext bc = JettyBootstrapActivator.getBundleContext();
String location = file.toURI().toString();
Bundle b = getBundle(bc, location);
if (b == null)
{
b = bc.installBundle(location);
}
if (b == null)
{
//not sure we will ever be here,
//most likely a BundleException was thrown
Log.warn("The file " + location + " is not an OSGi bundle.");
return null;
}
if (start && b.getHeaders().get(Constants.FRAGMENT_HOST) == null)
{//not a fragment, try to start it. if the framework has finished auto-starting.
if (!PackageAdminServiceTracker.INSTANCE.frameworkHasCompletedAutostarts())
{
if (_pendingBundlesToStart == null)
{
_pendingBundlesToStart = new HashSet<Bundle>();
}
_pendingBundlesToStart.add(b);
return null;
}
else
{
b.start();
}
}
return b;
}
catch (BundleException e)
{
Log.warn("Unable to " + (start? "start":"install") + " the bundle " + file.getAbsolutePath(), e);
}
return null;
}
protected void uninstallBundle(File file)
{
try
{
Bundle b = getBundle(JettyBootstrapActivator.getBundleContext(), file.toURI().toString());
b.stop();
b.uninstall();
}
catch (BundleException e)
{
Log.warn("Unable to uninstall the bundle " + file.getAbsolutePath(), e);
}
}
protected void updateBundle(File file)
{
try
{
Bundle b = getBundle(JettyBootstrapActivator.getBundleContext(), file.toURI().toString());
if (b == null)
{
installBundle(file, true);
}
else if (b.getState() == Bundle.ACTIVE)
{
b.update();
}
else
{
b.start();
}
}
catch (BundleException e)
{
Log.warn("Unable to update the bundle " + file.getAbsolutePath(), e);
}
}
} }
/**
* At the end of each scan, if there are some bundles to be started,
* look if the framework has completed its autostart. In that case start those bundles.
*/
class AutoStartWhenFrameworkHasCompleted implements Scanner.ScanCycleListener
{
private final OSGiAppProvider _appProvider;
AutoStartWhenFrameworkHasCompleted(OSGiAppProvider appProvider)
{
_appProvider = appProvider;
}
public void scanStarted(int cycle) throws Exception
{
}
public void scanEnded(int cycle) throws Exception
{
if (_appProvider._pendingBundlesToStart != null && PackageAdminServiceTracker.INSTANCE.frameworkHasCompletedAutostarts())
{
Iterator<Bundle> it = _appProvider._pendingBundlesToStart.iterator();
while (it.hasNext())
{
Bundle b = it.next();
if (b.getHeaders().get(Constants.FRAGMENT_HOST) != null)
{
continue;
}
try
{
b.start();
}
catch (BundleException e)
{
Log.warn("Unable to start the bundle " + b.getLocation(), e);
}
}
_appProvider._pendingBundlesToStart = null;
}
}
}

View File

@ -5,7 +5,6 @@
// are made available under the terms of the Eclipse Public License v1.0 // are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution. // 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 // The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php // 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.
@ -534,7 +533,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
+ " the fragment '" + frag.getSymbolicName() + "'"); + " the fragment '" + frag.getSymbolicName() + "'");
} }
fragUrl = DefaultFileLocatorHelper.getLocalURL(fragUrl); fragUrl = DefaultFileLocatorHelper.getLocalURL(fragUrl);
String key = patchFragFolder.startsWith("/") ? patchFragFolder.substring(1) : patchFragFolder; String key = fragFolder.startsWith("/") ? fragFolder.substring(1) : fragFolder;
appendedResourcesPath.put(key + ";" + frag.getSymbolicName(), Resource.newResource(fragUrl)); appendedResourcesPath.put(key + ";" + frag.getSymbolicName(), Resource.newResource(fragUrl));
} }
if (patchFragFolder != null) if (patchFragFolder != null)
@ -595,13 +594,23 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
} }
if (resEnum != null && resEnum.hasMoreElements()) if (resEnum != null && resEnum.hasMoreElements())
{ {
if (resfrags == null) URL resourcesEntry = frag.getEntry("/META-INF/resources/");
{ if (resourcesEntry == null)
resfrags = new ArrayList<Resource>(); {
wah.setAttribute(WebInfConfiguration.RESOURCE_URLS, resfrags); //probably we found some fragments to a bundle.
} //those are already contributed.
resfrags.add(Resource.newResource( //so we skip this.
DefaultFileLocatorHelper.getLocalURL(frag.getEntry("/META-INF/resources")))); }
else
{
if (resfrags == null)
{
resfrags = new ArrayList<Resource>();
wah.setAttribute(WebInfConfiguration.RESOURCE_URLS, resfrags);
}
resfrags.add(Resource.newResource(
DefaultFileLocatorHelper.getLocalURL(resourcesEntry)));
}
} }
if (tldEnum != null && tldEnum.hasMoreElements()) if (tldEnum != null && tldEnum.hasMoreElements())
{ {

View File

@ -17,6 +17,7 @@ import java.util.Dictionary;
import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator; import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator;
import org.eclipse.jetty.osgi.boot.OSGiWebappConstants; import org.eclipse.jetty.osgi.boot.OSGiWebappConstants;
import org.eclipse.jetty.util.log.Log;
import org.osgi.framework.Bundle; import org.osgi.framework.Bundle;
import org.osgi.framework.BundleEvent; import org.osgi.framework.BundleEvent;
import org.osgi.util.tracker.BundleTracker; import org.osgi.util.tracker.BundleTracker;
@ -151,7 +152,10 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer {
String contextPath = (String)dic.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH); String contextPath = (String)dic.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH);
if (contextPath == null || !contextPath.startsWith("/")) if (contextPath == null || !contextPath.startsWith("/"))
{ {
throw new IllegalArgumentException(); Log.warn("The manifest header '" + OSGiWebappConstants.JETTY_WAR_FOLDER_PATH +
": " + warFolderRelativePath + "' in the bundle " + bundle.getSymbolicName() +
" is not valid: there is no Web-ContextPath defined in the manifest.");
return false;
} }
// create the corresponding service and publish it in the context of // create the corresponding service and publish it in the context of
// the contributor bundle. // the contributor bundle.
@ -162,8 +166,7 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer {
} }
catch (Throwable e) catch (Throwable e)
{ {
// TODO Auto-generated catch block Log.warn("Starting the web-bundle " + bundle.getSymbolicName() + " threw an exception.", e);
e.printStackTrace();
return true;//maybe it did not work maybe it did. safer to track this bundle. return true;//maybe it did not work maybe it did. safer to track this bundle.
} }
} }

View File

@ -285,6 +285,7 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
return (URL)BUNDLE_URL_CONNECTION_getLocalURL.invoke(conn, null); return (URL)BUNDLE_URL_CONNECTION_getLocalURL.invoke(conn, null);
} }
} catch (Throwable t) { } catch (Throwable t) {
System.err.println("Unable to locate the OSGi url: '" + url + "'.");
t.printStackTrace(); t.printStackTrace();
} }
} }

View File

@ -13,9 +13,9 @@
package org.eclipse.jetty.osgi.boot.utils.internal; package org.eclipse.jetty.osgi.boot.utils.internal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Map;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import org.osgi.framework.Bundle; import org.osgi.framework.Bundle;
@ -26,11 +26,11 @@ import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener; import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceReference;
import org.osgi.service.packageadmin.PackageAdmin; import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.service.startlevel.StartLevel;
/** /**
* When the PackageAdmin service is activated we can look for the fragments * When the PackageAdmin service is activated we can look for the fragments
* attached to this bundle and "activate" them. * attached to this bundle and "activate" them.
*
*/ */
public class PackageAdminServiceTracker implements ServiceListener public class PackageAdminServiceTracker implements ServiceListener
{ {
@ -38,6 +38,9 @@ public class PackageAdminServiceTracker implements ServiceListener
private List<BundleActivator> _activatedFragments = new ArrayList<BundleActivator>(); private List<BundleActivator> _activatedFragments = new ArrayList<BundleActivator>();
private boolean _fragmentsWereActivated = false; private boolean _fragmentsWereActivated = false;
//Use the deprecated StartLevel to stay compatible with older versions of OSGi.
private StartLevel _startLevel;
private int _maxStartLevel = 6;
public static PackageAdminServiceTracker INSTANCE = null; public static PackageAdminServiceTracker INSTANCE = null;
public PackageAdminServiceTracker(BundleContext context) public PackageAdminServiceTracker(BundleContext context)
@ -66,6 +69,21 @@ public class PackageAdminServiceTracker implements ServiceListener
_fragmentsWereActivated = sr != null; _fragmentsWereActivated = sr != null;
if (sr != null) if (sr != null)
invokeFragmentActivators(sr); invokeFragmentActivators(sr);
sr = _context.getServiceReference(StartLevel.class.getName());
if (sr != null)
{
_startLevel = (StartLevel)_context.getService(sr);
try
{
_maxStartLevel = Integer.parseInt(System.getProperty("osgi.startLevel","6"));
}
catch (Exception e)
{
//nevermind default on the usual.
_maxStartLevel = 6;
}
}
return _fragmentsWereActivated; return _fragmentsWereActivated;
} }
@ -105,8 +123,9 @@ public class PackageAdminServiceTracker implements ServiceListener
} }
/** /**
* Returns the fragments and the required-bundles that have a jetty-web annotation attribute * Returns the fragments and the required-bundles of a bundle.
* compatible with the webFragOrAnnotationOrResources. * Recursively collect the required-bundles and fragment when the directive visibility:=reexport
* is added to a required-bundle.
* @param bundle * @param bundle
* @param webFragOrAnnotationOrResources * @param webFragOrAnnotationOrResources
* @return * @return
@ -119,60 +138,50 @@ public class PackageAdminServiceTracker implements ServiceListener
return null; return null;
} }
PackageAdmin admin = (PackageAdmin)_context.getService(sr); PackageAdmin admin = (PackageAdmin)_context.getService(sr);
LinkedHashMap<String,Bundle> deps = new LinkedHashMap<String,Bundle>();
collectFragmentsAndRequiredBundles(bundle, admin, deps, false);
return deps.values().toArray(new Bundle[deps.size()]);
}
/**
* Returns the fragments and the required-bundles. Collects them transitively when the directive 'visibility:=reexport'
* is added to a required-bundle.
* @param bundle
* @param webFragOrAnnotationOrResources
* @return
*/
protected void collectFragmentsAndRequiredBundles(Bundle bundle, PackageAdmin admin, Map<String,Bundle> deps, boolean onlyReexport)
{
Bundle[] fragments = admin.getFragments(bundle); Bundle[] fragments = admin.getFragments(bundle);
//get the required bundles. we can't use the org.osgi.framework.wiring package
//just yet: it is not supported by enough osgi implementations.
List<Bundle> requiredBundles = getRequiredBundles(bundle, admin);
if (fragments != null) if (fragments != null)
{ {
Set<String> already = new HashSet<String>();
for (Bundle b : requiredBundles)
{
already.add(b.getSymbolicName());
}
//Also add the bundles required by the fragments. //Also add the bundles required by the fragments.
//this way we can inject onto an existing web-bundle a set of bundles that extend it //this way we can inject onto an existing web-bundle a set of bundles that extend it
for (Bundle f : fragments) for (Bundle f : fragments)
{ {
List<Bundle> requiredBundlesByFragment = getRequiredBundles(f, admin); if (!deps.keySet().contains(f.getSymbolicName()))
for (Bundle b : requiredBundlesByFragment)
{ {
if (already.add(b.getSymbolicName())) deps.put(f.getSymbolicName(), f);
{ collectRequiredBundles(f, admin, deps, onlyReexport);
requiredBundles.add(b);
}
} }
} }
} }
ArrayList<Bundle> bundles = new ArrayList<Bundle>( collectRequiredBundles(bundle, admin, deps, onlyReexport);
(fragments != null ? fragments.length : 0) +
(requiredBundles != null ? requiredBundles.size() : 0));
if (fragments != null)
{
for (Bundle f : fragments)
{
bundles.add(f);
}
}
if (requiredBundles != null)
{
bundles.addAll(requiredBundles);
}
return bundles.toArray(new Bundle[bundles.size()]);
} }
/** /**
* A simplistic but good enough parser for the Require-Bundle header. * A simplistic but good enough parser for the Require-Bundle header.
* Parses the version range attribute and the visibility directive.
*
* @param onlyReexport true to collect resources and web-fragments transitively if and only if the directive visibility is reexport.
* @param bundle * @param bundle
* @return The map of required bundles associated to the value of the jetty-web attribute. * @return The map of required bundles associated to the value of the jetty-web attribute.
*/ */
protected List<Bundle> getRequiredBundles(Bundle bundle, PackageAdmin admin) protected void collectRequiredBundles(Bundle bundle, PackageAdmin admin, Map<String,Bundle> deps, boolean onlyReexport)
{ {
List<Bundle> res = new ArrayList<Bundle>();
String requiredBundleHeader = (String)bundle.getHeaders().get("Require-Bundle"); String requiredBundleHeader = (String)bundle.getHeaders().get("Require-Bundle");
if (requiredBundleHeader == null) if (requiredBundleHeader == null)
{ {
return res; return;
} }
StringTokenizer tokenizer = new StringTokenizer(requiredBundleHeader, ","); StringTokenizer tokenizer = new StringTokenizer(requiredBundleHeader, ",");
while (tokenizer.hasMoreTokens()) while (tokenizer.hasMoreTokens())
@ -180,7 +189,13 @@ public class PackageAdminServiceTracker implements ServiceListener
String tok = tokenizer.nextToken().trim(); String tok = tokenizer.nextToken().trim();
StringTokenizer tokenizer2 = new StringTokenizer(tok, ";"); StringTokenizer tokenizer2 = new StringTokenizer(tok, ";");
String symbolicName = tokenizer2.nextToken().trim(); String symbolicName = tokenizer2.nextToken().trim();
if (deps.keySet().contains(symbolicName))
{
//was already added. 2 dependencies pointing at the same bundle.
continue;
}
String versionRange = null; String versionRange = null;
boolean reexport = false;
while (tokenizer2.hasMoreTokens()) while (tokenizer2.hasMoreTokens())
{ {
String next = tokenizer2.nextToken().trim(); String next = tokenizer2.nextToken().trim();
@ -195,21 +210,37 @@ public class PackageAdminServiceTracker implements ServiceListener
versionRange = next.substring("bundle-version=".length()); versionRange = next.substring("bundle-version=".length());
} }
} }
else if (next.equals("visibility:=reexport"))
{
reexport = true;
}
}
if (!reexport && onlyReexport)
{
return;
} }
Bundle[] reqBundles = admin.getBundles(symbolicName, versionRange); Bundle[] reqBundles = admin.getBundles(symbolicName, versionRange);
if (reqBundles != null) if (reqBundles != null && reqBundles.length != 0)
{ {
Bundle reqBundle = null;
for (Bundle b : reqBundles) for (Bundle b : reqBundles)
{ {
if (b.getState() == Bundle.ACTIVE || b.getState() == Bundle.STARTING) if (b.getState() == Bundle.ACTIVE || b.getState() == Bundle.STARTING)
{ {
res.add(b); reqBundle = b;
break; break;
} }
} }
if (reqBundle == null)
{
//strange? in OSGi with Require-Bundle,
//the dependent bundle is supposed to be active already
reqBundle = reqBundles[0];
}
deps.put(reqBundle.getSymbolicName(),reqBundle);
collectFragmentsAndRequiredBundles(reqBundle, admin, deps, true);
} }
} }
return res;
} }
@ -273,6 +304,14 @@ public class PackageAdminServiceTracker implements ServiceListener
} }
} }
} }
/**
* @return true if the framework has completed all the start levels.
*/
public boolean frameworkHasCompletedAutostarts()
{
return _startLevel == null ? true : _startLevel.getStartLevel() >= _maxStartLevel;
}
} }

View File

@ -59,6 +59,7 @@ public class JettyPolicyRuntimeTest
@Test @Test
public void testSimplePolicyReplacement() throws Exception public void testSimplePolicyReplacement() throws Exception
{ {
Assume.assumeTrue(!OS.IS_WINDOWS); // Ignore test if running under windows.
JettyPolicy ap = new JettyPolicy(MavenTestingUtils.getTestResourceDir("runtime-test-1").getAbsolutePath(), evaluator); JettyPolicy ap = new JettyPolicy(MavenTestingUtils.getTestResourceDir("runtime-test-1").getAbsolutePath(), evaluator);
ap.refresh(); ap.refresh();
@ -73,6 +74,7 @@ public class JettyPolicyRuntimeTest
@Test @Test
public void testRepeatedPolicyReplacement() throws Exception public void testRepeatedPolicyReplacement() throws Exception
{ {
Assume.assumeTrue(!OS.IS_WINDOWS); // Ignore test if running under windows.
JettyPolicy ap = new JettyPolicy(MavenTestingUtils.getTestResourceDir("runtime-test-2/a").getAbsolutePath(),evaluator); JettyPolicy ap = new JettyPolicy(MavenTestingUtils.getTestResourceDir("runtime-test-2/a").getAbsolutePath(),evaluator);
ap.refresh(); ap.refresh();

View File

@ -18,12 +18,13 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.PathMap; import org.eclipse.jetty.http.PathMap;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.URIUtil;
/** /**
* Rewrite the URI by replacing the matched {@link PathMap} path with a fixed string. * Rewrite the URI by replacing the matched {@link PathMap} path with a fixed string.
*/ */
public class RewritePatternRule extends PatternRule public class RewritePatternRule extends PatternRule implements Rule.ApplyURI
{ {
private String _replacement; private String _replacement;
@ -56,6 +57,13 @@ public class RewritePatternRule extends PatternRule
return target; return target;
} }
/* ------------------------------------------------------------ */
public void applyURI(Request request, String oldTarget, String newTarget) throws IOException
{
String uri = URIUtil.addPaths(_replacement, PathMap.pathInfo(_pattern,request.getRequestURI()));
request.setRequestURI(uri);
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Returns the replacement string. * Returns the replacement string.

View File

@ -18,11 +18,13 @@ import java.util.regex.Matcher;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Request;
/** /**
* Rewrite the URI by matching with a regular expression. * Rewrite the URI by matching with a regular expression.
* The replacement string may use $n" to replace the nth capture group. * The replacement string may use $n" to replace the nth capture group.
*/ */
public class RewriteRegexRule extends RegexRule public class RewriteRegexRule extends RegexRule implements Rule.ApplyURI
{ {
private String _replacement; private String _replacement;
@ -61,6 +63,25 @@ public class RewriteRegexRule extends RegexRule
return target; return target;
} }
/* ------------------------------------------------------------ */
public void applyURI(Request request, String oldTarget, String newTarget) throws IOException
{
Matcher matcher=_regex.matcher(request.getRequestURI());
boolean matches = matcher.matches();
if (matches)
{
String uri=_replacement;
for (int g=1;g<=matcher.groupCount();g++)
{
String group = matcher.group(g);
uri=uri.replaceAll("\\$"+g,group);
}
request.setRequestURI(uri);
}
else
request.setRequestURI(newTarget);
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Returns the replacement string. * Returns the replacement string.

View File

@ -17,11 +17,21 @@ import java.io.IOException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Request;
/** /**
* An abstract rule for creating rewrite rules. * An abstract rule for creating rewrite rules.
*/ */
public abstract class Rule public abstract class Rule
{ {
/**
* Interface used to apply a changed target if {@link RuleContainer#setRewriteRequestURI(boolean)} is true.
*/
public interface ApplyURI
{
void applyURI(Request request, String oldTarget, String newTarget) throws IOException;
}
protected boolean _terminating; protected boolean _terminating;
protected boolean _handling; protected boolean _handling;

View File

@ -203,9 +203,14 @@ public class RuleContainer extends Rule
original_set=true; original_set=true;
request.setAttribute(_originalPathAttribute, target); request.setAttribute(_originalPathAttribute, target);
} }
if (_rewriteRequestURI) if (_rewriteRequestURI)
((Request)request).setRequestURI(applied); {
if (rule instanceof Rule.ApplyURI && !target.equals(request.getRequestURI()))
((Rule.ApplyURI)rule).applyURI((Request)request, target, applied);
else
((Request)request).setRequestURI(applied);
}
if (_rewritePathInfo) if (_rewritePathInfo)
((Request)request).setPathInfo(applied); ((Request)request).setPathInfo(applied);

View File

@ -31,6 +31,7 @@ public class RewriteHandlerTest extends AbstractRuleTestCase
private RewritePatternRule _rule1; private RewritePatternRule _rule1;
private RewritePatternRule _rule2; private RewritePatternRule _rule2;
private RewritePatternRule _rule3; private RewritePatternRule _rule3;
private RewriteRegexRule _rule4;
@Before @Before
public void init() throws Exception public void init() throws Exception
@ -58,8 +59,11 @@ public class RewriteHandlerTest extends AbstractRuleTestCase
_rule3 = new RewritePatternRule(); _rule3 = new RewritePatternRule();
_rule3.setPattern("/ccc/*"); _rule3.setPattern("/ccc/*");
_rule3.setReplacement("/ddd"); _rule3.setReplacement("/ddd");
_rule4 = new RewriteRegexRule();
_rule4.setRegex("/xxx/(.*)");
_rule4.setReplacement("/$1/zzz");
_handler.setRules(new Rule[]{_rule1,_rule2,_rule3}); _handler.setRules(new Rule[]{_rule1,_rule2,_rule3,_rule4});
start(false); start(false);
} }
@ -136,4 +140,38 @@ public class RewriteHandlerTest extends AbstractRuleTestCase
assertEquals("/aaa/bar",_request.getAttribute("before")); assertEquals("/aaa/bar",_request.getAttribute("before"));
assertTrue(_request.isHandled()); assertTrue(_request.isHandled());
} }
public void testEncodedPattern() throws Exception
{
_response.setStatus(200);
_request.setHandled(false);
_handler.setOriginalPathAttribute("/before");
_handler.setRewriteRequestURI(true);
_handler.setRewritePathInfo(false);
_request.setRequestURI("/ccc/x%2Fy");
_request.setPathInfo("/ccc/x/y");
_handler.handle("/ccc/x/y",_request,_request, _response);
assertEquals(201,_response.getStatus());
assertEquals("/ddd/x/y",_request.getAttribute("target"));
assertEquals("/ddd/x%2Fy",_request.getAttribute("URI"));
assertEquals("/ccc/x/y",_request.getAttribute("info"));
}
public void testEncodedRegex() throws Exception
{
_response.setStatus(200);
_request.setHandled(false);
_handler.setOriginalPathAttribute("/before");
_handler.setRewriteRequestURI(true);
_handler.setRewritePathInfo(false);
_request.setRequestURI("/xxx/x%2Fy");
_request.setPathInfo("/xxx/x/y");
_handler.handle("/xxx/x/y",_request,_request, _response);
assertEquals(201,_response.getStatus());
assertEquals("/x/y/zzz",_request.getAttribute("target"));
assertEquals("/x%2Fy/zzz",_request.getAttribute("URI"));
assertEquals("/xxx/x/y",_request.getAttribute("info"));
}
} }

View File

@ -149,15 +149,18 @@ public class Response implements HttpServletResponse
if (sessionManager==null) if (sessionManager==null)
return url; return url;
HttpURI uri = null;
if (sessionManager.isCheckingRemoteSessionIdEncoding() && URIUtil.hasScheme(url)) if (sessionManager.isCheckingRemoteSessionIdEncoding() && URIUtil.hasScheme(url))
{ {
HttpURI uri = new HttpURI(url); uri = new HttpURI(url);
String path = uri.getPath();
path = (path == null?"":path);
int port=uri.getPort(); int port=uri.getPort();
if (port<0) if (port<0)
port = HttpSchemes.HTTPS.equalsIgnoreCase(uri.getScheme())?443:80; port = HttpSchemes.HTTPS.equalsIgnoreCase(uri.getScheme())?443:80;
if (!request.getServerName().equalsIgnoreCase(uri.getHost()) || if (!request.getServerName().equalsIgnoreCase(uri.getHost()) ||
request.getServerPort()!=port || request.getServerPort()!=port ||
!uri.getPath().startsWith(request.getContextPath())) !path.startsWith(request.getContextPath())) //TODO the root context path is "", with which every non null string starts
return url; return url;
} }
@ -198,6 +201,10 @@ public class Response implements HttpServletResponse
String id=sessionManager.getNodeId(session); String id=sessionManager.getNodeId(session);
if (uri == null)
uri = new HttpURI(url);
// Already encoded // Already encoded
int prefix=url.indexOf(sessionURLPrefix); int prefix=url.indexOf(sessionURLPrefix);
if (prefix!=-1) if (prefix!=-1)
@ -216,9 +223,16 @@ public class Response implements HttpServletResponse
int suffix=url.indexOf('?'); int suffix=url.indexOf('?');
if (suffix<0) if (suffix<0)
suffix=url.indexOf('#'); suffix=url.indexOf('#');
if (suffix<0) if (suffix<0)
return url+sessionURLPrefix+id; {
return url+
((HttpSchemes.HTTPS.equalsIgnoreCase(uri.getScheme()) || HttpSchemes.HTTP.equalsIgnoreCase(uri.getScheme())) && uri.getPath()==null?"/":"") + //if no path, insert the root path
sessionURLPrefix+id;
}
return url.substring(0,suffix)+ return url.substring(0,suffix)+
((HttpSchemes.HTTPS.equalsIgnoreCase(uri.getScheme()) || HttpSchemes.HTTP.equalsIgnoreCase(uri.getScheme())) && uri.getPath()==null?"/":"")+ //if no path so insert the root path
sessionURLPrefix+id+url.substring(suffix); sessionURLPrefix+id+url.substring(suffix);
} }
@ -1037,12 +1051,7 @@ public class Response implements HttpServletResponse
public void fwdReset() public void fwdReset()
{ {
resetBuffer(); resetBuffer();
_mimeType=null;
_cachedMimeType=null;
_contentType=null;
_characterEncoding=null;
_explicitEncoding=false;
_locale=null;
_outputState=NONE; _outputState=NONE;
_writer=null; _writer=null;
} }

View File

@ -0,0 +1,306 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// 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.server.handler;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.continuation.Continuation;
import org.eclipse.jetty.continuation.ContinuationListener;
import org.eclipse.jetty.continuation.ContinuationSupport;
import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.http.gzip.GzipResponseWrapper;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.log.Log;
/* ------------------------------------------------------------ */
/**
* GZIP Handler This handler will gzip the content of a response if:
* <ul>
* <li>The filter is mapped to a matching path</li>
* <li>The response status code is >=200 and <300
* <li>The content length is unknown or more than the <code>minGzipSize</code> initParameter or the minGzipSize is 0(default)</li>
* <li>The content-type is in the comma separated list of mimeTypes set in the <code>mimeTypes</code> initParameter or if no mimeTypes are defined the
* content-type is not "application/gzip"</li>
* <li>No content-encoding is specified by the resource</li>
* </ul>
*
* <p>
* Compressing the content can greatly improve the network bandwidth usage, but at a cost of memory and CPU cycles. If this handler is used for static content,
* then use of efficient direct NIO may be prevented, thus use of the gzip mechanism of the {@link org.eclipse.jetty.servlet.DefaultServlet} is advised instead.
* </p>
*/
public class GzipHandler extends HandlerWrapper
{
protected Set<String> _mimeTypes;
protected Set<String> _excluded;
protected int _bufferSize = 8192;
protected int _minGzipSize = 256;
/* ------------------------------------------------------------ */
/**
* Instantiates a new gzip handler.
*/
public GzipHandler()
{
}
/* ------------------------------------------------------------ */
/**
* Get the mime types.
*
* @return mime types to set
*/
public Set<String> getMimeTypes()
{
return _mimeTypes;
}
/* ------------------------------------------------------------ */
/**
* Set the mime types.
*
* @param mimeTypes
* the mime types to set
*/
public void setMimeTypes(Set<String> mimeTypes)
{
_mimeTypes = mimeTypes;
}
/* ------------------------------------------------------------ */
/**
* Set the mime types.
*
* @param mimeTypes
* the mime types to set
*/
public void setMimeTypes(String mimeTypes)
{
if (mimeTypes != null)
{
_mimeTypes = new HashSet<String>();
StringTokenizer tok = new StringTokenizer(mimeTypes,",",false);
while (tok.hasMoreTokens())
{
_mimeTypes.add(tok.nextToken());
}
}
}
/* ------------------------------------------------------------ */
/**
* Get the excluded user agents.
*
* @return excluded user agents
*/
public Set<String> getExcluded()
{
return _excluded;
}
/* ------------------------------------------------------------ */
/**
* Set the excluded user agents.
*
* @param excluded
* excluded user agents to set
*/
public void setExcluded(Set<String> excluded)
{
_excluded = excluded;
}
/* ------------------------------------------------------------ */
/**
* Set the excluded user agents.
*
* @param excluded
* excluded user agents to set
*/
public void setExcluded(String excluded)
{
if (excluded != null)
{
_excluded = new HashSet<String>();
StringTokenizer tok = new StringTokenizer(excluded,",",false);
while (tok.hasMoreTokens())
_excluded.add(tok.nextToken());
}
}
/* ------------------------------------------------------------ */
/**
* Get the buffer size.
*
* @return the buffer size
*/
public int setBufferSize()
{
return _bufferSize;
}
/* ------------------------------------------------------------ */
/**
* Set the buffer size.
*
* @param bufferSize
* buffer size to set
*/
public void setBufferSize(int bufferSize)
{
_bufferSize = bufferSize;
}
/* ------------------------------------------------------------ */
/**
* Get the minimum reponse size.
*
* @return minimum reponse size
*/
public int getMinGzipSize()
{
return _minGzipSize;
}
/* ------------------------------------------------------------ */
/**
* Set the minimum reponse size.
*
* @param minGzipSize
* minimum reponse size
*/
public void setMinGzipSize(int minGzipSize)
{
_minGzipSize = minGzipSize;
}
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.server.handler.HandlerWrapper#handle(java.lang.String, org.eclipse.jetty.server.Request, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
if (_handler!=null && isStarted())
{
String ae = request.getHeader("accept-encoding");
if (ae != null && ae.indexOf("gzip")>=0 && !response.containsHeader("Content-Encoding")
&& !HttpMethods.HEAD.equalsIgnoreCase(request.getMethod()))
{
if (_excluded!=null)
{
String ua = request.getHeader("User-Agent");
if (_excluded.contains(ua))
{
_handler.handle(target,baseRequest, request, response);
return;
}
}
final GzipResponseWrapper wrappedResponse = newGzipResponseWrapper(request,response);
boolean exceptional=true;
try
{
_handler.handle(target, baseRequest, request, wrappedResponse);
exceptional=false;
}
finally
{
Continuation continuation = ContinuationSupport.getContinuation(request);
if (continuation.isSuspended() && continuation.isResponseWrapped())
{
continuation.addContinuationListener(new ContinuationListener()
{
public void onComplete(Continuation continuation)
{
try
{
wrappedResponse.finish();
}
catch(IOException e)
{
Log.warn(e);
}
}
public void onTimeout(Continuation continuation)
{}
});
}
else if (exceptional && !response.isCommitted())
{
wrappedResponse.resetBuffer();
wrappedResponse.noGzip();
}
else
wrappedResponse.finish();
}
}
else
{
_handler.handle(target,baseRequest, request, response);
}
}
}
/**
* Allows derived implementations to replace ResponseWrapper implementation.
*
* @param request the request
* @param response the response
* @return the gzip response wrapper
*/
protected GzipResponseWrapper newGzipResponseWrapper(HttpServletRequest request, HttpServletResponse response)
{
return new GzipResponseWrapper(request, response)
{
{
_mimeTypes = GzipHandler.this._mimeTypes;
_bufferSize = GzipHandler.this._bufferSize;
_minGzipSize = GzipHandler.this._minGzipSize;
}
@Override
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
{
return GzipHandler.this.newWriter(out,encoding);
}
};
}
/**
* Allows derived implementations to replace PrintWriter implementation.
*
* @param out the out
* @param encoding the encoding
* @return the prints the writer
* @throws UnsupportedEncodingException
*/
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
{
return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
}
}

View File

@ -102,17 +102,6 @@ public class SelectChannelConnector extends AbstractNIOConnector
{ {
synchronized(this) synchronized(this)
{ {
if(_manager.isRunning())
{
try
{
_manager.stop();
}
catch (Exception e)
{
Log.warn(e);
}
}
if (_acceptChannel != null) if (_acceptChannel != null)
_acceptChannel.close(); _acceptChannel.close();
_acceptChannel = null; _acceptChannel = null;
@ -297,6 +286,20 @@ public class SelectChannelConnector extends AbstractNIOConnector
@Override @Override
protected void doStop() throws Exception protected void doStop() throws Exception
{ {
synchronized(this)
{
if(_manager.isRunning())
{
try
{
_manager.stop();
}
catch (Exception e)
{
Log.warn(e);
}
}
}
super.doStop(); super.doStop();
} }

View File

@ -496,11 +496,13 @@ public class JDBCSessionManager extends AbstractSessionManager
if (Log.isDebugEnabled()) if (Log.isDebugEnabled())
{ {
if (session==null) if (session==null)
Log.debug("now="+now+ Log.debug("getSession("+idInCluster+"): not in session map,"+
" now="+now+
" lastSaved="+(session==null?0:session._data._lastSaved)+ " lastSaved="+(session==null?0:session._data._lastSaved)+
" interval="+(_saveIntervalSec * 1000)); " interval="+(_saveIntervalSec * 1000));
else else
Log.debug("now="+now+ Log.debug("getSession("+idInCluster+"): in session map, "+
" now="+now+
" lastSaved="+(session==null?0:session._data._lastSaved)+ " lastSaved="+(session==null?0:session._data._lastSaved)+
" interval="+(_saveIntervalSec * 1000)+ " interval="+(_saveIntervalSec * 1000)+
" lastNode="+session._data.getLastNode()+ " lastNode="+session._data.getLastNode()+
@ -510,16 +512,17 @@ public class JDBCSessionManager extends AbstractSessionManager
if (session==null || ((now - session._data._lastSaved) >= (_saveIntervalSec * 1000))) if (session==null || ((now - session._data._lastSaved) >= (_saveIntervalSec * 1000)))
{ {
Log.debug("no session ",idInCluster); 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)); data = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context));
} }
else if ((now - session._data._lastSaved) >= (_saveIntervalSec * 1000)) else if ((now - session._data._lastSaved) >= (_saveIntervalSec * 1000))
{ {
Log.debug("old session",idInCluster); Log.debug("getSession("+idInCluster+"): stale session. Reloading session data from db.");
data = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context)); data = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context));
} }
else else
{ {
Log.debug("getSession("+idInCluster+"): session in session map");
data = session._data; data = session._data;
} }
@ -527,10 +530,11 @@ public class JDBCSessionManager extends AbstractSessionManager
{ {
if (!data.getLastNode().equals(getIdManager().getWorkerName()) || session==null) if (!data.getLastNode().equals(getIdManager().getWorkerName()) || session==null)
{ {
//if the session in the database has not already expired //if the session has no expiry, or it is not already expired
if (data._expiryTime > now) if (data._expiryTime <= 0 || data._expiryTime > now)
{ {
Log.debug("expired session",idInCluster); Log.debug("getSession("+idInCluster+"): lastNode="+data.getLastNode()+" thisNode="+getIdManager().getWorkerName());
data.setLastNode(getIdManager().getWorkerName());
//session last used on a different node, or we don't have it in memory //session last used on a different node, or we don't have it in memory
session = new Session(now,data); session = new Session(now,data);
_sessions.put(idInCluster, session); _sessions.put(idInCluster, session);
@ -539,16 +543,19 @@ public class JDBCSessionManager extends AbstractSessionManager
//the _dirty flag? //the _dirty flag?
updateSessionNode(data); updateSessionNode(data);
} }
else
if (Log.isDebugEnabled()) Log.debug("getSession("+idInCluster+"): Session has expired");
} }
else else
if (Log.isDebugEnabled()) Log.debug("Session not stale "+session._data); if (Log.isDebugEnabled()) Log.debug("getSession("+idInCluster+"): Session not stale "+session._data);
//session in db shares same id, but is not for this context //session in db shares same id, but is not for this context
} }
else else
{ {
//No session in db with matching id and context path. //No session in db with matching id and context path.
session=null; session=null;
if (Log.isDebugEnabled()) Log.debug("No session in database matching id="+idInCluster); if (Log.isDebugEnabled()) Log.debug("getSession("+idInCluster+"): No session in database matching id="+idInCluster);
} }
return session; return session;

View File

@ -564,28 +564,19 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements
*/ */
protected SSLEngine createSSLEngine(SocketChannel channel) throws IOException protected SSLEngine createSSLEngine(SocketChannel channel) throws IOException
{ {
try SSLEngine engine;
if (channel != null && _sslContextFactory.isSessionCachingEnabled())
{ {
SSLEngine engine; String peerHost = channel.socket().getInetAddress().getHostAddress();
if (channel != null && _sslContextFactory.isSessionCachingEnabled()) int peerPort = channel.socket().getPort();
{ engine = _sslContextFactory.getSslContext().createSSLEngine(peerHost, peerPort);
String peerHost = channel.socket().getInetAddress().getHostAddress();
int peerPort = channel.socket().getPort();
engine = _sslContextFactory.getSslContext().createSSLEngine(peerHost, peerPort);
}
else
{
engine = _sslContextFactory.getSslContext().createSSLEngine();
}
customizeEngine(engine);
return engine;
} }
catch (Exception x) else
{ {
Log.warn("Error creating SSLEngine -- closing this connector", x); engine = _sslContextFactory.getSslContext().createSSLEngine();
close();
throw new IllegalStateException(x);
} }
customizeEngine(engine);
return engine;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */

View File

@ -0,0 +1,29 @@
// ========================================================================
// 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.server;
import org.eclipse.jetty.server.nio.BlockingChannelConnector;
import org.junit.BeforeClass;
/**
* HttpServer Tester.
*/
public class BlockingChannelCloseTest extends HttpServerTestBase
{
@BeforeClass
public static void init() throws Exception
{
startServer(new BlockingChannelConnector());
}
}

View File

@ -0,0 +1,232 @@
//========================================================================
//Copyright (c) Webtide LLC
//------------------------------------------------------------------------
//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.apache.org/licenses/LICENSE-2.0.txt
//
//You may elect to redistribute this code under either of these licenses.
//========================================================================
package org.eclipse.jetty.server;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.util.StringTokenizer;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.junit.Before;
import org.junit.Test;
/**
* HttpServer Tester.
*/
public abstract class ConnectorCloseTestBase extends HttpServerTestFixture
{
private static String __content =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis felis nunc. "+
"Quisque suscipit mauris et ante auctor ornare rhoncus lacus aliquet. Pellentesque "+
"habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. "+
"Vestibulum sit amet felis augue, vel convallis dolor. Cras accumsan vehicula diam "+
"at faucibus. Etiam in urna turpis, sed congue mi. Morbi et lorem eros. Donec vulputate "+
"velit in risus suscipit lobortis. Aliquam id urna orci, nec sollicitudin ipsum. "+
"Cras a orci turpis. Donec suscipit vulputate cursus. Mauris nunc tellus, fermentum "+
"eu auctor ut, mollis at diam. Quisque porttitor ultrices metus, vitae tincidunt massa "+
"sollicitudin a. Vivamus porttitor libero eget purus hendrerit cursus. Integer aliquam "+
"consequat mauris quis luctus. Cras enim nibh, dignissim eu faucibus ac, mollis nec neque. "+
"Aliquam purus mauris, consectetur nec convallis lacinia, porta sed ante. Suspendisse "+
"et cursus magna. Donec orci enim, molestie a lobortis eu, imperdiet vitae neque.";
private static int __length = __content.length();
private StringBuffer _response;
private boolean _continue;
/* ------------------------------------------------------------ */
@Test
public void testCloseBetweenRequests() throws Exception
{
int total = 0;
_continue = true;
_response = new StringBuffer();
configureServer(new HelloWorldHandler());
Socket client = newSocket(HOST,_connector.getLocalPort());
try
{
OutputStream os = client.getOutputStream();
ResponseReader reader = new ResponseReader(client);
Thread runner = new Thread(reader);
runner.start();
for (int pipeline = 1; pipeline < 32; pipeline++)
{
if (pipeline == 16)
_connector.close();
total += pipeline;
String request = "";
for (int i = 0; i < pipeline; i++)
{
request +=
"GET /data?writes=1&block=16&id="+i+" HTTP/1.1\r\n"+
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
"user-agent: testharness/1.0 (blah foo/bar)\r\n"+
"accept-encoding: nothing\r\n"+
"cookie: aaa=1234567890\r\n"+
"\r\n";
}
os.write(request.getBytes());
os.flush();
Thread.sleep(50);
}
_continue = false;
runner.join();
}
finally
{
client.close();
int count = 0;
StringTokenizer lines = new StringTokenizer(_response.toString(),"\r\n");
while(lines.hasMoreTokens())
{
String line = lines.nextToken();
if (line.equals("HTTP/1.1 200 OK"))
{
++count;
}
}
assertEquals(total, count);
}
}
/* ------------------------------------------------------------ */
@Test
public void testCloseBetweenChunks() throws Exception
{
_continue = true;
_response = new StringBuffer();
configureServer(new EchoHandler());
Socket client = newSocket(HOST,_connector.getLocalPort());
try
{
OutputStream os = client.getOutputStream();
ResponseReader reader = new ResponseReader(client);
Thread runner = new Thread(reader);
runner.start();
String content = "abcdefghij";
byte[] bytes = __content.getBytes("utf-8");
os.write((
"POST /echo?charset=utf-8 HTTP/1.1\r\n"+
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
"content-type: text/plain; charset=utf-8\r\n"+
"content-length: "+bytes.length+"\r\n"+
"\r\n"
).getBytes("iso-8859-1"));
int len = bytes.length;
int offset = 0;
int stop = len / 2;
while (offset < stop)
{
os.write(bytes, offset, 64);
offset += 64;
}
_connector.close();
while (offset < len)
{
os.write(bytes, offset, len-offset <=64 ? len-offset : 64);
offset += 64;
}
os.flush();
Thread.sleep(50);
_continue = false;
runner.join();
String in = _response.toString();
assertTrue(in.indexOf(__content.substring(__length-64))>0);
}
finally
{
client.close();
}
}
/* ------------------------------------------------------------ */
public class ResponseReader implements Runnable
{
private BufferedReader _reader;
/* ------------------------------------------------------------ */
public ResponseReader(Socket client) throws IOException
{
_reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
}
/* ------------------------------------------------------------ */
/**
* @see java.lang.Runnable#run()
*/
public void run()
{
int count = 0;
char[] buffer = new char[256];
try
{
while (_continue)
{
if (_reader.ready())
{
count = _reader.read(buffer);
_response.append(buffer, 0, count);
}
else
{
count = 0;
Thread.sleep(10);
}
}
}
catch (IOException ex) { }
catch (InterruptedException ex) { }
finally
{
try
{
_reader.close();
}
catch (IOException e) { }
}
}
}
}

View File

@ -67,6 +67,7 @@ public class HttpURITest
/*29*/ {"/?x=y",null, null, null,null,"/", null,"x=y",null}, /*29*/ {"/?x=y",null, null, null,null,"/", null,"x=y",null},
/*30*/ {"/?abc=test",null, null, null,null,"/", null,"abc=test",null}, /*30*/ {"/?abc=test",null, null, null,null,"/", null,"abc=test",null},
/*31*/ {"/#fragment",null, null, null,null,"/", null,null,"fragment"}, /*31*/ {"/#fragment",null, null, null,null,"/", null,null,"fragment"},
/*32*/ {"http://localhost:8080", "http", "//localhost:8080", "localhost", "8080", null, null, null, null}
}; };
@Test @Test

View File

@ -348,6 +348,21 @@ public class ResponseTest
assertEquals("http://other:8888/path/info;param?query=0&more=1#target",response.encodeURL("http://other:8888/path/info;param?query=0&more=1#target")); assertEquals("http://other:8888/path/info;param?query=0&more=1#target",response.encodeURL("http://other:8888/path/info;param?query=0&more=1#target"));
assertEquals("http://myhost/path/info;param?query=0&more=1#target",response.encodeURL("http://myhost/path/info;param?query=0&more=1#target")); assertEquals("http://myhost/path/info;param?query=0&more=1#target",response.encodeURL("http://myhost/path/info;param?query=0&more=1#target"));
assertEquals("http://myhost:8888/other/info;param?query=0&more=1#target",response.encodeURL("http://myhost:8888/other/info;param?query=0&more=1#target")); assertEquals("http://myhost:8888/other/info;param?query=0&more=1#target",response.encodeURL("http://myhost:8888/other/info;param?query=0&more=1#target"));
request.setContextPath("");
assertEquals("http://myhost:8888/;jsessionid=12345",response.encodeURL("http://myhost:8888"));
assertEquals("https://myhost:8888/;jsessionid=12345",response.encodeURL("https://myhost:8888"));
assertEquals("mailto:/foo", response.encodeURL("mailto:/foo"));
assertEquals("http://myhost:8888/;jsessionid=12345",response.encodeURL("http://myhost:8888/"));
assertEquals("http://myhost:8888/;jsessionid=12345", response.encodeURL("http://myhost:8888/;jsessionid=7777"));
assertEquals("http://myhost:8888/;param;jsessionid=12345?query=0&more=1#target",response.encodeURL("http://myhost:8888/;param?query=0&more=1#target"));
assertEquals("http://other:8888/path/info;param?query=0&more=1#target",response.encodeURL("http://other:8888/path/info;param?query=0&more=1#target"));
manager.setCheckingRemoteSessionIdEncoding(false);
assertEquals("/foo;jsessionid=12345", response.encodeURL("/foo"));
assertEquals("/;jsessionid=12345", response.encodeURL("/"));
assertEquals("/foo.html;jsessionid=12345#target", response.encodeURL("/foo.html#target"));
assertEquals(";jsessionid=12345", response.encodeURL(""));
} }
@Test @Test

View File

@ -0,0 +1,31 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// 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.server;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.junit.Before;
/* ------------------------------------------------------------ */
public class SelectChannelConnectorCloseTest extends ConnectorCloseTestBase
{
/* ------------------------------------------------------------ */
@Before
public void init() throws Exception
{
System.setProperty("org.eclipse.jetty.util.log.DEBUG","true");
startServer(new SelectChannelConnector());
}
}

View File

@ -0,0 +1,31 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// 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.server;
import org.eclipse.jetty.server.bio.SocketConnector;
import org.junit.Before;
/* ------------------------------------------------------------ */
public class SocketConnectorCloseTest extends ConnectorCloseTestBase
{
/* ------------------------------------------------------------ */
@Before
public void init() throws Exception
{
System.setProperty("org.eclipse.jetty.util.log.DEBUG","true");
startServer(new SocketConnector());
}
}

View File

@ -117,7 +117,8 @@ public class StressTest
@Test @Test
public void testNonPersistent() throws Throwable public void testNonPersistent() throws Throwable
{ {
assumeTrue(!OS.IS_OSX || Stress.isEnabled()); // TODO needs to be further investigated
assumeTrue(!OS.IS_OSX || Stress.isEnabled());
doThreads(10,100,false); doThreads(10,100,false);
if (Stress.isEnabled()) if (Stress.isEnabled())
@ -132,7 +133,8 @@ public class StressTest
@Test @Test
public void testPersistent() throws Throwable public void testPersistent() throws Throwable
{ {
assumeTrue(!OS.IS_OSX || Stress.isEnabled()); // TODO needs to be further investigated
assumeTrue(!OS.IS_OSX || Stress.isEnabled());
doThreads(20,100,true); doThreads(20,100,true);
if (Stress.isEnabled()) if (Stress.isEnabled())

View File

@ -53,6 +53,11 @@
<artifactId>junit</artifactId> <artifactId>junit</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-continuation</artifactId> <artifactId>jetty-continuation</artifactId>

View File

@ -127,7 +127,7 @@ public class CrossOriginFilter implements Filter
allowedMethods.addAll(Arrays.asList(allowedMethodsConfig.split(","))); allowedMethods.addAll(Arrays.asList(allowedMethodsConfig.split(",")));
String allowedHeadersConfig = config.getInitParameter(ALLOWED_HEADERS_PARAM); String allowedHeadersConfig = config.getInitParameter(ALLOWED_HEADERS_PARAM);
if (allowedHeadersConfig == null) allowedHeadersConfig = "X-Requested-With,Content-Type,Accept"; if (allowedHeadersConfig == null) allowedHeadersConfig = "X-Requested-With,Content-Type,Accept,Origin";
allowedHeaders.addAll(Arrays.asList(allowedHeadersConfig.split(","))); allowedHeaders.addAll(Arrays.asList(allowedHeadersConfig.split(",")));
String preflightMaxAgeConfig = config.getInitParameter(PREFLIGHT_MAX_AGE_PARAM); String preflightMaxAgeConfig = config.getInitParameter(PREFLIGHT_MAX_AGE_PARAM);

View File

@ -20,24 +20,20 @@ import java.io.UnsupportedEncodingException;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.zip.GZIPOutputStream;
import javax.servlet.FilterChain; import javax.servlet.FilterChain;
import javax.servlet.FilterConfig; import javax.servlet.FilterConfig;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.eclipse.jetty.continuation.Continuation; import org.eclipse.jetty.continuation.Continuation;
import org.eclipse.jetty.continuation.ContinuationListener; import org.eclipse.jetty.continuation.ContinuationListener;
import org.eclipse.jetty.continuation.ContinuationSupport; import org.eclipse.jetty.continuation.ContinuationSupport;
import org.eclipse.jetty.http.HttpMethods; import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.util.ByteArrayOutputStream2; import org.eclipse.jetty.http.gzip.GzipResponseWrapper;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -65,11 +61,15 @@ import org.eclipse.jetty.util.log.Log;
*/ */
public class GzipFilter extends UserAgentFilter public class GzipFilter extends UserAgentFilter
{ {
protected Set _mimeTypes; protected Set<String> _mimeTypes;
protected int _bufferSize=8192; protected int _bufferSize=8192;
protected int _minGzipSize=256; protected int _minGzipSize=256;
protected Set _excluded; protected Set<String> _excluded;
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.servlets.UserAgentFilter#init(javax.servlet.FilterConfig)
*/
public void init(FilterConfig filterConfig) throws ServletException public void init(FilterConfig filterConfig) throws ServletException
{ {
super.init(filterConfig); super.init(filterConfig);
@ -85,7 +85,7 @@ public class GzipFilter extends UserAgentFilter
tmp=filterConfig.getInitParameter("mimeTypes"); tmp=filterConfig.getInitParameter("mimeTypes");
if (tmp!=null) if (tmp!=null)
{ {
_mimeTypes=new HashSet(); _mimeTypes=new HashSet<String>();
StringTokenizer tok = new StringTokenizer(tmp,",",false); StringTokenizer tok = new StringTokenizer(tmp,",",false);
while (tok.hasMoreTokens()) while (tok.hasMoreTokens())
_mimeTypes.add(tok.nextToken()); _mimeTypes.add(tok.nextToken());
@ -94,17 +94,25 @@ public class GzipFilter extends UserAgentFilter
tmp=filterConfig.getInitParameter("excludedAgents"); tmp=filterConfig.getInitParameter("excludedAgents");
if (tmp!=null) if (tmp!=null)
{ {
_excluded=new HashSet(); _excluded=new HashSet<String>();
StringTokenizer tok = new StringTokenizer(tmp,",",false); StringTokenizer tok = new StringTokenizer(tmp,",",false);
while (tok.hasMoreTokens()) while (tok.hasMoreTokens())
_excluded.add(tok.nextToken()); _excluded.add(tok.nextToken());
} }
} }
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.servlets.UserAgentFilter#destroy()
*/
public void destroy() public void destroy()
{ {
} }
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.servlets.UserAgentFilter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException throws IOException, ServletException
{ {
@ -125,7 +133,7 @@ public class GzipFilter extends UserAgentFilter
} }
} }
final GZIPResponseWrapper wrappedResponse=newGZIPResponseWrapper(request,response); final GzipResponseWrapper wrappedResponse=newGzipResponseWrapper(request,response);
boolean exceptional=true; boolean exceptional=true;
try try
@ -171,436 +179,41 @@ public class GzipFilter extends UserAgentFilter
} }
} }
protected GZIPResponseWrapper newGZIPResponseWrapper(HttpServletRequest request, HttpServletResponse response) /**
* Allows derived implementations to replace ResponseWrapper implementation.
*
* @param request the request
* @param response the response
* @return the gzip response wrapper
*/
protected GzipResponseWrapper newGzipResponseWrapper(HttpServletRequest request, HttpServletResponse response)
{ {
return new GZIPResponseWrapper(request,response); return new GzipResponseWrapper(request, response)
{
{
_mimeTypes = GzipFilter.this._mimeTypes;
_bufferSize = GzipFilter.this._bufferSize;
_minGzipSize = GzipFilter.this._minGzipSize;
}
@Override
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
{
return GzipFilter.this.newWriter(out,encoding);
}
};
} }
/* /**
* Allows derived implementations to replace PrintWriter implementation * Allows derived implementations to replace PrintWriter implementation.
*
* @param out the out
* @param encoding the encoding
* @return the prints the writer
* @throws UnsupportedEncodingException
*/ */
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
{ {
return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding)); return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
} }
public class GZIPResponseWrapper extends HttpServletResponseWrapper
{
HttpServletRequest _request;
boolean _noGzip;
PrintWriter _writer;
GzipStream _gzStream;
long _contentLength=-1;
public GZIPResponseWrapper(HttpServletRequest request, HttpServletResponse response)
{
super(response);
_request=request;
}
public void setContentType(String ct)
{
super.setContentType(ct);
if (ct!=null)
{
int colon=ct.indexOf(";");
if (colon>0)
ct=ct.substring(0,colon);
}
if ((_gzStream==null || _gzStream._out==null) &&
(_mimeTypes==null && "application/gzip".equalsIgnoreCase(ct) ||
_mimeTypes!=null && (ct==null||!_mimeTypes.contains(StringUtil.asciiToLowerCase(ct)))))
{
noGzip();
}
}
public void setStatus(int sc, String sm)
{
super.setStatus(sc,sm);
if (sc<200||sc>=300)
noGzip();
}
public void setStatus(int sc)
{
super.setStatus(sc);
if (sc<200||sc>=300)
noGzip();
}
public void setContentLength(int length)
{
_contentLength=length;
if (_gzStream!=null)
_gzStream.setContentLength(length);
}
public void addHeader(String name, String value)
{
if ("content-length".equalsIgnoreCase(name))
{
_contentLength=Long.parseLong(value);
if (_gzStream!=null)
_gzStream.setContentLength(_contentLength);
}
else if ("content-type".equalsIgnoreCase(name))
{
setContentType(value);
}
else if ("content-encoding".equalsIgnoreCase(name))
{
super.addHeader(name,value);
if (!isCommitted())
{
noGzip();
}
}
else
super.addHeader(name,value);
}
public void setHeader(String name, String value)
{
if ("content-length".equalsIgnoreCase(name))
{
_contentLength=Long.parseLong(value);
if (_gzStream!=null)
_gzStream.setContentLength(_contentLength);
}
else if ("content-type".equalsIgnoreCase(name))
{
setContentType(value);
}
else if ("content-encoding".equalsIgnoreCase(name))
{
super.setHeader(name,value);
if (!isCommitted())
{
noGzip();
}
}
else
super.setHeader(name,value);
}
public void setIntHeader(String name, int value)
{
if ("content-length".equalsIgnoreCase(name))
{
_contentLength=value;
if (_gzStream!=null)
_gzStream.setContentLength(_contentLength);
}
else
super.setIntHeader(name,value);
}
public void flushBuffer() throws IOException
{
if (_writer!=null)
_writer.flush();
if (_gzStream!=null)
_gzStream.finish();
else
getResponse().flushBuffer();
}
public void reset()
{
super.reset();
if (_gzStream!=null)
_gzStream.resetBuffer();
_writer=null;
_gzStream=null;
_noGzip=false;
_contentLength=-1;
}
public void resetBuffer()
{
super.resetBuffer();
if (_gzStream!=null)
_gzStream.resetBuffer();
_writer=null;
_gzStream=null;
}
public void sendError(int sc, String msg) throws IOException
{
resetBuffer();
super.sendError(sc,msg);
}
public void sendError(int sc) throws IOException
{
resetBuffer();
super.sendError(sc);
}
public void sendRedirect(String location) throws IOException
{
resetBuffer();
super.sendRedirect(location);
}
public ServletOutputStream getOutputStream() throws IOException
{
if (_gzStream==null)
{
if (getResponse().isCommitted() || _noGzip)
return getResponse().getOutputStream();
_gzStream=newGzipStream(_request,(HttpServletResponse)getResponse(),_contentLength,_bufferSize,_minGzipSize);
}
else if (_writer!=null)
throw new IllegalStateException("getWriter() called");
return _gzStream;
}
public PrintWriter getWriter() throws IOException
{
if (_writer==null)
{
if (_gzStream!=null)
throw new IllegalStateException("getOutputStream() called");
if (getResponse().isCommitted() || _noGzip)
return getResponse().getWriter();
_gzStream=newGzipStream(_request,(HttpServletResponse)getResponse(),_contentLength,_bufferSize,_minGzipSize);
_writer=newWriter(_gzStream,getCharacterEncoding());
}
return _writer;
}
void noGzip()
{
_noGzip=true;
if (_gzStream!=null)
{
try
{
_gzStream.doNotGzip();
}
catch (IOException e)
{
throw new IllegalStateException(e);
}
}
}
void finish() throws IOException
{
if (_writer!=null && !_gzStream._closed)
_writer.flush();
if (_gzStream!=null)
_gzStream.finish();
}
protected GzipStream newGzipStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minGzipSize) throws IOException
{
return new GzipStream(request,response,contentLength,bufferSize,minGzipSize);
}
}
public static class GzipStream extends ServletOutputStream
{
protected HttpServletRequest _request;
protected HttpServletResponse _response;
protected OutputStream _out;
protected ByteArrayOutputStream2 _bOut;
protected GZIPOutputStream _gzOut;
protected boolean _closed;
protected int _bufferSize;
protected int _minGzipSize;
protected long _contentLength;
public GzipStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minGzipSize) throws IOException
{
_request=request;
_response=response;
_contentLength=contentLength;
_bufferSize=bufferSize;
_minGzipSize=minGzipSize;
if (minGzipSize==0)
doGzip();
}
public void resetBuffer()
{
if (_response.isCommitted())
throw new IllegalStateException("Committed");
_closed=false;
_out=null;
_bOut=null;
if (_gzOut!=null)
_response.setHeader("Content-Encoding",null);
_gzOut=null;
}
public void setContentLength(long length)
{
_contentLength=length;
}
public void flush() throws IOException
{
if (_out==null || _bOut!=null)
{
if (_contentLength>0 && _contentLength<_minGzipSize)
doNotGzip();
else
doGzip();
}
_out.flush();
}
public void close() throws IOException
{
if (_closed)
return;
if (_request.getAttribute("javax.servlet.include.request_uri")!=null)
flush();
else
{
if (_bOut!=null)
{
if (_contentLength<0)
_contentLength=_bOut.getCount();
if (_contentLength<_minGzipSize)
doNotGzip();
else
doGzip();
}
else if (_out==null)
{
doNotGzip();
}
if (_gzOut!=null)
_gzOut.close();
else
_out.close();
_closed=true;
}
}
public void finish() throws IOException
{
if (!_closed)
{
if (_out==null || _bOut!=null)
{
if (_contentLength>0 && _contentLength<_minGzipSize)
doNotGzip();
else
doGzip();
}
if (_gzOut!=null && !_closed)
{
_closed=true;
_gzOut.close();
}
}
}
public void write(int b) throws IOException
{
checkOut(1);
_out.write(b);
}
public void write(byte b[]) throws IOException
{
checkOut(b.length);
_out.write(b);
}
public void write(byte b[], int off, int len) throws IOException
{
checkOut(len);
_out.write(b,off,len);
}
protected boolean setContentEncodingGzip()
{
_response.setHeader("Content-Encoding", "gzip");
return _response.containsHeader("Content-Encoding");
}
public void doGzip() throws IOException
{
if (_gzOut==null)
{
if (_response.isCommitted())
throw new IllegalStateException();
if (setContentEncodingGzip())
{
_out=_gzOut=new GZIPOutputStream(_response.getOutputStream(),_bufferSize);
if (_bOut!=null)
{
_out.write(_bOut.getBuf(),0,_bOut.getCount());
_bOut=null;
}
}
else
doNotGzip();
}
}
public void doNotGzip() throws IOException
{
if (_gzOut!=null)
throw new IllegalStateException();
if (_out==null || _bOut!=null )
{
_out=_response.getOutputStream();
if (_contentLength>=0)
{
if(_contentLength<Integer.MAX_VALUE)
_response.setContentLength((int)_contentLength);
else
_response.setHeader("Content-Length",Long.toString(_contentLength));
}
if (_bOut!=null)
_out.write(_bOut.getBuf(),0,_bOut.getCount());
_bOut=null;
}
}
private void checkOut(int length) throws IOException
{
if (_closed)
throw new IOException("CLOSED");
if (_out==null)
{
if (_response.isCommitted() || (_contentLength>=0 && _contentLength<_minGzipSize))
doNotGzip();
else if (length>_minGzipSize)
doGzip();
else
_out=_bOut=new ByteArrayOutputStream2(_bufferSize);
}
else if (_bOut!=null)
{
if (_response.isCommitted() || (_contentLength>=0 && _contentLength<_minGzipSize))
doNotGzip();
else if (length>=(_bOut.getBuf().length -_bOut.getCount()))
doGzip();
}
}
}
} }

View File

@ -24,6 +24,8 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.gzip.GzipResponseWrapper;
import org.eclipse.jetty.http.gzip.GzipStream;
import org.eclipse.jetty.io.UncheckedPrintWriter; import org.eclipse.jetty.io.UncheckedPrintWriter;
@ -55,16 +57,20 @@ public class IncludableGzipFilter extends GzipFilter
} }
@Override @Override
protected GZIPResponseWrapper newGZIPResponseWrapper(HttpServletRequest request, HttpServletResponse response) protected GzipResponseWrapper newGzipResponseWrapper(HttpServletRequest request, HttpServletResponse response)
{ {
return new IncludableResponseWrapper(request,response); return new IncludableResponseWrapper(request,response);
} }
public class IncludableResponseWrapper extends GzipFilter.GZIPResponseWrapper public class IncludableResponseWrapper extends GzipResponseWrapper
{ {
public IncludableResponseWrapper(HttpServletRequest request, HttpServletResponse response) public IncludableResponseWrapper(HttpServletRequest request, HttpServletResponse response)
{ {
super(request,response); super(request,response);
_mimeTypes = IncludableGzipFilter.this._mimeTypes;
_bufferSize = IncludableGzipFilter.this._bufferSize;
_minGzipSize = IncludableGzipFilter.this._minGzipSize;
} }
@Override @Override
@ -72,9 +78,15 @@ public class IncludableGzipFilter extends GzipFilter
{ {
return new IncludableGzipStream(request,response,contentLength,bufferSize,minGzipSize); return new IncludableGzipStream(request,response,contentLength,bufferSize,minGzipSize);
} }
@Override
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
{
return IncludableGzipFilter.this.newWriter(out,encoding);
}
} }
public class IncludableGzipStream extends GzipFilter.GzipStream public class IncludableGzipStream extends GzipStream
{ {
public IncludableGzipStream(HttpServletRequest request, HttpServletResponse response, long contentLength, int bufferSize, int minGzipSize) public IncludableGzipStream(HttpServletRequest request, HttpServletResponse response, long contentLength, int bufferSize, int minGzipSize)
throws IOException throws IOException
@ -93,7 +105,7 @@ public class IncludableGzipFilter extends GzipFilter
return _response.containsHeader("Content-Encoding"); return _response.containsHeader("Content-Encoding");
} }
} }
@Override @Override
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
{ {

View File

@ -38,6 +38,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.HttpConnection;
import org.eclipse.jetty.client.HttpExchange; import org.eclipse.jetty.client.HttpExchange;
import org.eclipse.jetty.continuation.Continuation; import org.eclipse.jetty.continuation.Continuation;
import org.eclipse.jetty.continuation.ContinuationSupport; import org.eclipse.jetty.continuation.ContinuationSupport;
@ -48,34 +49,40 @@ import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.PathMap; import org.eclipse.jetty.http.PathMap;
import org.eclipse.jetty.io.Buffer; import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.EofException; import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.servlet.Holder;
import org.eclipse.jetty.util.HostMap; import org.eclipse.jetty.util.HostMap;
import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.omg.CORBA._PolicyStub;
/** /**
* Asynchronous Proxy Servlet. * Asynchronous Proxy Servlet.
* *
* Forward requests to another server either as a standard web proxy (as defined by * Forward requests to another server either as a standard web proxy (as defined by RFC2616) or as a transparent proxy.
* RFC2616) or as a transparent proxy.
* <p> * <p>
* This servlet needs the jetty-util and jetty-client classes to be available to * This servlet needs the jetty-util and jetty-client classes to be available to the web application.
* the web application.
* <p> * <p>
* To facilitate JMX monitoring, the "HttpClient", it's "ThreadPool" and the "Logger" * To facilitate JMX monitoring, the "HttpClient", it's "ThreadPool" and the "Logger" are set as context attributes prefixed with the servlet name.
* are set as context attributes prefixed with the servlet name.
* <p> * <p>
* The following init parameters may be used to configure the servlet: <ul> * The following init parameters may be used to configure the servlet:
* <ul>
* <li>name - Name of Proxy servlet (default: "ProxyServlet" * <li>name - Name of Proxy servlet (default: "ProxyServlet"
* <li>maxThreads - maximum threads * <li>maxThreads - maximum threads
* <li>maxConnections - maximum connections per destination * <li>maxConnections - maximum connections per destination
* <li>HostHeader - Force the host header to a particular value * <li>timeout - the period in ms the client will wait for a response from the proxied server
* <li>idleTimeout - the period in ms a connection to proxied server can be idle for before it is closed
* <li>requestHeaderSize - the size of the request header buffer (d. 6,144)
* <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>whiteList - comma-separated list of allowed proxy destinations * <li>whiteList - comma-separated list of allowed proxy destinations
* <li>blackList - comma-separated list of forbidden proxy destinations * <li>blackList - comma-separated list of forbidden proxy destinations
* </ul> * </ul>
* *
* @see org.eclipse.jetty.server.handler.ConnectHandler * @see org.eclipse.jetty.server.handler.ConnectHandler
*/ */
public class ProxyServlet implements Servlet public class ProxyServlet implements Servlet
@ -103,53 +110,40 @@ public class ProxyServlet implements Servlet
protected HostMap<PathMap> _black = new HostMap<PathMap>(); protected HostMap<PathMap> _black = new HostMap<PathMap>();
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see javax.servlet.Servlet#init(javax.servlet.ServletConfig) * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig)
*/ */
public void init(ServletConfig config) throws ServletException public void init(ServletConfig config) throws ServletException
{ {
_config=config; _config = config;
_context=config.getServletContext(); _context = config.getServletContext();
_client=new HttpClient(); _hostHeader = config.getInitParameter("HostHeader");
_client.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
_hostHeader=config.getInitParameter("HostHeader");
try try
{ {
_log= Log.getLogger("org.eclipse.jetty.servlets."+config.getServletName()); _log = createLogger(config);
String t = config.getInitParameter("maxThreads"); _client = createHttpClient(config);
if (t!=null)
_client.setThreadPool(new QueuedThreadPool(Integer.parseInt(t))); if (_context != null)
else
_client.setThreadPool(new QueuedThreadPool());
((QueuedThreadPool)_client.getThreadPool()).setName(config.getServletName());
t = config.getInitParameter("maxConnections");
if (t!=null)
_client.setMaxConnectionsPerAddress(Integer.parseInt(t));
_client.start();
if (_context!=null)
{ {
_context.setAttribute(config.getServletName()+".Logger",_log); _context.setAttribute(config.getServletName() + ".Logger",_log);
_context.setAttribute(config.getServletName()+".ThreadPool",_client.getThreadPool()); _context.setAttribute(config.getServletName() + ".ThreadPool",_client.getThreadPool());
_context.setAttribute(config.getServletName()+".HttpClient",_client); _context.setAttribute(config.getServletName() + ".HttpClient",_client);
} }
String white = config.getInitParameter("whiteList"); String white = config.getInitParameter("whiteList");
if (white != null) if (white != null)
{ {
parseList(white, _white); parseList(white,_white);
} }
String black = config.getInitParameter("blackList"); String black = config.getInitParameter("blackList");
if (black != null) if (black != null)
{ {
parseList(black, _black); parseList(black,_black);
} }
} }
catch (Exception e) catch (Exception e)
@ -169,14 +163,110 @@ public class ProxyServlet implements Servlet
_log.debug(x); _log.debug(x);
} }
} }
/**
* Create and return a logger based on the ServletConfig for use in the
* proxy servlet
*
* @param config
* @return Logger
*/
protected Logger createLogger(ServletConfig config)
{
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
* HttpClient for use by this proxy servlet.
*
* @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)));
}
else
{
client.setThreadPool(new QueuedThreadPool());
}
((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 * Helper function to process a parameter value containing a list of new entries and initialize the specified host map.
* of new entries and initialize the specified host map. *
* * @param list
* @param list comma-separated list of new entries * comma-separated list of new entries
* @param hostMap target host map * @param hostMap
* target host map
*/ */
private void parseList(String list, HostMap<PathMap> hostMap) private void parseList(String list, HostMap<PathMap> hostMap)
{ {
@ -185,14 +275,14 @@ public class ProxyServlet implements Servlet
int idx; int idx;
String entry; String entry;
StringTokenizer entries = new StringTokenizer(list, ","); StringTokenizer entries = new StringTokenizer(list,",");
while(entries.hasMoreTokens()) while (entries.hasMoreTokens())
{ {
entry = entries.nextToken(); entry = entries.nextToken();
idx = entry.indexOf('/'); idx = entry.indexOf('/');
String host = idx > 0 ? entry.substring(0,idx) : entry; String host = idx > 0?entry.substring(0,idx):entry;
String path = idx > 0 ? entry.substring(idx) : "/*"; String path = idx > 0?entry.substring(idx):"/*";
host = host.trim(); host = host.trim();
PathMap pathMap = hostMap.get(host); PathMap pathMap = hostMap.get(host);
@ -212,26 +302,28 @@ public class ProxyServlet implements Servlet
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Check the request hostname and path against white- and blacklist. * Check the request hostname and path against white- and blacklist.
* *
* @param host hostname to check * @param host
* @param path path to check * hostname to check
* @param path
* path to check
* @return true if request is allowed to be proxied * @return true if request is allowed to be proxied
*/ */
public boolean validateDestination(String host, String path) public boolean validateDestination(String host, String path)
{ {
if (_white.size()>0) if (_white.size() > 0)
{ {
boolean match = false; boolean match = false;
Object whiteObj = _white.getLazyMatches(host); Object whiteObj = _white.getLazyMatches(host);
if (whiteObj != null) if (whiteObj != null)
{ {
List whiteList = (whiteObj instanceof List) ? (List)whiteObj : Collections.singletonList(whiteObj); List whiteList = (whiteObj instanceof List)?(List)whiteObj:Collections.singletonList(whiteObj);
for (Object entry: whiteList) for (Object entry : whiteList)
{ {
PathMap pathMap = ((Map.Entry<String, PathMap>)entry).getValue(); PathMap pathMap = ((Map.Entry<String, PathMap>)entry).getValue();
if (match = (pathMap!=null && (pathMap.size()==0 || pathMap.match(path)!=null))) if (match = (pathMap != null && (pathMap.size() == 0 || pathMap.match(path) != null)))
break; break;
} }
} }
@ -245,12 +337,12 @@ public class ProxyServlet implements Servlet
Object blackObj = _black.getLazyMatches(host); Object blackObj = _black.getLazyMatches(host);
if (blackObj != null) if (blackObj != null)
{ {
List blackList = (blackObj instanceof List) ? (List)blackObj : Collections.singletonList(blackObj); List blackList = (blackObj instanceof List)?(List)blackObj:Collections.singletonList(blackObj);
for (Object entry: blackList) for (Object entry : blackList)
{ {
PathMap pathMap = ((Map.Entry<String, PathMap>)entry).getValue(); PathMap pathMap = ((Map.Entry<String, PathMap>)entry).getValue();
if (pathMap!=null && (pathMap.size()==0 || pathMap.match(path)!=null)) if (pathMap != null && (pathMap.size() == 0 || pathMap.match(path) != null))
return false; return false;
} }
} }
@ -260,7 +352,9 @@ public class ProxyServlet implements Servlet
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see javax.servlet.Servlet#getServletConfig() * @see javax.servlet.Servlet#getServletConfig()
*/ */
public ServletConfig getServletConfig() public ServletConfig getServletConfig()
@ -268,9 +362,10 @@ public class ProxyServlet implements Servlet
return _config; return _config;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Get the hostHeader. /**
* Get the hostHeader.
*
* @return the hostHeader * @return the hostHeader
*/ */
public String getHostHeader() public String getHostHeader()
@ -279,8 +374,11 @@ public class ProxyServlet implements Servlet
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Set the hostHeader. /**
* @param hostHeader the hostHeader to set * Set the hostHeader.
*
* @param hostHeader
* the hostHeader to set
*/ */
public void setHostHeader(String hostHeader) public void setHostHeader(String hostHeader)
{ {
@ -288,24 +386,26 @@ public class ProxyServlet implements Servlet
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see javax.servlet.Servlet#service(javax.servlet.ServletRequest, javax.servlet.ServletResponse) * @see javax.servlet.Servlet#service(javax.servlet.ServletRequest, javax.servlet.ServletResponse)
*/ */
public void service(ServletRequest req, ServletResponse res) throws ServletException, public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
IOException
{ {
final int debug=_log.isDebugEnabled()?req.hashCode():0; final int debug = _log.isDebugEnabled()?req.hashCode():0;
final HttpServletRequest request = (HttpServletRequest)req; final HttpServletRequest request = (HttpServletRequest)req;
final HttpServletResponse response = (HttpServletResponse)res; final HttpServletResponse response = (HttpServletResponse)res;
if ("CONNECT".equalsIgnoreCase(request.getMethod())) if ("CONNECT".equalsIgnoreCase(request.getMethod()))
{ {
handleConnect(request,response); handleConnect(request,response);
} }
else else
{ {
final InputStream in=request.getInputStream(); final InputStream in = request.getInputStream();
final OutputStream out=response.getOutputStream(); final OutputStream out = response.getOutputStream();
final Continuation continuation = ContinuationSupport.getContinuation(request); final Continuation continuation = ContinuationSupport.getContinuation(request);
@ -313,19 +413,17 @@ public class ProxyServlet implements Servlet
response.sendError(HttpServletResponse.SC_GATEWAY_TIMEOUT); // Need better test that isInitial response.sendError(HttpServletResponse.SC_GATEWAY_TIMEOUT); // Need better test that isInitial
else else
{ {
String uri=request.getRequestURI();
if (request.getQueryString()!=null) String uri = request.getRequestURI();
uri+="?"+request.getQueryString(); if (request.getQueryString() != null)
uri += "?" + request.getQueryString();
HttpURI url=proxyHttpURI(request.getScheme(), HttpURI url = proxyHttpURI(request.getScheme(),request.getServerName(),request.getServerPort(),uri);
request.getServerName(),
request.getServerPort(),
uri);
if (debug!=0) if (debug != 0)
_log.debug(debug+" proxy "+uri+"-->"+url); _log.debug(debug + " proxy " + uri + "-->" + url);
if (url==null) if (url == null)
{ {
response.sendError(HttpServletResponse.SC_FORBIDDEN); response.sendError(HttpServletResponse.SC_FORBIDDEN);
return; return;
@ -343,15 +441,15 @@ public class ProxyServlet implements Servlet
protected void onResponseComplete() throws IOException protected void onResponseComplete() throws IOException
{ {
if (debug!=0) if (debug != 0)
_log.debug(debug+" complete"); _log.debug(debug + " complete");
continuation.complete(); continuation.complete();
} }
protected void onResponseContent(Buffer content) throws IOException protected void onResponseContent(Buffer content) throws IOException
{ {
if (debug!=0) if (debug != 0)
_log.debug(debug+" content"+content.length()); _log.debug(debug + " content" + content.length());
content.writeTo(out); content.writeTo(out);
} }
@ -361,10 +459,10 @@ public class ProxyServlet implements Servlet
protected void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException protected void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
{ {
if (debug!=0) if (debug != 0)
_log.debug(debug+" "+version+" "+status+" "+reason); _log.debug(debug + " " + version + " " + status + " " + reason);
if (reason!=null && reason.length()>0) if (reason != null && reason.length() > 0)
response.setStatus(status,reason.toString()); response.setStatus(status,reason.toString());
else else
response.setStatus(status); response.setStatus(status);
@ -373,22 +471,27 @@ public class ProxyServlet implements Servlet
protected void onResponseHeader(Buffer name, Buffer value) throws IOException protected void onResponseHeader(Buffer name, Buffer value) throws IOException
{ {
String s = name.toString().toLowerCase(); String s = name.toString().toLowerCase();
if (!_DontProxyHeaders.contains(s) || if (!_DontProxyHeaders.contains(s) || (HttpHeaders.CONNECTION_BUFFER.equals(name) && HttpHeaderValues.CLOSE_BUFFER.equals(value)))
(HttpHeaders.CONNECTION_BUFFER.equals(name) &&
HttpHeaderValues.CLOSE_BUFFER.equals(value)))
{ {
if (debug!=0) if (debug != 0)
_log.debug(debug+" "+name+": "+value); _log.debug(debug + " " + name + ": " + value);
response.addHeader(name.toString(),value.toString()); response.addHeader(name.toString(),value.toString());
} }
else if (debug!=0) else if (debug != 0)
_log.debug(debug+" "+name+"! "+value); _log.debug(debug + " " + name + "! " + value);
} }
protected void onConnectionFailed(Throwable ex) protected void onConnectionFailed(Throwable ex)
{ {
onException(ex); handleOnConnectionFailed(ex,request,response);
// it is possible this might trigger before the
// continuation.suspend()
if (!continuation.isInitial())
{
continuation.complete();
}
} }
protected void onException(Throwable ex) protected void onException(Throwable ex)
@ -398,17 +501,19 @@ public class ProxyServlet implements Servlet
Log.ignore(ex); Log.ignore(ex);
return; return;
} }
Log.warn(ex.toString()); handleOnException(ex,request,response);
Log.debug(ex);
if (!response.isCommitted()) // it is possible this might trigger before the
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); // continuation.suspend()
continuation.complete(); if (!continuation.isInitial())
{
continuation.complete();
}
} }
protected void onExpire() protected void onExpire()
{ {
if (!response.isCommitted()) handleOnExpire(request,response);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
continuation.complete(); continuation.complete();
} }
@ -419,61 +524,61 @@ public class ProxyServlet implements Servlet
exchange.setURL(url.toString()); exchange.setURL(url.toString());
exchange.setVersion(request.getProtocol()); exchange.setVersion(request.getProtocol());
if (debug!=0)
_log.debug(debug+" "+request.getMethod()+" "+url+" "+request.getProtocol()); if (debug != 0)
_log.debug(debug + " " + request.getMethod() + " " + url + " " + request.getProtocol());
// check connection header // check connection header
String connectionHdr = request.getHeader("Connection"); String connectionHdr = request.getHeader("Connection");
if (connectionHdr!=null) if (connectionHdr != null)
{ {
connectionHdr=connectionHdr.toLowerCase(); connectionHdr = connectionHdr.toLowerCase();
if (connectionHdr.indexOf("keep-alive")<0 && if (connectionHdr.indexOf("keep-alive") < 0 && connectionHdr.indexOf("close") < 0)
connectionHdr.indexOf("close")<0) connectionHdr = null;
connectionHdr=null;
} }
// force host // force host
if (_hostHeader!=null) if (_hostHeader != null)
exchange.setRequestHeader("Host",_hostHeader); exchange.setRequestHeader("Host",_hostHeader);
// copy headers // copy headers
boolean xForwardedFor=false; boolean xForwardedFor = false;
boolean hasContent=false; boolean hasContent = false;
long contentLength=-1; long contentLength = -1;
Enumeration<?> enm = request.getHeaderNames(); Enumeration<?> enm = request.getHeaderNames();
while (enm.hasMoreElements()) while (enm.hasMoreElements())
{ {
// TODO could be better than this! // TODO could be better than this!
String hdr=(String)enm.nextElement(); String hdr = (String)enm.nextElement();
String lhdr=hdr.toLowerCase(); String lhdr = hdr.toLowerCase();
if (_DontProxyHeaders.contains(lhdr)) if (_DontProxyHeaders.contains(lhdr))
continue; continue;
if (connectionHdr!=null && connectionHdr.indexOf(lhdr)>=0) if (connectionHdr != null && connectionHdr.indexOf(lhdr) >= 0)
continue; continue;
if (_hostHeader!=null && "host".equals(lhdr)) if (_hostHeader != null && "host".equals(lhdr))
continue; continue;
if ("content-type".equals(lhdr)) if ("content-type".equals(lhdr))
hasContent=true; hasContent = true;
else if ("content-length".equals(lhdr)) else if ("content-length".equals(lhdr))
{ {
contentLength=request.getContentLength(); contentLength = request.getContentLength();
exchange.setRequestHeader(HttpHeaders.CONTENT_LENGTH,Long.toString(contentLength)); exchange.setRequestHeader(HttpHeaders.CONTENT_LENGTH,Long.toString(contentLength));
if (contentLength>0) if (contentLength > 0)
hasContent=true; hasContent = true;
} }
else if ("x-forwarded-for".equals(lhdr)) else if ("x-forwarded-for".equals(lhdr))
xForwardedFor=true; xForwardedFor = true;
Enumeration<?> vals = request.getHeaders(hdr); Enumeration<?> vals = request.getHeaders(hdr);
while (vals.hasMoreElements()) while (vals.hasMoreElements())
{ {
String val = (String)vals.nextElement(); String val = (String)vals.nextElement();
if (val!=null) if (val != null)
{ {
if (debug!=0) if (debug != 0)
_log.debug(debug+" "+hdr+": "+val); _log.debug(debug + " " + hdr + ": " + val);
exchange.setRequestHeader(hdr,val); exchange.setRequestHeader(hdr,val);
} }
@ -484,19 +589,36 @@ public class ProxyServlet implements Servlet
exchange.setRequestHeader("Via","1.1 (jetty)"); exchange.setRequestHeader("Via","1.1 (jetty)");
if (!xForwardedFor) if (!xForwardedFor)
{ {
exchange.addRequestHeader("X-Forwarded-For", exchange.addRequestHeader("X-Forwarded-For",request.getRemoteAddr());
request.getRemoteAddr()); exchange.addRequestHeader("X-Forwarded-Proto",request.getScheme());
exchange.addRequestHeader("X-Forwarded-Proto", exchange.addRequestHeader("X-Forwarded-Host",request.getServerName());
request.getScheme()); exchange.addRequestHeader("X-Forwarded-Server",request.getLocalName());
exchange.addRequestHeader("X-Forwarded-Host",
request.getServerName());
exchange.addRequestHeader("X-Forwarded-Server",
request.getLocalName());
} }
if (hasContent) if (hasContent)
exchange.setRequestContentSource(in); exchange.setRequestContentSource(in);
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 )
{
continuation.setTimeout(0); // ideally never times out
}
else
{
continuation.setTimeout(ctimeout + 1000);
}
customizeContinuation(continuation);
continuation.suspend(response); continuation.suspend(response);
_client.send(exchange); _client.send(exchange);
@ -504,11 +626,8 @@ public class ProxyServlet implements Servlet
} }
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public void handleConnect(HttpServletRequest request, public void handleConnect(HttpServletRequest request, HttpServletResponse response) throws IOException
HttpServletResponse response)
throws IOException
{ {
String uri = request.getRequestURI(); String uri = request.getRequestURI();
@ -516,27 +635,26 @@ public class ProxyServlet implements Servlet
String host = ""; String host = "";
int c = uri.indexOf(':'); int c = uri.indexOf(':');
if (c>=0) if (c >= 0)
{ {
port = uri.substring(c+1); port = uri.substring(c + 1);
host = uri.substring(0,c); host = uri.substring(0,c);
if (host.indexOf('/')>0) if (host.indexOf('/') > 0)
host = host.substring(host.indexOf('/')+1); host = host.substring(host.indexOf('/') + 1);
} }
// TODO - make this async! // TODO - make this async!
InetSocketAddress inetAddress = new InetSocketAddress(host,Integer.parseInt(port));
InetSocketAddress inetAddress = new InetSocketAddress (host, Integer.parseInt(port)); // if (isForbidden(HttpMessage.__SSL_SCHEME,addrPort.getHost(),addrPort.getPort(),false))
// {
//if (isForbidden(HttpMessage.__SSL_SCHEME,addrPort.getHost(),addrPort.getPort(),false)) // sendForbid(request,response,uri);
//{ // }
// sendForbid(request,response,uri); // else
//}
//else
{ {
InputStream in=request.getInputStream(); InputStream in = request.getInputStream();
OutputStream out=response.getOutputStream(); OutputStream out = response.getOutputStream();
Socket socket = new Socket(inetAddress.getAddress(),inetAddress.getPort()); Socket socket = new Socket(inetAddress.getAddress(),inetAddress.getPort());
@ -551,17 +669,17 @@ public class ProxyServlet implements Servlet
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
protected HttpURI proxyHttpURI(String scheme, String serverName, int serverPort, String uri) protected HttpURI proxyHttpURI(String scheme, String serverName, int serverPort, String uri) throws MalformedURLException
throws MalformedURLException
{ {
if (!validateDestination(serverName, uri)) if (!validateDestination(serverName,uri))
return null; return null;
return new HttpURI(scheme+"://"+serverName+":"+serverPort+uri); return new HttpURI(scheme + "://" + serverName + ":" + serverPort + uri);
} }
/*
/* (non-Javadoc) * (non-Javadoc)
*
* @see javax.servlet.Servlet#getServletInfo() * @see javax.servlet.Servlet#getServletInfo()
*/ */
public String getServletInfo() public String getServletInfo()
@ -569,17 +687,85 @@ public class ProxyServlet implements Servlet
return "Proxy Servlet"; return "Proxy Servlet";
} }
/**
* Extension point for subclasses to customize an exchange. Useful for setting timeouts etc. The default implementation does nothing.
*
* @param exchange
* @param request
*/
protected void customizeExchange(HttpExchange exchange, HttpServletRequest request)
{
}
/**
* 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)
{
}
/**
* 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
*/
protected void handleOnConnectionFailed(Throwable ex, HttpServletRequest request, HttpServletResponse response)
{
handleOnException(ex,request,response);
}
/**
* 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);
if (!response.isCommitted())
{
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
/**
* 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
*/
protected void handleOnExpire(HttpServletRequest request, HttpServletResponse response)
{
if (!response.isCommitted())
{
response.setStatus(HttpServletResponse.SC_GATEWAY_TIMEOUT);
}
}
/** /**
* Transparent Proxy. * Transparent Proxy.
* *
* This convenience extension to ProxyServlet configures the servlet as a transparent proxy. * This convenience extension to ProxyServlet configures the servlet as a transparent proxy. The servlet is configured with init parameters:
* The servlet is configured with init parameters:
* <ul> * <ul>
* <li>ProxyTo - a URI like http://host:80/context to which the request is proxied. * <li>ProxyTo - a URI like http://host:80/context to which the request is proxied.
* <li>Prefix - a URI prefix that is striped from the start of the forwarded URI. * <li>Prefix - a URI prefix that is striped from the start of the forwarded URI.
* </ul> * </ul>
* For example, if a request was received at /foo/bar and the ProxyTo was http://host:80/context * 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
* and the Prefix was /foo, then the request would be proxied to http://host:80/context/bar * to http://host:80/context/bar
* *
*/ */
public static class Transparent extends ProxyServlet public static class Transparent extends ProxyServlet
@ -633,7 +819,7 @@ public class ProxyServlet implements Servlet
if (!_prefix.startsWith("/")) if (!_prefix.startsWith("/"))
throw new UnavailableException("Prefix parameter must start with a '/'."); throw new UnavailableException("Prefix parameter must start with a '/'.");
_log.info(config.getServletName()+" @ " + _prefix + " to " + _proxyTo); _log.info(config.getServletName() + " @ " + _prefix + " to " + _proxyTo);
} }
@Override @Override

View File

@ -0,0 +1,115 @@
// ========================================================================
// 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.servlets;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.testing.HttpTester;
import org.eclipse.jetty.testing.ServletTester;
import org.eclipse.jetty.toolchain.test.TestingDir;
import org.eclipse.jetty.util.IO;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
public class GzipFilterTest
{
private static String __content =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis felis nunc. "+
"Quisque suscipit mauris et ante auctor ornare rhoncus lacus aliquet. Pellentesque "+
"habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. "+
"Vestibulum sit amet felis augue, vel convallis dolor. Cras accumsan vehicula diam "+
"at faucibus. Etiam in urna turpis, sed congue mi. Morbi et lorem eros. Donec vulputate "+
"velit in risus suscipit lobortis. Aliquam id urna orci, nec sollicitudin ipsum. "+
"Cras a orci turpis. Donec suscipit vulputate cursus. Mauris nunc tellus, fermentum "+
"eu auctor ut, mollis at diam. Quisque porttitor ultrices metus, vitae tincidunt massa "+
"sollicitudin a. Vivamus porttitor libero eget purus hendrerit cursus. Integer aliquam "+
"consequat mauris quis luctus. Cras enim nibh, dignissim eu faucibus ac, mollis nec neque. "+
"Aliquam purus mauris, consectetur nec convallis lacinia, porta sed ante. Suspendisse "+
"et cursus magna. Donec orci enim, molestie a lobortis eu, imperdiet vitae neque.";
@Rule
public TestingDir testdir = new TestingDir();
private ServletTester tester;
@Before
public void setUp() throws Exception
{
testdir.ensureEmpty();
File testFile = testdir.getFile("file.txt");
BufferedOutputStream testOut = new BufferedOutputStream(new FileOutputStream(testFile));
ByteArrayInputStream testIn = new ByteArrayInputStream(__content.getBytes("ISO8859_1"));
IO.copy(testIn,testOut);
testOut.close();
tester=new ServletTester();
tester.setContextPath("/context");
tester.setResourceBase(testdir.getDir().getCanonicalPath());
tester.addServlet(org.eclipse.jetty.servlet.DefaultServlet.class, "/");
FilterHolder holder = tester.addFilter(GzipFilter.class,"/*",null);
holder.setInitParameter("mimeTypes","text/plain");
tester.start();
}
@After
public void tearDown() throws Exception
{
tester.stop();
IO.delete(testdir.getDir());
}
@Test
public void testGzipFilter() throws Exception
{
// generated and parsed test
HttpTester request = new HttpTester();
HttpTester response = new HttpTester();
request.setMethod("GET");
request.setVersion("HTTP/1.0");
request.setHeader("Host","tester");
request.setHeader("accept-encoding","gzip");
request.setURI("/context/file.txt");
ByteArrayBuffer reqsBuff = new ByteArrayBuffer(request.generate().getBytes());
ByteArrayBuffer respBuff = tester.getResponses(reqsBuff);
response.parse(respBuff.asArray());
assertTrue(response.getMethod()==null);
assertTrue(response.getHeader("Content-Encoding").equalsIgnoreCase("gzip"));
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes()));
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
IO.copy(testIn,testOut);
assertEquals(__content, testOut.toString("ISO8859_1"));
}
}

View File

@ -0,0 +1,115 @@
// ========================================================================
// 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.servlets;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.testing.HttpTester;
import org.eclipse.jetty.testing.ServletTester;
import org.eclipse.jetty.toolchain.test.TestingDir;
import org.eclipse.jetty.util.IO;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
public class IncludableGzipFilterTest
{
private static String __content =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis felis nunc. "+
"Quisque suscipit mauris et ante auctor ornare rhoncus lacus aliquet. Pellentesque "+
"habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. "+
"Vestibulum sit amet felis augue, vel convallis dolor. Cras accumsan vehicula diam "+
"at faucibus. Etiam in urna turpis, sed congue mi. Morbi et lorem eros. Donec vulputate "+
"velit in risus suscipit lobortis. Aliquam id urna orci, nec sollicitudin ipsum. "+
"Cras a orci turpis. Donec suscipit vulputate cursus. Mauris nunc tellus, fermentum "+
"eu auctor ut, mollis at diam. Quisque porttitor ultrices metus, vitae tincidunt massa "+
"sollicitudin a. Vivamus porttitor libero eget purus hendrerit cursus. Integer aliquam "+
"consequat mauris quis luctus. Cras enim nibh, dignissim eu faucibus ac, mollis nec neque. "+
"Aliquam purus mauris, consectetur nec convallis lacinia, porta sed ante. Suspendisse "+
"et cursus magna. Donec orci enim, molestie a lobortis eu, imperdiet vitae neque.";
@Rule
public TestingDir testdir = new TestingDir();
private ServletTester tester;
@Before
public void setUp() throws Exception
{
testdir.ensureEmpty();
File testFile = testdir.getFile("file.txt");
BufferedOutputStream testOut = new BufferedOutputStream(new FileOutputStream(testFile));
ByteArrayInputStream testIn = new ByteArrayInputStream(__content.getBytes("ISO8859_1"));
IO.copy(testIn,testOut);
testOut.close();
tester=new ServletTester();
tester.setContextPath("/context");
tester.setResourceBase(testdir.getDir().getCanonicalPath());
tester.addServlet(org.eclipse.jetty.servlet.DefaultServlet.class, "/");
FilterHolder holder = tester.addFilter(IncludableGzipFilter.class,"/*",null);
holder.setInitParameter("mimeTypes","text/plain");
tester.start();
}
@After
public void tearDown() throws Exception
{
tester.stop();
IO.delete(testdir.getDir());
}
@Test
public void testGzipFilter() throws Exception
{
// generated and parsed test
HttpTester request = new HttpTester();
HttpTester response = new HttpTester();
request.setMethod("GET");
request.setVersion("HTTP/1.0");
request.setHeader("Host","tester");
request.setHeader("accept-encoding","gzip");
request.setURI("/context/file.txt");
ByteArrayBuffer reqsBuff = new ByteArrayBuffer(request.generate().getBytes());
ByteArrayBuffer respBuff = tester.getResponses(reqsBuff);
response.parse(respBuff.asArray());
assertTrue(response.getMethod()==null);
assertTrue(response.getHeader("Content-Encoding").equalsIgnoreCase("gzip"));
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes()));
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
IO.copy(testIn,testOut);
assertEquals(__content, testOut.toString("ISO8859_1"));
}
}

View File

@ -562,7 +562,15 @@ public class Main
if (_exec) if (_exec)
{ {
String cmd = buildCommandLine(classpath,configuredXmls); String cmd = buildCommandLine(classpath,configuredXmls);
Process process = Runtime.getRuntime().exec(cmd); final Process process = Runtime.getRuntime().exec(cmd);
Runtime.getRuntime().addShutdownHook(new Thread()
{
public void run()
{
Config.debug("Destroying " + process);
process.destroy();
}
});
copyInThread(process.getErrorStream(),System.err); copyInThread(process.getErrorStream(),System.err);
copyInThread(process.getInputStream(),System.out); copyInThread(process.getInputStream(),System.out);
copyInThread(System.in,process.getOutputStream()); copyInThread(System.in,process.getOutputStream());

View File

@ -231,7 +231,10 @@ public class UrlEncoded extends MultiMap
key = encoded key = encoded
?decodeString(content,mark+1,content.length()-mark-1,charset) ?decodeString(content,mark+1,content.length()-mark-1,charset)
:content.substring(mark+1); :content.substring(mark+1);
map.add(key,""); if (key != null && key.length() > 0)
{
map.add(key,"");
}
} }
} }
} }
@ -504,7 +507,14 @@ public class UrlEncoded extends MultiMap
public static void decodeTo(InputStream in, MultiMap map, String charset, int maxLength) public static void decodeTo(InputStream in, MultiMap map, String charset, int maxLength)
throws IOException throws IOException
{ {
if (charset==null || StringUtil.__UTF8.equalsIgnoreCase(charset)) //no charset present, use the configured default
if (charset==null)
{
charset=ENCODING;
}
if (StringUtil.__UTF8.equalsIgnoreCase(charset))
{ {
decodeUtf8To(in,map,maxLength); decodeUtf8To(in,map,maxLength);
return; return;

View File

@ -12,6 +12,7 @@
// ======================================================================== // ========================================================================
package org.eclipse.jetty.util.component; package org.eclipse.jetty.util.component;
import java.lang.ref.WeakReference;
import java.util.EventListener; import java.util.EventListener;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
@ -225,20 +226,19 @@ public class Container
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** A Container event. /** A Container event.
* @see Listener * @see Listener
*
*/ */
public static class Relationship public static class Relationship
{ {
private Object _parent; private final WeakReference<Object> _parent;
private Object _child; private final WeakReference<Object> _child;
private String _relationship; private String _relationship;
private Container _container; private Container _container;
private Relationship(Container container, Object parent,Object child, String relationship) private Relationship(Container container, Object parent,Object child, String relationship)
{ {
_container=container; _container=container;
_parent=parent; _parent=new WeakReference<Object>(parent);
_child=child; _child=new WeakReference<Object>(child);
_relationship=relationship; _relationship=relationship;
} }
@ -249,12 +249,12 @@ public class Container
public Object getChild() public Object getChild()
{ {
return _child; return _child.get();
} }
public Object getParent() public Object getParent()
{ {
return _parent; return _parent.get();
} }
public String getRelationship() public String getRelationship()
@ -280,7 +280,7 @@ public class Container
if (o==null || !(o instanceof Relationship)) if (o==null || !(o instanceof Relationship))
return false; return false;
Relationship r = (Relationship)o; Relationship r = (Relationship)o;
return r._parent==_parent && r._child==_child && r._relationship.equals(_relationship); return r._parent.get()==_parent.get() && r._child.get()==_child.get() && r._relationship.equals(_relationship);
} }
} }

View File

@ -536,7 +536,7 @@ public abstract class Resource implements ResourceFactory
buf.append("\">"); buf.append("\">");
buf.append(deTag(ls[i])); buf.append(deTag(ls[i]));
buf.append("&nbsp;"); buf.append("&nbsp;");
buf.append("</TD><TD ALIGN=right>"); buf.append("</A></TD><TD ALIGN=right>");
buf.append(item.length()); buf.append(item.length());
buf.append(" bytes&nbsp;</TD><TD>"); buf.append(" bytes&nbsp;</TD><TD>");
buf.append(dfmt.format(new Date(item.lastModified()))); buf.append(dfmt.format(new Date(item.lastModified())));

View File

@ -87,6 +87,7 @@ public class ScannerTest
@Test @Test
public void testAddedChangeRemove() throws Exception public void testAddedChangeRemove() throws Exception
{ {
// TODO needs to be further investigated
Assume.assumeTrue(!OS.IS_WINDOWS && !OS.IS_OSX); Assume.assumeTrue(!OS.IS_WINDOWS && !OS.IS_OSX);
touch("a0"); touch("a0");
@ -195,6 +196,7 @@ public class ScannerTest
@Test @Test
public void testSizeChange() throws Exception public void testSizeChange() throws Exception
{ {
// TODO needs to be further investigated
Assume.assumeTrue(!OS.IS_WINDOWS && !OS.IS_OSX); Assume.assumeTrue(!OS.IS_WINDOWS && !OS.IS_OSX);
touch("tsc0"); touch("tsc0");

View File

@ -19,6 +19,7 @@ import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
@ -28,13 +29,30 @@ import org.junit.Test;
*/ */
public class URLEncodedTest public class URLEncodedTest
{ {
/* -------------------------------------------------------------- */
static
{
/*
* Uncomment to set setting the System property to something other than the default of UTF-8.
* Beware however that you will have to @Ignore all the other tests other than testUrlEncodedStream!
System.setProperty("org.eclipse.jetty.util.UrlEncoding.charset", StringUtil.__ISO_8859_1);
*/
}
/* -------------------------------------------------------------- */ /* -------------------------------------------------------------- */
@Test @Test
public void testUrlEncoded() throws UnsupportedEncodingException public void testUrlEncoded() throws UnsupportedEncodingException
{ {
UrlEncoded url_encoded = new UrlEncoded(); UrlEncoded url_encoded = new UrlEncoded();
assertEquals("Empty",0, url_encoded.size()); assertEquals("Initially not empty",0, url_encoded.size());
url_encoded.clear();
url_encoded.decode("");
assertEquals("Not empty after decode(\"\")",0, url_encoded.size());
url_encoded.clear(); url_encoded.clear();
url_encoded.decode("Name1=Value1"); url_encoded.decode("Name1=Value1");
@ -156,6 +174,7 @@ public class URLEncodedTest
{StringUtil.__UTF16,StringUtil.__UTF16}, {StringUtil.__UTF16,StringUtil.__UTF16},
}; };
for (int i=0;i<charsets.length;i++) for (int i=0;i<charsets.length;i++)
{ {
ByteArrayInputStream in = new ByteArrayInputStream("name\n=value+%30&name1=&name2&n\u00e3me3=value+3".getBytes(charsets[i][0])); ByteArrayInputStream in = new ByteArrayInputStream("name\n=value+%30&name1=&name2&n\u00e3me3=value+3".getBytes(charsets[i][0]));
@ -180,7 +199,28 @@ public class URLEncodedTest
} }
else else
assertTrue("Charset Shift_JIS not supported by jvm", true); assertTrue("Charset Shift_JIS not supported by jvm", true);
} }
/* -------------------------------------------------------------- */
@Test
public void testCharsetViaSystemProperty ()
throws Exception
{
/*
* Uncomment to test setting a non-UTF-8 default character encoding using the SystemProperty org.eclipse.jetty.util.UrlEncoding.charset.
* You will also need to uncomment the static initializer that sets this SystemProperty near the top of this file.
ByteArrayInputStream in3 = new ByteArrayInputStream("name=libell%E9".getBytes(StringUtil.__ISO_8859_1));
MultiMap m3 = new MultiMap();
UrlEncoded.decodeTo(in3, m3, null, -1);
assertEquals("stream name", "libell\u00E9", m3.getString("name"));
*/
}
/* -------------------------------------------------------------- */ /* -------------------------------------------------------------- */
@Test @Test

View File

@ -461,6 +461,7 @@ public class ResourceTest
@Test @Test
public void testUncPathResourceFile() throws Exception public void testUncPathResourceFile() throws Exception
{ {
// This test is intended to run only on Windows platform
assumeTrue(OS.IS_WINDOWS); assumeTrue(OS.IS_WINDOWS);
String uncPath = "\\\\127.0.0.1"+__userURL.toURI().getPath().replace('/','\\').replace(':','$')+"ResourceTest.java"; String uncPath = "\\\\127.0.0.1"+__userURL.toURI().getPath().replace('/','\\').replace(':','$')+"ResourceTest.java";

View File

@ -316,10 +316,9 @@ public class WebAppClassLoader extends URLClassLoader
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
private List<URL> toList(Enumeration<URL> e) private List<URL> toList(Enumeration<URL> e)
{ {
List<URL> list = new ArrayList<URL>(); if (e==null)
while (e!=null && e.hasMoreElements()) return new ArrayList<URL>();
list.add(e.nextElement()); return Collections.list(e);
return list;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */

View File

@ -11,36 +11,16 @@ import org.eclipse.jetty.websocket.WebSocketParser.FrameHandler;
public class AbstractExtension implements Extension public class AbstractExtension implements Extension
{ {
private static final int[] __mask = { -1, 0x04, 0x02, 0x01};
private final String _name; private final String _name;
private final byte[] _dataOpcodes;
private final byte[] _controlOpcodes;
private final byte[] _bitMasks;
private final Map<String,String> _parameters=new HashMap<String, String>(); private final Map<String,String> _parameters=new HashMap<String, String>();
private FrameHandler _inbound; private FrameHandler _inbound;
private WebSocketGenerator _outbound; private WebSocketGenerator _outbound;
private WebSocket.FrameConnection _connection; private WebSocket.FrameConnection _connection;
public AbstractExtension(String name,int dataCodes, int controlCodes, int flags) public AbstractExtension(String name)
{ {
_name = name; _name = name;
_dataOpcodes=new byte[dataCodes];
_controlOpcodes=new byte[controlCodes];
_bitMasks=new byte[flags];
}
public int getDataOpcodes()
{
return _dataOpcodes.length;
}
public int getControlOpcodes()
{
return _controlOpcodes.length;
}
public int getReservedBits()
{
return _bitMasks.length;
} }
public WebSocket.FrameConnection getConnection() public WebSocket.FrameConnection getConnection()
@ -75,19 +55,11 @@ public class AbstractExtension implements Extension
} }
public void bind(WebSocket.FrameConnection connection, FrameHandler incoming, WebSocketGenerator outgoing, byte[] dataOpcodes, byte[] controlOpcodes, byte[] bitMasks) public void bind(WebSocket.FrameConnection connection, FrameHandler incoming, WebSocketGenerator outgoing)
{ {
_connection=connection; _connection=connection;
_inbound=incoming; _inbound=incoming;
_outbound=outgoing; _outbound=outgoing;
if (dataOpcodes!=null)
System.arraycopy(dataOpcodes,0,_dataOpcodes,0,dataOpcodes.length);
if (controlOpcodes!=null)
System.arraycopy(controlOpcodes,0,_dataOpcodes,0,controlOpcodes.length);
if (bitMasks!=null)
System.arraycopy(bitMasks,0,_bitMasks,0,bitMasks.length);
// System.err.printf("bind %s[%s|%s|%s]\n",_name,TypeUtil.toHexString(dataOpcodes),TypeUtil.toHexString(controlOpcodes),TypeUtil.toHexString(bitMasks));
} }
public String getName() public String getName()
@ -130,46 +102,27 @@ public class AbstractExtension implements Extension
// System.err.printf("addFrame %s %x %x %d\n",getExtensionName(),flags,opcode,length); // System.err.printf("addFrame %s %x %x %d\n",getExtensionName(),flags,opcode,length);
_outbound.addFrame(flags,opcode,content,offset,length); _outbound.addFrame(flags,opcode,content,offset,length);
} }
public byte dataOpcode(int i) public byte setFlag(byte flags,int rsv)
{ {
return _dataOpcodes[i]; if (rsv<1||rsv>3)
} throw new IllegalArgumentException("rsv"+rsv);
byte b=(byte)(flags | __mask[rsv]);
public int dataIndex(byte op) return b;
{
for (int i=0;i<_dataOpcodes.length;i++)
if (_dataOpcodes[i]==op)
return i;
return -1;
}
public byte controlOpcode(int i)
{
return _dataOpcodes[i];
}
public int controlIndex(byte op)
{
for (int i=0;i<_controlOpcodes.length;i++)
if (_controlOpcodes[i]==op)
return i;
return -1;
} }
public byte setFlag(byte flags,int flag) public byte clearFlag(byte flags,int rsv)
{ {
return (byte)(flags | _bitMasks[flag]); if (rsv<1||rsv>3)
} throw new IllegalArgumentException("rsv"+rsv);
return (byte)(flags & ~__mask[rsv]);
public byte clearFlag(byte flags,int flag)
{
return (byte)(flags & ~_bitMasks[flag]);
} }
public boolean isFlag(byte flags,int flag) public boolean isFlag(byte flags,int rsv)
{ {
return (flags & _bitMasks[flag])!=0; if (rsv<1||rsv>3)
throw new IllegalArgumentException("rsv"+rsv);
return (flags & __mask[rsv])!=0;
} }
public String toString() public String toString()

View File

@ -13,13 +13,13 @@ import org.eclipse.jetty.util.log.Log;
public class DeflateFrameExtension extends AbstractExtension public class DeflateFrameExtension extends AbstractExtension
{ {
private int _minLength=64; private int _minLength=8;
private Deflater _deflater; private Deflater _deflater;
private Inflater _inflater; private Inflater _inflater;
public DeflateFrameExtension() public DeflateFrameExtension()
{ {
super("x-deflate-frame",0,0,1); super("x-deflate-frame");
} }
@Override @Override
@ -45,12 +45,12 @@ public class DeflateFrameExtension extends AbstractExtension
@Override @Override
public void onFrame(byte flags, byte opcode, Buffer buffer) public void onFrame(byte flags, byte opcode, Buffer buffer)
{ {
if (getConnection().isControl(opcode) || !isFlag(flags,0)) if (getConnection().isControl(opcode) || !isFlag(flags,1))
{ {
super.onFrame(flags,opcode,buffer); super.onFrame(flags,opcode,buffer);
return; return;
} }
if (buffer.array()==null) if (buffer.array()==null)
buffer=buffer.asMutableBuffer(); buffer=buffer.asMutableBuffer();
@ -61,7 +61,8 @@ public class DeflateFrameExtension extends AbstractExtension
length=0; length=0;
while(b-->0) while(b-->0)
length=0x100*length+(0xff&buffer.get()); length=0x100*length+(0xff&buffer.get());
} }
// TODO check a max framesize // TODO check a max framesize
_inflater.setInput(buffer.array(),buffer.getIndex(),buffer.length()); _inflater.setInput(buffer.array(),buffer.getIndex(),buffer.length());
@ -76,12 +77,12 @@ public class DeflateFrameExtension extends AbstractExtension
buf.setPutIndex(buf.putIndex()+inflated); buf.setPutIndex(buf.putIndex()+inflated);
} }
super.onFrame(clearFlag(flags,0),opcode,buf); super.onFrame(clearFlag(flags,1),opcode,buf);
} }
catch(DataFormatException e) catch(DataFormatException e)
{ {
Log.warn(e); Log.warn(e);
getConnection().close(WebSocketConnectionD07.CLOSE_PROTOCOL,e.toString()); getConnection().close(WebSocketConnectionD7_9.CLOSE_PROTOCOL,e.toString());
} }
} }
@ -91,9 +92,9 @@ public class DeflateFrameExtension extends AbstractExtension
@Override @Override
public void addFrame(byte flags, byte opcode, byte[] content, int offset, int length) throws IOException public void addFrame(byte flags, byte opcode, byte[] content, int offset, int length) throws IOException
{ {
if (getConnection().isControl(opcode) && length<_minLength) if (getConnection().isControl(opcode) || length<_minLength)
{ {
super.addFrame(clearFlag(flags,0),opcode,content,offset,length); super.addFrame(clearFlag(flags,1),opcode,content,offset,length);
return; return;
} }
@ -133,8 +134,8 @@ public class DeflateFrameExtension extends AbstractExtension
int l = _deflater.deflate(out,out_offset,length-out_offset); int l = _deflater.deflate(out,out_offset,length-out_offset);
if (_deflater.finished()) if (_deflater.finished())
super.addFrame(setFlag(flags,0),opcode,out,0,l+out_offset); super.addFrame(setFlag(flags,1),opcode,out,0,l+out_offset);
else else
super.addFrame(clearFlag(flags,0),opcode,content,offset,length); super.addFrame(clearFlag(flags,1),opcode,content,offset,length);
} }
} }

View File

@ -6,11 +6,8 @@ public interface Extension extends WebSocketParser.FrameHandler, WebSocketGenera
{ {
public String getName(); public String getName();
public String getParameterizedName(); public String getParameterizedName();
public int getDataOpcodes();
public int getControlOpcodes();
public int getReservedBits();
public boolean init(Map<String,String> parameters); public boolean init(Map<String,String> parameters);
public void bind(WebSocket.FrameConnection connection, WebSocketParser.FrameHandler inbound, WebSocketGenerator outbound,byte[] dataOpCodes, byte[] controlOpcodes, byte[] bitMasks); public void bind(WebSocket.FrameConnection connection, WebSocketParser.FrameHandler inbound, WebSocketGenerator outbound);
} }

View File

@ -10,7 +10,7 @@ public class FragmentExtension extends AbstractExtension
public FragmentExtension() public FragmentExtension()
{ {
super("fragment",0,0,0); super("fragment");
} }
@Override @Override

View File

@ -4,6 +4,6 @@ public class IdentityExtension extends AbstractExtension
{ {
public IdentityExtension() public IdentityExtension()
{ {
super("identity",0,0,0); super("identity");
} }
} }

View File

@ -37,8 +37,8 @@ public class TestClient
private final BufferedWriter _output; private final BufferedWriter _output;
private final BufferedReader _input; private final BufferedReader _input;
private final SocketEndPoint _endp; private final SocketEndPoint _endp;
private final WebSocketGeneratorD07 _generator; private final WebSocketGeneratorD7_9 _generator;
private final WebSocketParserD07 _parser; private final WebSocketParserD7_9 _parser;
private int _framesSent; private int _framesSent;
private int _messagesSent; private int _messagesSent;
private int _framesReceived; private int _framesReceived;
@ -59,19 +59,19 @@ public class TestClient
{ {
_framesReceived++; _framesReceived++;
_frames++; _frames++;
if (opcode == WebSocketConnectionD07.OP_CLOSE) if (opcode == WebSocketConnectionD7_9.OP_CLOSE)
{ {
byte[] data=buffer.asArray(); byte[] data=buffer.asArray();
// System.err.println("CLOSED: "+((0xff&data[0])*0x100+(0xff&data[1]))+" "+new String(data,2,data.length-2,StringUtil.__UTF8)); // System.err.println("CLOSED: "+((0xff&data[0])*0x100+(0xff&data[1]))+" "+new String(data,2,data.length-2,StringUtil.__UTF8));
_generator.addFrame((byte)0x8,WebSocketConnectionD07.OP_CLOSE,data,0,data.length); _generator.addFrame((byte)0x8,WebSocketConnectionD7_9.OP_CLOSE,data,0,data.length);
_generator.flush(); _generator.flush();
_socket.shutdownOutput(); _socket.shutdownOutput();
_socket.close(); _socket.close();
return; return;
} }
else if (opcode == WebSocketConnectionD07.OP_PING) else if (opcode == WebSocketConnectionD7_9.OP_PING)
{ {
_generator.addFrame((byte)0x8,WebSocketConnectionD07.OP_PONG,buffer.array(),buffer.getIndex(),buffer.length()); _generator.addFrame((byte)0x8,WebSocketConnectionD7_9.OP_PONG,buffer.array(),buffer.getIndex(),buffer.length());
_generator.flush(); _generator.flush();
} }
@ -81,7 +81,7 @@ public class TestClient
_opcode=opcode; _opcode=opcode;
if (WebSocketConnectionD07.isLastFrame(flags)) if (WebSocketConnectionD7_9.isLastFrame(flags))
{ {
_messagesReceived++; _messagesReceived++;
Long start=_starts.take(); Long start=_starts.take();
@ -123,8 +123,8 @@ public class TestClient
_input = new BufferedReader(new InputStreamReader(_socket.getInputStream(), "ISO-8859-1")); _input = new BufferedReader(new InputStreamReader(_socket.getInputStream(), "ISO-8859-1"));
_endp=new SocketEndPoint(_socket); _endp=new SocketEndPoint(_socket);
_generator = new WebSocketGeneratorD07(new WebSocketBuffers(32*1024),_endp,new WebSocketGeneratorD07.FixedMaskGen(new byte[4])); _generator = new WebSocketGeneratorD7_9(new WebSocketBuffers(32*1024),_endp,new WebSocketGeneratorD7_9.FixedMaskGen(new byte[4]));
_parser = new WebSocketParserD07(new WebSocketBuffers(32*1024),_endp,_handler,false); _parser = new WebSocketParserD7_9(new WebSocketBuffers(32*1024),_endp,_handler,false);
} }
public int getSize() public int getSize()
@ -170,7 +170,7 @@ public class TestClient
if (line.startsWith("Sec-WebSocket-Accept:")) if (line.startsWith("Sec-WebSocket-Accept:"))
{ {
String accept=line.substring(21).trim(); String accept=line.substring(21).trim();
accepted=accept.equals(WebSocketConnectionD07.hashKey(new String(B64Code.encode(key)))); accepted=accept.equals(WebSocketConnectionD7_9.hashKey(new String(B64Code.encode(key))));
} }
else if (line.startsWith("Sec-WebSocket-Protocol:")) else if (line.startsWith("Sec-WebSocket-Protocol:"))
{ {
@ -205,7 +205,7 @@ public class TestClient
break; break;
byte data[]=null; byte data[]=null;
if (opcode==WebSocketConnectionD07.OP_TEXT) if (opcode==WebSocketConnectionD7_9.OP_TEXT)
{ {
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
while (b.length()<_size) while (b.length()<_size)
@ -228,7 +228,7 @@ public class TestClient
{ {
_framesSent++; _framesSent++;
byte flags= (byte)(off+len==data.length?0x8:0); byte flags= (byte)(off+len==data.length?0x8:0);
byte op=(byte)(off==0?opcode:WebSocketConnectionD07.OP_CONTINUATION); byte op=(byte)(off==0?opcode:WebSocketConnectionD7_9.OP_CONTINUATION);
if (_verbose) if (_verbose)
System.err.printf("%s#addFrame %s|%s %s\n",this.getClass().getSimpleName(),TypeUtil.toHexString(flags),TypeUtil.toHexString(op),TypeUtil.toHexString(data,off,len)); System.err.printf("%s#addFrame %s|%s %s\n",this.getClass().getSimpleName(),TypeUtil.toHexString(flags),TypeUtil.toHexString(op),TypeUtil.toHexString(data,off,len));
@ -330,9 +330,9 @@ public class TestClient
{ {
client.open(); client.open();
if (protocol!=null && protocol.startsWith("echo")) if (protocol!=null && protocol.startsWith("echo"))
client.ping(count,binary?WebSocketConnectionD07.OP_BINARY:WebSocketConnectionD07.OP_TEXT,fragment); client.ping(count,binary?WebSocketConnectionD7_9.OP_BINARY:WebSocketConnectionD7_9.OP_TEXT,fragment);
else else
client.ping(count,WebSocketConnectionD07.OP_PING,-1); client.ping(count,WebSocketConnectionD7_9.OP_PING,-1);
} }
finally finally
{ {

View File

@ -38,7 +38,7 @@ import org.eclipse.jetty.websocket.WebSocket.OnTextMessage;
import org.eclipse.jetty.websocket.WebSocket.OnBinaryMessage; import org.eclipse.jetty.websocket.WebSocket.OnBinaryMessage;
import org.eclipse.jetty.websocket.WebSocket.OnControl; import org.eclipse.jetty.websocket.WebSocket.OnControl;
public class WebSocketConnectionD07 extends AbstractConnection implements WebSocketConnection public class WebSocketConnectionD7_9 extends AbstractConnection implements WebSocketConnection
{ {
final static byte OP_CONTINUATION = 0x00; final static byte OP_CONTINUATION = 0x00;
final static byte OP_TEXT = 0x01; final static byte OP_TEXT = 0x01;
@ -69,9 +69,9 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc
private final static byte[] MAGIC; private final static byte[] MAGIC;
private final IdleCheck _idle; private final IdleCheck _idle;
private final List<Extension> _extensions; private final List<Extension> _extensions;
private final WebSocketParserD07 _parser; private final WebSocketParserD7_9 _parser;
private final WebSocketParser.FrameHandler _inbound; private final WebSocketParser.FrameHandler _inbound;
private final WebSocketGeneratorD07 _generator; private final WebSocketGeneratorD7_9 _generator;
private final WebSocketGenerator _outbound; private final WebSocketGenerator _outbound;
private final WebSocket _webSocket; private final WebSocket _webSocket;
private final OnFrame _onFrame; private final OnFrame _onFrame;
@ -79,6 +79,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc
private final OnTextMessage _onTextMessage; private final OnTextMessage _onTextMessage;
private final OnControl _onControl; private final OnControl _onControl;
private final String _protocol; private final String _protocol;
private final int _draft;
private boolean _closedIn; private boolean _closedIn;
private boolean _closedOut; private boolean _closedOut;
private int _maxTextMessageSize; private int _maxTextMessageSize;
@ -106,7 +107,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public WebSocketConnectionD07(WebSocket websocket, EndPoint endpoint, WebSocketBuffers buffers, long timestamp, int maxIdleTime, String protocol, List<Extension> extensions) public WebSocketConnectionD7_9(WebSocket websocket, EndPoint endpoint, WebSocketBuffers buffers, long timestamp, int maxIdleTime, String protocol, List<Extension> extensions,int draft)
throws IOException throws IOException
{ {
super(endpoint,timestamp); super(endpoint,timestamp);
@ -115,6 +116,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc
if (endpoint instanceof AsyncEndPoint) if (endpoint instanceof AsyncEndPoint)
((AsyncEndPoint)endpoint).cancelIdle(); ((AsyncEndPoint)endpoint).cancelIdle();
_draft=draft;
_endp.setMaxIdleTime(maxIdleTime); _endp.setMaxIdleTime(maxIdleTime);
_webSocket = websocket; _webSocket = websocket;
@ -122,35 +124,18 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc
_onTextMessage=_webSocket instanceof OnTextMessage ? (OnTextMessage)_webSocket : null; _onTextMessage=_webSocket instanceof OnTextMessage ? (OnTextMessage)_webSocket : null;
_onBinaryMessage=_webSocket instanceof OnBinaryMessage ? (OnBinaryMessage)_webSocket : null; _onBinaryMessage=_webSocket instanceof OnBinaryMessage ? (OnBinaryMessage)_webSocket : null;
_onControl=_webSocket instanceof OnControl ? (OnControl)_webSocket : null; _onControl=_webSocket instanceof OnControl ? (OnControl)_webSocket : null;
_generator = new WebSocketGeneratorD07(buffers, _endp,null); _generator = new WebSocketGeneratorD7_9(buffers, _endp,null);
_extensions=extensions; _extensions=extensions;
if (_extensions!=null) if (_extensions!=null)
{ {
byte data_op=OP_EXT_DATA;
byte ctrl_op=OP_EXT_CTRL;
byte flag_mask=0x4;
int e=0; int e=0;
for (Extension extension : _extensions) for (Extension extension : _extensions)
{ {
byte[] data_ops=new byte[extension.getDataOpcodes()];
for (int i=0;i<data_ops.length;i++)
data_ops[i]=data_op++;
byte[] ctrl_ops=new byte[extension.getControlOpcodes()];
for (int i=0;i<ctrl_ops.length;i++)
ctrl_ops[i]=ctrl_op++;
byte[] flag_masks=new byte[extension.getReservedBits()];
for (int i=0;i<flag_masks.length;i++)
{
flag_masks[i]=flag_mask;
flag_mask= (byte)(flag_mask>>1);
}
extension.bind( extension.bind(
_connection, _connection,
e==extensions.size()-1?_frameHandler:extensions.get(e+1), e==extensions.size()-1?_frameHandler:extensions.get(e+1),
e==0?_generator:extensions.get(e-1), e==0?_generator:extensions.get(e-1));
data_ops,ctrl_ops,flag_masks);
e++; e++;
} }
} }
@ -158,7 +143,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc
_outbound=_extensions.size()==0?_generator:extensions.get(extensions.size()-1); _outbound=_extensions.size()==0?_generator:extensions.get(extensions.size()-1);
_inbound=_extensions.size()==0?_frameHandler:extensions.get(0); _inbound=_extensions.size()==0?_frameHandler:extensions.get(0);
_parser = new WebSocketParserD07(buffers, endpoint,_inbound,true); _parser = new WebSocketParserD7_9(buffers, endpoint,_inbound,true);
_protocol=protocol; _protocol=protocol;
@ -266,7 +251,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc
@Override @Override
public void idleExpired() public void idleExpired()
{ {
closeOut(WebSocketConnectionD07.CLOSE_NORMAL,"Idle"); closeOut(WebSocketConnectionD7_9.CLOSE_NORMAL,"Idle");
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -278,7 +263,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public void closed() public void closed()
{ {
_webSocket.onClose(WebSocketConnectionD07.CLOSE_NORMAL,""); _webSocket.onClose(WebSocketConnectionD7_9.CLOSE_NORMAL,"");
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -313,11 +298,11 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc
else else
{ {
if (code<=0) if (code<=0)
code=WebSocketConnectionD07.CLOSE_NORMAL; code=WebSocketConnectionD7_9.CLOSE_NORMAL;
byte[] bytes = ("xx"+(message==null?"":message)).getBytes(StringUtil.__ISO_8859_1); byte[] bytes = ("xx"+(message==null?"":message)).getBytes(StringUtil.__ISO_8859_1);
bytes[0]=(byte)(code/0x100); bytes[0]=(byte)(code/0x100);
bytes[1]=(byte)(code%0x100); bytes[1]=(byte)(code%0x100);
_outbound.addFrame((byte)0x8,WebSocketConnectionD07.OP_CLOSE,bytes,0,bytes.length); _outbound.addFrame((byte)0x8,WebSocketConnectionD7_9.OP_CLOSE,bytes,0,bytes.length);
} }
_outbound.flush(); _outbound.flush();
@ -353,8 +338,8 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc
private class FrameConnectionD07 implements WebSocket.FrameConnection private class FrameConnectionD07 implements WebSocket.FrameConnection
{ {
volatile boolean _disconnecting; volatile boolean _disconnecting;
int _maxTextMessage=WebSocketConnectionD07.this._maxTextMessageSize; int _maxTextMessage=WebSocketConnectionD7_9.this._maxTextMessageSize;
int _maxBinaryMessage=WebSocketConnectionD07.this._maxBinaryMessageSize; int _maxBinaryMessage=WebSocketConnectionD7_9.this._maxBinaryMessageSize;
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public synchronized void sendMessage(String content) throws IOException public synchronized void sendMessage(String content) throws IOException
@ -362,7 +347,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc
if (_closedOut) if (_closedOut)
throw new IOException("closing"); throw new IOException("closing");
byte[] data = content.getBytes(StringUtil.__UTF8); byte[] data = content.getBytes(StringUtil.__UTF8);
_outbound.addFrame((byte)0x8,WebSocketConnectionD07.OP_TEXT,data,0,data.length); _outbound.addFrame((byte)0x8,WebSocketConnectionD7_9.OP_TEXT,data,0,data.length);
checkWriteable(); checkWriteable();
_idle.access(_endp); _idle.access(_endp);
} }
@ -372,7 +357,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc
{ {
if (_closedOut) if (_closedOut)
throw new IOException("closing"); throw new IOException("closing");
_outbound.addFrame((byte)0x8,WebSocketConnectionD07.OP_BINARY,content,offset,length); _outbound.addFrame((byte)0x8,WebSocketConnectionD7_9.OP_BINARY,content,offset,length);
checkWriteable(); checkWriteable();
_idle.access(_endp); _idle.access(_endp);
} }
@ -415,7 +400,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc
if (_disconnecting) if (_disconnecting)
return; return;
_disconnecting=true; _disconnecting=true;
WebSocketConnectionD07.this.closeOut(code,message); WebSocketConnectionD7_9.this.closeOut(code,message);
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -540,7 +525,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc
{ {
boolean lastFrame = isLastFrame(flags); boolean lastFrame = isLastFrame(flags);
synchronized(WebSocketConnectionD07.this) synchronized(WebSocketConnectionD7_9.this)
{ {
// Ignore incoming after a close // Ignore incoming after a close
if (_closedIn) if (_closedIn)
@ -565,10 +550,10 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc
switch(opcode) switch(opcode)
{ {
case WebSocketConnectionD07.OP_CONTINUATION: case WebSocketConnectionD7_9.OP_CONTINUATION:
{ {
// If text, append to the message buffer // If text, append to the message buffer
if (_opcode==WebSocketConnectionD07.OP_TEXT && _connection.getMaxTextMessageSize()>=0) if (_opcode==WebSocketConnectionD7_9.OP_TEXT && _connection.getMaxTextMessageSize()>=0)
{ {
if (_utf8.append(buffer.array(),buffer.getIndex(),buffer.length(),_connection.getMaxTextMessageSize())) if (_utf8.append(buffer.array(),buffer.getIndex(),buffer.length(),_connection.getMaxTextMessageSize()))
{ {
@ -583,7 +568,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc
} }
else else
{ {
_connection.close(WebSocketConnectionD07.CLOSE_LARGE,"Text message size > "+_connection.getMaxTextMessageSize()+" chars"); _connection.close(WebSocketConnectionD7_9.CLOSE_LARGE,"Text message size > "+_connection.getMaxTextMessageSize()+" chars");
_utf8.reset(); _utf8.reset();
_opcode=-1; _opcode=-1;
} }
@ -592,7 +577,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc
{ {
if (_aggregate.space()<_aggregate.length()) if (_aggregate.space()<_aggregate.length())
{ {
_connection.close(WebSocketConnectionD07.CLOSE_LARGE,"Message size > "+_connection.getMaxBinaryMessageSize()); _connection.close(WebSocketConnectionD7_9.CLOSE_LARGE,"Message size > "+_connection.getMaxBinaryMessageSize());
_aggregate.clear(); _aggregate.clear();
_opcode=-1; _opcode=-1;
} }
@ -617,21 +602,21 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc
} }
break; break;
} }
case WebSocketConnectionD07.OP_PING: case WebSocketConnectionD7_9.OP_PING:
{ {
Log.debug("PING {}",this); Log.debug("PING {}",this);
if (!_closedOut) if (!_closedOut)
_connection.sendControl(WebSocketConnectionD07.OP_PONG,buffer.array(),buffer.getIndex(),buffer.length()); _connection.sendControl(WebSocketConnectionD7_9.OP_PONG,buffer.array(),buffer.getIndex(),buffer.length());
break; break;
} }
case WebSocketConnectionD07.OP_PONG: case WebSocketConnectionD7_9.OP_PONG:
{ {
Log.debug("PONG {}",this); Log.debug("PONG {}",this);
break; break;
} }
case WebSocketConnectionD07.OP_CLOSE: case WebSocketConnectionD7_9.OP_CLOSE:
{ {
int code=-1; int code=-1;
String message=null; String message=null;
@ -646,7 +631,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc
} }
case WebSocketConnectionD07.OP_TEXT: case WebSocketConnectionD7_9.OP_TEXT:
{ {
if(_onTextMessage!=null) if(_onTextMessage!=null)
{ {
@ -661,12 +646,12 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc
{ {
// If this is a text fragment, append to buffer // If this is a text fragment, append to buffer
if (_utf8.append(buffer.array(),buffer.getIndex(),buffer.length(),_connection.getMaxTextMessageSize())) if (_utf8.append(buffer.array(),buffer.getIndex(),buffer.length(),_connection.getMaxTextMessageSize()))
_opcode=WebSocketConnectionD07.OP_TEXT; _opcode=WebSocketConnectionD7_9.OP_TEXT;
else else
{ {
_utf8.reset(); _utf8.reset();
_opcode=-1; _opcode=-1;
_connection.close(WebSocketConnectionD07.CLOSE_LARGE,"Text message size > "+_connection.getMaxTextMessageSize()+" chars"); _connection.close(WebSocketConnectionD7_9.CLOSE_LARGE,"Text message size > "+_connection.getMaxTextMessageSize()+" chars");
} }
} }
} }
@ -688,7 +673,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc
{ {
if (buffer.length()>_connection.getMaxBinaryMessageSize()) if (buffer.length()>_connection.getMaxBinaryMessageSize())
{ {
_connection.close(WebSocketConnectionD07.CLOSE_LARGE,"Message size > "+_connection.getMaxBinaryMessageSize()); _connection.close(WebSocketConnectionD7_9.CLOSE_LARGE,"Message size > "+_connection.getMaxBinaryMessageSize());
if (_aggregate!=null) if (_aggregate!=null)
_aggregate.clear(); _aggregate.clear();
_opcode=-1; _opcode=-1;
@ -726,7 +711,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc
public String toString() public String toString()
{ {
return WebSocketConnectionD07.this.toString()+"FH"; return WebSocketConnectionD7_9.this.toString()+"FH";
} }
} }
@ -776,4 +761,10 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
/* ------------------------------------------------------------ */
public String toString()
{
return "WS/D"+_draft+"-"+_endp;
}
} }

View File

@ -164,8 +164,10 @@ public class WebSocketFactory
connection = new WebSocketConnectionD06(websocket, endp, _buffers, http.getTimeStamp(), _maxIdleTime, protocol); connection = new WebSocketConnectionD06(websocket, endp, _buffers, http.getTimeStamp(), _maxIdleTime, protocol);
break; break;
case 7: case 7:
extensions= initExtensions(extensions_requested,8-WebSocketConnectionD07.OP_EXT_DATA, 16-WebSocketConnectionD07.OP_EXT_CTRL,3); case 8:
connection = new WebSocketConnectionD07(websocket, endp, _buffers, http.getTimeStamp(), _maxIdleTime, protocol,extensions); case 9:
extensions= initExtensions(extensions_requested,8-WebSocketConnectionD7_9.OP_EXT_DATA, 16-WebSocketConnectionD7_9.OP_EXT_CTRL,3);
connection = new WebSocketConnectionD7_9(websocket, endp, _buffers, http.getTimeStamp(), _maxIdleTime, protocol,extensions,draft);
break; break;
default: default:
Log.warn("Unsupported Websocket version: "+draft); Log.warn("Unsupported Websocket version: "+draft);
@ -256,14 +258,8 @@ public class WebSocketFactory
if (extension.init(parameters)) if (extension.init(parameters))
{ {
if (extension.getDataOpcodes()<=maxDataOpcodes && extension.getControlOpcodes()<=maxControlOpcodes && extension.getReservedBits()<=maxReservedBits) Log.debug("add {} {}",extName,parameters);
{ extensions.add(extension);
Log.debug("add {} {}",extName,parameters);
extensions.add(extension);
maxDataOpcodes-=extension.getDataOpcodes();
maxControlOpcodes-=extension.getControlOpcodes();
maxReservedBits-=extension.getReservedBits();
}
} }
} }
Log.debug("extensions={}",extensions); Log.debug("extensions={}",extensions);

View File

@ -30,7 +30,7 @@ import org.eclipse.jetty.util.TypeUtil;
* threads will call the addMessage methods while other * threads will call the addMessage methods while other
* threads are flushing the generator. * threads are flushing the generator.
*/ */
public class WebSocketGeneratorD07 implements WebSocketGenerator public class WebSocketGeneratorD7_9 implements WebSocketGenerator
{ {
final private WebSocketBuffers _buffers; final private WebSocketBuffers _buffers;
final private EndPoint _endp; final private EndPoint _endp;
@ -95,14 +95,14 @@ public class WebSocketGeneratorD07 implements WebSocketGenerator
} }
public WebSocketGeneratorD07(WebSocketBuffers buffers, EndPoint endp) public WebSocketGeneratorD7_9(WebSocketBuffers buffers, EndPoint endp)
{ {
_buffers=buffers; _buffers=buffers;
_endp=endp; _endp=endp;
_maskGen=null; _maskGen=null;
} }
public WebSocketGeneratorD07(WebSocketBuffers buffers, EndPoint endp, MaskGen maskGen) public WebSocketGeneratorD7_9(WebSocketBuffers buffers, EndPoint endp, MaskGen maskGen)
{ {
_buffers=buffers; _buffers=buffers;
_endp=endp; _endp=endp;
@ -118,14 +118,14 @@ public class WebSocketGeneratorD07 implements WebSocketGenerator
if (_buffer==null) if (_buffer==null)
_buffer=mask?_buffers.getBuffer():_buffers.getDirectBuffer(); _buffer=mask?_buffers.getBuffer():_buffers.getDirectBuffer();
boolean last=WebSocketConnectionD07.isLastFrame(flags); boolean last=WebSocketConnectionD7_9.isLastFrame(flags);
byte orig=opcode; byte orig=opcode;
int space=mask?14:10; int space=mask?14:10;
do do
{ {
opcode = _opsent?WebSocketConnectionD07.OP_CONTINUATION:opcode; opcode = _opsent?WebSocketConnectionD7_9.OP_CONTINUATION:opcode;
opcode=(byte)(((0xf&flags)<<4)+(0xf&opcode)); opcode=(byte)(((0xf&flags)<<4)+(0xf&opcode));
_opsent=true; _opsent=true;

View File

@ -29,7 +29,7 @@ import org.eclipse.jetty.util.log.Log;
* Parser the WebSocket protocol. * Parser the WebSocket protocol.
* *
*/ */
public class WebSocketParserD07 implements WebSocketParser public class WebSocketParserD7_9 implements WebSocketParser
{ {
public enum State { public enum State {
@ -72,7 +72,7 @@ public class WebSocketParserD07 implements WebSocketParser
* @param endp * @param endp
* @param handler * @param handler
*/ */
public WebSocketParserD07(WebSocketBuffers buffers, EndPoint endp, FrameHandler handler, boolean shouldBeMasked) public WebSocketParserD7_9(WebSocketBuffers buffers, EndPoint endp, FrameHandler handler, boolean shouldBeMasked)
{ {
_buffers=buffers; _buffers=buffers;
_endp=endp; _endp=endp;
@ -160,11 +160,11 @@ public class WebSocketParserD07 implements WebSocketParser
_opcode=(byte)(b&0xf); _opcode=(byte)(b&0xf);
_flags=(byte)(0xf&(b>>4)); _flags=(byte)(0xf&(b>>4));
if (WebSocketConnectionD07.isControlFrame(_opcode)&&!WebSocketConnectionD07.isLastFrame(_flags)) if (WebSocketConnectionD7_9.isControlFrame(_opcode)&&!WebSocketConnectionD7_9.isLastFrame(_flags))
{ {
events++; events++;
Log.warn("Fragmented Control from "+_endp); Log.warn("Fragmented Control from "+_endp);
_handler.close(WebSocketConnectionD07.CLOSE_PROTOCOL,"Fragmented control"); _handler.close(WebSocketConnectionD7_9.CLOSE_PROTOCOL,"Fragmented control");
_skip=true; _skip=true;
} }
@ -205,7 +205,7 @@ public class WebSocketParserD07 implements WebSocketParser
if (_length>_buffer.capacity()) if (_length>_buffer.capacity())
{ {
events++; events++;
_handler.close(WebSocketConnectionD07.CLOSE_LARGE,"frame size "+_length+">"+_buffer.capacity()); _handler.close(WebSocketConnectionD7_9.CLOSE_LARGE,"frame size "+_length+">"+_buffer.capacity());
_skip=true; _skip=true;
} }
@ -224,7 +224,7 @@ public class WebSocketParserD07 implements WebSocketParser
if (_length>=_buffer.capacity()) if (_length>=_buffer.capacity())
{ {
events++; events++;
_handler.close(WebSocketConnectionD07.CLOSE_LARGE,"frame size "+_length+">"+_buffer.capacity()); _handler.close(WebSocketConnectionD7_9.CLOSE_LARGE,"frame size "+_length+">"+_buffer.capacity());
_skip=true; _skip=true;
} }
@ -267,7 +267,7 @@ public class WebSocketParserD07 implements WebSocketParser
_buffer.skip(_bytesNeeded); _buffer.skip(_bytesNeeded);
_state=State.START; _state=State.START;
events++; events++;
_handler.close(WebSocketConnectionD07.CLOSE_PROTOCOL,"bad mask"); _handler.close(WebSocketConnectionD7_9.CLOSE_PROTOCOL,"bad mask");
} }
else else
{ {

View File

@ -11,7 +11,7 @@ import org.junit.Test;
/** /**
* @version $Revision$ $Date$ * @version $Revision$ $Date$
*/ */
public class WebSocketGeneratorD07Test public class WebSocketGeneratorD7_9Test
{ {
private ByteArrayBuffer _out; private ByteArrayBuffer _out;
private WebSocketGenerator _generator; private WebSocketGenerator _generator;
@ -20,7 +20,7 @@ public class WebSocketGeneratorD07Test
byte[] _mask = new byte[4]; byte[] _mask = new byte[4];
int _m; int _m;
public WebSocketGeneratorD07.MaskGen _maskGen = new WebSocketGeneratorD07.FixedMaskGen( public WebSocketGeneratorD7_9.MaskGen _maskGen = new WebSocketGeneratorD7_9.FixedMaskGen(
new byte[]{(byte)0x00,(byte)0x00,(byte)0x0f,(byte)0xff}); new byte[]{(byte)0x00,(byte)0x00,(byte)0x0f,(byte)0xff});
@Before @Before
@ -42,7 +42,7 @@ public class WebSocketGeneratorD07Test
@Test @Test
public void testOneString() throws Exception public void testOneString() throws Exception
{ {
_generator = new WebSocketGeneratorD07(_buffers, _endPoint,null); _generator = new WebSocketGeneratorD7_9(_buffers, _endPoint,null);
byte[] data = "Hell\uFF4F W\uFF4Frld".getBytes(StringUtil.__UTF8); byte[] data = "Hell\uFF4F W\uFF4Frld".getBytes(StringUtil.__UTF8);
_generator.addFrame((byte)0x8,(byte)0x04,data,0,data.length); _generator.addFrame((byte)0x8,(byte)0x04,data,0,data.length);
@ -69,7 +69,7 @@ public class WebSocketGeneratorD07Test
@Test @Test
public void testOneBuffer() throws Exception public void testOneBuffer() throws Exception
{ {
_generator = new WebSocketGeneratorD07(_buffers, _endPoint,null); _generator = new WebSocketGeneratorD7_9(_buffers, _endPoint,null);
String string = "Hell\uFF4F W\uFF4Frld"; String string = "Hell\uFF4F W\uFF4Frld";
byte[] bytes=string.getBytes(StringUtil.__UTF8); byte[] bytes=string.getBytes(StringUtil.__UTF8);
@ -97,7 +97,7 @@ public class WebSocketGeneratorD07Test
@Test @Test
public void testOneLongBuffer() throws Exception public void testOneLongBuffer() throws Exception
{ {
_generator = new WebSocketGeneratorD07(_buffers, _endPoint,null); _generator = new WebSocketGeneratorD7_9(_buffers, _endPoint,null);
byte[] b=new byte[150]; byte[] b=new byte[150];
for (int i=0;i<b.length;i++) for (int i=0;i<b.length;i++)
@ -118,7 +118,7 @@ public class WebSocketGeneratorD07Test
@Test @Test
public void testOneStringMasked() throws Exception public void testOneStringMasked() throws Exception
{ {
_generator = new WebSocketGeneratorD07(_buffers, _endPoint,_maskGen); _generator = new WebSocketGeneratorD7_9(_buffers, _endPoint,_maskGen);
byte[] data = "Hell\uFF4F W\uFF4Frld".getBytes(StringUtil.__UTF8); byte[] data = "Hell\uFF4F W\uFF4Frld".getBytes(StringUtil.__UTF8);
_generator.addFrame((byte)0x8,(byte)0x04,data,0,data.length); _generator.addFrame((byte)0x8,(byte)0x04,data,0,data.length);
@ -147,7 +147,7 @@ public class WebSocketGeneratorD07Test
@Test @Test
public void testOneBufferMasked() throws Exception public void testOneBufferMasked() throws Exception
{ {
_generator = new WebSocketGeneratorD07(_buffers, _endPoint,_maskGen); _generator = new WebSocketGeneratorD7_9(_buffers, _endPoint,_maskGen);
String string = "Hell\uFF4F W\uFF4Frld"; String string = "Hell\uFF4F W\uFF4Frld";
byte[] bytes=string.getBytes(StringUtil.__UTF8); byte[] bytes=string.getBytes(StringUtil.__UTF8);
@ -177,7 +177,7 @@ public class WebSocketGeneratorD07Test
@Test @Test
public void testOneLongBufferMasked() throws Exception public void testOneLongBufferMasked() throws Exception
{ {
_generator = new WebSocketGeneratorD07(_buffers, _endPoint,_maskGen); _generator = new WebSocketGeneratorD7_9(_buffers, _endPoint,_maskGen);
byte[] b=new byte[150]; byte[] b=new byte[150];
for (int i=0;i<b.length;i++) for (int i=0;i<b.length;i++)

View File

@ -33,7 +33,7 @@ import org.junit.Test;
/** /**
* @version $Revision$ $Date$ * @version $Revision$ $Date$
*/ */
public class WebSocketLoadD07Test public class WebSocketLoadD7_9Test
{ {
private static Server _server; private static Server _server;
private static Connector _connector; private static Connector _connector;
@ -142,8 +142,8 @@ public class WebSocketLoadD07Test
private final int iterations; private final int iterations;
private final CountDownLatch latch; private final CountDownLatch latch;
private final SocketEndPoint _endp; private final SocketEndPoint _endp;
private final WebSocketGeneratorD07 _generator; private final WebSocketGeneratorD7_9 _generator;
private final WebSocketParserD07 _parser; private final WebSocketParserD7_9 _parser;
private final WebSocketParser.FrameHandler _handler = new WebSocketParser.FrameHandler() private final WebSocketParser.FrameHandler _handler = new WebSocketParser.FrameHandler()
{ {
public void onFrame(byte flags, byte opcode, Buffer buffer) public void onFrame(byte flags, byte opcode, Buffer buffer)
@ -167,8 +167,8 @@ public class WebSocketLoadD07Test
this.iterations = iterations; this.iterations = iterations;
_endp=new SocketEndPoint(socket); _endp=new SocketEndPoint(socket);
_generator = new WebSocketGeneratorD07(new WebSocketBuffers(32*1024),_endp,new WebSocketGeneratorD07.FixedMaskGen()); _generator = new WebSocketGeneratorD7_9(new WebSocketBuffers(32*1024),_endp,new WebSocketGeneratorD7_9.FixedMaskGen());
_parser = new WebSocketParserD07(new WebSocketBuffers(32*1024),_endp,_handler,false); _parser = new WebSocketParserD7_9(new WebSocketBuffers(32*1024),_endp,_handler,false);
} }
@ -202,7 +202,7 @@ public class WebSocketLoadD07Test
for (int i = 0; i < iterations; ++i) for (int i = 0; i < iterations; ++i)
{ {
byte[] data = message.getBytes(StringUtil.__UTF8); byte[] data = message.getBytes(StringUtil.__UTF8);
_generator.addFrame((byte)0x8,WebSocketConnectionD07.OP_TEXT,data,0,data.length); _generator.addFrame((byte)0x8,WebSocketConnectionD7_9.OP_TEXT,data,0,data.length);
_generator.flush(); _generator.flush();
//System.err.println("-> "+message); //System.err.println("-> "+message);

View File

@ -34,7 +34,7 @@ import org.junit.Test;
/** /**
* @version $Revision$ $Date$ * @version $Revision$ $Date$
*/ */
public class WebSocketMessageD07Test public class WebSocketMessageD7_9Test
{ {
private static Server _server; private static Server _server;
private static Connector _connector; private static Connector _connector;
@ -75,7 +75,7 @@ public class WebSocketMessageD07Test
@Test @Test
public void testHash() public void testHash()
{ {
assertEquals("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",WebSocketConnectionD07.hashKey("dGhlIHNhbXBsZSBub25jZQ==")); assertEquals("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",WebSocketConnectionD7_9.hashKey("dGhlIHNhbXBsZSBub25jZQ=="));
} }
@Test @Test
@ -116,7 +116,7 @@ public class WebSocketMessageD07Test
String data=message.toString(); String data=message.toString();
_serverWebSocket.connection.sendMessage(data); _serverWebSocket.connection.sendMessage(data);
assertEquals(WebSocketConnectionD07.OP_TEXT,input.read()); assertEquals(WebSocketConnectionD7_9.OP_TEXT,input.read());
assertEquals(0x7e,input.read()); assertEquals(0x7e,input.read());
assertEquals(0x1f,input.read()); assertEquals(0x1f,input.read());
assertEquals(0xf6,input.read()); assertEquals(0xf6,input.read());
@ -272,7 +272,7 @@ public class WebSocketMessageD07Test
"Sec-WebSocket-Origin: http://example.com\r\n"+ "Sec-WebSocket-Origin: http://example.com\r\n"+
"Sec-WebSocket-Protocol: echo\r\n" + "Sec-WebSocket-Protocol: echo\r\n" +
"Sec-WebSocket-Version: 7\r\n"+ "Sec-WebSocket-Version: 7\r\n"+
"Sec-WebSocket-Extensions: x-deflate-frame\r\n"+ "Sec-WebSocket-Extensions: x-deflate-frame;minLength=64\r\n"+
"Sec-WebSocket-Extensions: fragment;minFragments=2\r\n"+ "Sec-WebSocket-Extensions: fragment;minFragments=2\r\n"+
"\r\n").getBytes("ISO-8859-1")); "\r\n").getBytes("ISO-8859-1"));
output.flush(); output.flush();
@ -322,8 +322,7 @@ public class WebSocketMessageD07Test
output.write(buf,0,l+3); output.write(buf,0,l+3);
output.flush(); output.flush();
assertEquals(0x40+WebSocketConnectionD7_9.OP_TEXT,input.read());
assertEquals(0x40+WebSocketConnectionD07.OP_TEXT,input.read());
assertEquals(0x20+3,input.read()); assertEquals(0x20+3,input.read());
assertEquals(0x7e,input.read()); assertEquals(0x7e,input.read());
assertEquals(0x02,input.read()); assertEquals(0x02,input.read());
@ -491,7 +490,7 @@ public class WebSocketMessageD07Test
output.write(bytes[i]^0xff); output.write(bytes[i]^0xff);
output.flush(); output.flush();
assertEquals(0x80|WebSocketConnectionD07.OP_CLOSE,input.read()); assertEquals(0x80|WebSocketConnectionD7_9.OP_CLOSE,input.read());
assertEquals(30,input.read()); assertEquals(30,input.read());
int code=(0xff&input.read())*0x100+(0xff&input.read()); int code=(0xff&input.read())*0x100+(0xff&input.read());
assertEquals(1004,code); assertEquals(1004,code);
@ -542,7 +541,7 @@ public class WebSocketMessageD07Test
assertEquals(0x80|WebSocketConnectionD07.OP_CLOSE,input.read()); assertEquals(0x80|WebSocketConnectionD7_9.OP_CLOSE,input.read());
assertEquals(30,input.read()); assertEquals(30,input.read());
int code=(0xff&input.read())*0x100+(0xff&input.read()); int code=(0xff&input.read())*0x100+(0xff&input.read());
assertEquals(1004,code); assertEquals(1004,code);
@ -578,7 +577,7 @@ public class WebSocketMessageD07Test
assertNotNull(_serverWebSocket.connection); assertNotNull(_serverWebSocket.connection);
_serverWebSocket.getConnection().setMaxBinaryMessageSize(1024); _serverWebSocket.getConnection().setMaxBinaryMessageSize(1024);
output.write(WebSocketConnectionD07.OP_BINARY); output.write(WebSocketConnectionD7_9.OP_BINARY);
output.write(0x8a); output.write(0x8a);
output.write(0xff); output.write(0xff);
output.write(0xff); output.write(0xff);
@ -599,7 +598,7 @@ public class WebSocketMessageD07Test
output.write(bytes[i]^0xff); output.write(bytes[i]^0xff);
output.flush(); output.flush();
assertEquals(0x80+WebSocketConnectionD07.OP_BINARY,input.read()); assertEquals(0x80+WebSocketConnectionD7_9.OP_BINARY,input.read());
assertEquals(20,input.read()); assertEquals(20,input.read());
lookFor("01234567890123456789",input); lookFor("01234567890123456789",input);
} }
@ -656,7 +655,7 @@ public class WebSocketMessageD07Test
output.flush(); output.flush();
assertEquals(0x80|WebSocketConnectionD07.OP_CLOSE,input.read()); assertEquals(0x80|WebSocketConnectionD7_9.OP_CLOSE,input.read());
assertEquals(19,input.read()); assertEquals(19,input.read());
int code=(0xff&input.read())*0x100+(0xff&input.read()); int code=(0xff&input.read())*0x100+(0xff&input.read());
assertEquals(1004,code); assertEquals(1004,code);
@ -705,7 +704,7 @@ public class WebSocketMessageD07Test
output.write(bytes[i]^0xff); output.write(bytes[i]^0xff);
output.flush(); output.flush();
assertEquals(0x80|WebSocketConnectionD07.OP_CLOSE,input.read()); assertEquals(0x80|WebSocketConnectionD7_9.OP_CLOSE,input.read());
assertEquals(19,input.read()); assertEquals(19,input.read());
int code=(0xff&input.read())*0x100+(0xff&input.read()); int code=(0xff&input.read())*0x100+(0xff&input.read());
assertEquals(1004,code); assertEquals(1004,code);
@ -831,14 +830,14 @@ public class WebSocketMessageD07Test
final AtomicReference<String> received = new AtomicReference<String>(); final AtomicReference<String> received = new AtomicReference<String>();
ByteArrayEndPoint endp = new ByteArrayEndPoint(new byte[0],4096); ByteArrayEndPoint endp = new ByteArrayEndPoint(new byte[0],4096);
WebSocketGeneratorD07 gen = new WebSocketGeneratorD07(new WebSocketBuffers(8096),endp,null); WebSocketGeneratorD7_9 gen = new WebSocketGeneratorD7_9(new WebSocketBuffers(8096),endp,null);
byte[] data = message.getBytes(StringUtil.__UTF8); byte[] data = message.getBytes(StringUtil.__UTF8);
gen.addFrame((byte)0x8,(byte)0x4,data,0,data.length); gen.addFrame((byte)0x8,(byte)0x4,data,0,data.length);
endp = new ByteArrayEndPoint(endp.getOut().asArray(),4096); endp = new ByteArrayEndPoint(endp.getOut().asArray(),4096);
WebSocketParserD07 parser = new WebSocketParserD07(new WebSocketBuffers(8096),endp,new WebSocketParser.FrameHandler() WebSocketParserD7_9 parser = new WebSocketParserD7_9(new WebSocketBuffers(8096),endp,new WebSocketParser.FrameHandler()
{ {
public void onFrame(byte flags, byte opcode, Buffer buffer) public void onFrame(byte flags, byte opcode, Buffer buffer)
{ {
@ -863,15 +862,15 @@ public class WebSocketMessageD07Test
final AtomicReference<String> received = new AtomicReference<String>(); final AtomicReference<String> received = new AtomicReference<String>();
ByteArrayEndPoint endp = new ByteArrayEndPoint(new byte[0],4096); ByteArrayEndPoint endp = new ByteArrayEndPoint(new byte[0],4096);
WebSocketGeneratorD07.MaskGen maskGen = new WebSocketGeneratorD07.RandomMaskGen(); WebSocketGeneratorD7_9.MaskGen maskGen = new WebSocketGeneratorD7_9.RandomMaskGen();
WebSocketGeneratorD07 gen = new WebSocketGeneratorD07(new WebSocketBuffers(8096),endp,maskGen); WebSocketGeneratorD7_9 gen = new WebSocketGeneratorD7_9(new WebSocketBuffers(8096),endp,maskGen);
byte[] data = message.getBytes(StringUtil.__UTF8); byte[] data = message.getBytes(StringUtil.__UTF8);
gen.addFrame((byte)0x8,(byte)0x1,data,0,data.length); gen.addFrame((byte)0x8,(byte)0x1,data,0,data.length);
endp = new ByteArrayEndPoint(endp.getOut().asArray(),4096); endp = new ByteArrayEndPoint(endp.getOut().asArray(),4096);
WebSocketParserD07 parser = new WebSocketParserD07(new WebSocketBuffers(8096),endp,new WebSocketParser.FrameHandler() WebSocketParserD7_9 parser = new WebSocketParserD7_9(new WebSocketBuffers(8096),endp,new WebSocketParser.FrameHandler()
{ {
public void onFrame(byte flags, byte opcode, Buffer buffer) public void onFrame(byte flags, byte opcode, Buffer buffer)
{ {
@ -994,9 +993,9 @@ public class WebSocketMessageD07Test
{ {
switch(opcode) switch(opcode)
{ {
case WebSocketConnectionD07.OP_CLOSE: case WebSocketConnectionD7_9.OP_CLOSE:
case WebSocketConnectionD07.OP_PING: case WebSocketConnectionD7_9.OP_PING:
case WebSocketConnectionD07.OP_PONG: case WebSocketConnectionD7_9.OP_PONG:
break; break;
default: default:

View File

@ -20,7 +20,7 @@ import org.junit.Test;
/** /**
* @version $Revision$ $Date$ * @version $Revision$ $Date$
*/ */
public class WebSocketParserD07Test public class WebSocketParserD7_9Test
{ {
private MaskedByteArrayBuffer _in; private MaskedByteArrayBuffer _in;
private Handler _handler; private Handler _handler;
@ -87,7 +87,7 @@ public class WebSocketParserD07Test
ByteArrayEndPoint endPoint = new ByteArrayEndPoint(); ByteArrayEndPoint endPoint = new ByteArrayEndPoint();
endPoint.setNonBlocking(true); endPoint.setNonBlocking(true);
_handler = new Handler(); _handler = new Handler();
_parser=new WebSocketParserD07(buffers, endPoint,_handler,true); _parser=new WebSocketParserD7_9(buffers, endPoint,_handler,true);
_in = new MaskedByteArrayBuffer(); _in = new MaskedByteArrayBuffer();
endPoint.setIn(_in); endPoint.setIn(_in);
@ -187,7 +187,7 @@ public class WebSocketParserD07Test
{ {
WebSocketBuffers buffers = new WebSocketBuffers(0x20000); WebSocketBuffers buffers = new WebSocketBuffers(0x20000);
ByteArrayEndPoint endPoint = new ByteArrayEndPoint(); ByteArrayEndPoint endPoint = new ByteArrayEndPoint();
WebSocketParser parser=new WebSocketParserD07(buffers, endPoint,_handler,false); WebSocketParser parser=new WebSocketParserD7_9(buffers, endPoint,_handler,false);
ByteArrayBuffer in = new ByteArrayBuffer(0x20000); ByteArrayBuffer in = new ByteArrayBuffer(0x20000);
endPoint.setIn(in); endPoint.setIn(in);
@ -261,7 +261,7 @@ public class WebSocketParserD07Test
assertTrue(progress>0); assertTrue(progress>0);
assertEquals(WebSocketConnectionD07.CLOSE_LARGE,_handler._code); assertEquals(WebSocketConnectionD7_9.CLOSE_LARGE,_handler._code);
for (int i=0;i<2048;i++) for (int i=0;i<2048;i++)
_in.put((byte)'a'); _in.put((byte)'a');
progress =_parser.parseNext(); progress =_parser.parseNext();

17
pom.xml
View File

@ -3,7 +3,7 @@
<parent> <parent>
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-parent</artifactId> <artifactId>jetty-parent</artifactId>
<version>17</version> <version>18</version>
</parent> </parent>
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId> <artifactId>jetty-project</artifactId>
@ -23,13 +23,13 @@
<servlet.spec.artifactId>servlet-api</servlet.spec.artifactId> <servlet.spec.artifactId>servlet-api</servlet.spec.artifactId>
<servlet.spec.version>3.0.20100224</servlet.spec.version> <servlet.spec.version>3.0.20100224</servlet.spec.version>
<build-support-version>1.0</build-support-version> <build-support-version>1.0</build-support-version>
<jetty.test.helper>1.5</jetty.test.helper> <jetty.test.helper>1.6</jetty.test.helper>
<jetty.test.policy>1.2</jetty.test.policy> <jetty.test.policy>1.2</jetty.test.policy>
</properties> </properties>
<scm> <scm>
<connection>scm:svn:http://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/branches/jetty-8</connection> <connection>scm:git:http://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.project.git</connection>
<developerConnection>scm:svn:svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/branches/jetty-8</developerConnection> <developerConnection>scm:git:ssh://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.project.git</developerConnection>
<url>http://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/branches/jetty-8</url> <url>http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree</url>
</scm> </scm>
<build> <build>
<defaultGoal>install</defaultGoal> <defaultGoal>install</defaultGoal>
@ -45,7 +45,6 @@
<plugin> <plugin>
<artifactId>maven-release-plugin</artifactId> <artifactId>maven-release-plugin</artifactId>
<configuration> <configuration>
<tagBase>svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/tags</tagBase>
<autoVersionSubmodules>true</autoVersionSubmodules> <autoVersionSubmodules>true</autoVersionSubmodules>
</configuration> </configuration>
</plugin> </plugin>
@ -420,14 +419,10 @@
--> -->
<id>osgi</id> <id>osgi</id>
<activation> <activation>
<activeByDefault>true</activeByDefault>
<activeByDefault>false</activeByDefault>
<!--
<activeByDefault>true</activeByDefault>
<file> <file>
<exists>${basedir}/pom.xml</exists> <exists>${basedir}/pom.xml</exists>
</file> </file>
-->
</activation> </activation>
<modules> <modules>
<module>jetty-osgi</module> <module>jetty-osgi</module>

View File

@ -140,6 +140,23 @@ public class HttpTester
return getString(view.asArray()); return getString(view.asArray());
} }
/* ------------------------------------------------------------ */
/**
* Parse one HTTP request or response
* @param rawHTTP Raw HTTP to parse
* @return Any unparsed data in the rawHTTP (eg pipelined requests)
* @throws IOException
*/
public byte[] parse(byte[] rawHTTP) throws IOException
{
_charset = _defaultCharset;
ByteArrayBuffer buf = new ByteArrayBuffer(rawHTTP);
View view = new View(buf);
HttpParser parser = new HttpParser(view,new PH());
parser.parse();
return view.asArray();
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public String generate() throws IOException public String generate() throws IOException
{ {
@ -438,6 +455,16 @@ public class HttpTester
return null; return null;
} }
/* ------------------------------------------------------------ */
public byte[] getContentBytes()
{
if (_parsedContent!=null)
return _parsedContent.toByteArray();
if (_genContent!=null)
return _genContent;
return null;
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public void setContent(String content) public void setContent(String content)
{ {

View File

@ -22,6 +22,9 @@ import java.io.PrintWriter;
import java.io.Reader; import java.io.Reader;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.net.URL;
import java.util.Collections;
import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Locale; import java.util.Locale;
@ -700,6 +703,13 @@ public class Dump extends HttpServlet
pout.write("</tr><tr>\n"); pout.write("</tr><tr>\n");
pout.write("<th align=\"right\">Thread.currentThread().getContextClassLoader().getResource(...):&nbsp;</th>"); pout.write("<th align=\"right\">Thread.currentThread().getContextClassLoader().getResource(...):&nbsp;</th>");
pout.write("<td>"+Thread.currentThread().getContextClassLoader().getResource(res)+"</td>"); pout.write("<td>"+Thread.currentThread().getContextClassLoader().getResource(res)+"</td>");
pout.write("</tr><tr>\n");
pout.write("<th align=\"right\">Thread.currentThread().getContextClassLoader().getResources(...):&nbsp;</th>");
Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(res);
if (urls==null)
pout.write("<td>null</td>");
else
pout.write("<td>"+Collections.list(urls)+"</td>");
} }

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