diff --git a/VERSION.txt b/VERSION.txt index 402907dfb29..b8f19739290 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1,3 +1,6 @@ +jetty-8.0.0.RC0 + + Merge from jetty-7.4.3 + jetty-8.0.0.M3 + 324505 Implement API login + 335500 request.getParts() throws a NullPointerException @@ -5,6 +8,42 @@ jetty-8.0.0.M3 + 346180 jsp-2.2 support + 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 + 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 diff --git a/example-jetty-embedded/pom.xml b/example-jetty-embedded/pom.xml index edcbdf5a156..3affc94f6dd 100644 --- a/example-jetty-embedded/pom.xml +++ b/example-jetty-embedded/pom.xml @@ -6,7 +6,7 @@ 4.0.0 example-jetty-embedded - Example :: Embedded Jetty Examples + Example :: Jetty Embedded Jetty Embedded Examples @@ -48,5 +48,16 @@ jetty-websocket ${project.version} + + junit + junit + test + + + org.eclipse.jetty + test-jetty-servlet + ${project.version} + test + diff --git a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java index 95c7b60b45a..8e533d8296a 100644 --- a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java +++ b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java @@ -50,7 +50,6 @@ public class ManyConnectors cf.setKeyStore(jetty_home + "/etc/keystore"); cf.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); cf.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); - server.addConnector(ssl_connector); server.setConnectors(new Connector[] { connector0, connector1, ssl_connector }); diff --git a/example-jetty-embedded/src/test/java/org/eclipse/jetty/embedded/GzipHandlerTest.java b/example-jetty-embedded/src/test/java/org/eclipse/jetty/embedded/GzipHandlerTest.java new file mode 100644 index 00000000000..56122ea150c --- /dev/null +++ b/example-jetty-embedded/src/test/java/org/eclipse/jetty/embedded/GzipHandlerTest.java @@ -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")); + + } +} diff --git a/icon.jpg b/icon.jpg new file mode 100644 index 00000000000..d2b7ab52417 Binary files /dev/null and b/icon.jpg differ diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpExchange.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpExchange.java index 36b32f5e70d..da5b6e55c49 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpExchange.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpExchange.java @@ -586,7 +586,7 @@ public class HttpExchange public void setRequestContentSource(InputStream stream) { _requestContentSource = stream; - if (_requestContentSource.markSupported()) + if (_requestContentSource != null && _requestContentSource.markSupported()) _requestContentSource.mark(Integer.MAX_VALUE); } diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpExchangeCancelTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpExchangeCancelTest.java index 93c3c076b36..3123cee07d9 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpExchangeCancelTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpExchangeCancelTest.java @@ -14,6 +14,10 @@ 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.net.SocketTimeoutException; @@ -22,8 +26,6 @@ import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import junit.framework.TestCase; - import org.eclipse.jetty.io.Buffer; import org.eclipse.jetty.server.Connector; 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.util.log.Log; import org.eclipse.jetty.util.log.StdErrLog; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; /** * @version $Revision$ $Date$ */ -public abstract class AbstractHttpExchangeCancelTest extends TestCase +public abstract class AbstractHttpExchangeCancelTest { private Server server; private Connector connector; - @Override - protected void setUp() throws Exception + @Before + public void setUp() throws Exception { server = new Server(); connector = new SelectChannelConnector(); @@ -51,13 +56,15 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase server.start(); } - @Override - protected void tearDown() throws Exception + @After + public void tearDown() throws Exception { server.stop(); server.join(); } + /* ------------------------------------------------------------ */ + @Test public void testHttpExchangeCancelOnSend1() throws Exception { // One of the first things that HttpClient.send() does @@ -93,6 +100,8 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase assertFalse(exchange.isAssociated()); } + /* ------------------------------------------------------------ */ + @Test public void testHttpExchangeCancelOnSend2() throws Exception { // One of the first things that HttpClient.send() does @@ -129,6 +138,8 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase assertFalse(exchange.isAssociated()); } + /* ------------------------------------------------------------ */ + @Test public void testHttpExchangeCancelOnRequestCommitted() throws Exception { TestHttpExchange exchange = new TestHttpExchange() @@ -152,6 +163,8 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase assertFalse(exchange.isAssociated()); } + /* ------------------------------------------------------------ */ + @Test public void testHttpExchangeCancelOnRequestComplete() throws Exception { TestHttpExchange exchange = new TestHttpExchange() @@ -175,6 +188,8 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase assertFalse(exchange.isAssociated()); } + /* ------------------------------------------------------------ */ + @Test public void testHttpExchangeCancelOnResponseStatus() throws Exception { TestHttpExchange exchange = new TestHttpExchange() @@ -198,6 +213,8 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase assertFalse(exchange.isAssociated()); } + /* ------------------------------------------------------------ */ + @Test public void testHttpExchangeCancelOnResponseHeader() throws Exception { TestHttpExchange exchange = new TestHttpExchange() @@ -221,6 +238,8 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase assertFalse(exchange.isAssociated()); } + /* ------------------------------------------------------------ */ + @Test public void testHttpExchangeCancelOnResponseHeadersComplete() throws Exception { TestHttpExchange exchange = new TestHttpExchange() @@ -244,6 +263,8 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase assertFalse(exchange.isAssociated()); } + /* ------------------------------------------------------------ */ + @Test public void testHttpExchangeCancelOnResponseContent() throws Exception { TestHttpExchange exchange = new TestHttpExchange() @@ -267,6 +288,8 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase assertFalse(exchange.isAssociated()); } + /* ------------------------------------------------------------ */ + @Test public void testHttpExchangeCancelOnResponseComplete() throws Exception { TestHttpExchange exchange = new TestHttpExchange() @@ -290,6 +313,8 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase assertEquals(HttpExchange.STATUS_COMPLETED, status); } + /* ------------------------------------------------------------ */ + @Test public void testHttpExchangeOnServerException() throws Exception { try @@ -313,6 +338,8 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase } } + /* ------------------------------------------------------------ */ + @Test public void testHttpExchangeOnExpire() throws Exception { HttpClient httpClient = getHttpClient(); @@ -338,15 +365,19 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase assertFalse(exchange.isAssociated()); } + /* ------------------------------------------------------------ */ protected abstract HttpClient getHttpClient(); + /* ------------------------------------------------------------ */ protected Address newAddress() { return new Address("localhost", connector.getLocalPort()); } + /* ------------------------------------------------------------ */ private static class EmptyHandler extends AbstractHandler { + /* ------------------------------------------------------------ */ public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException { request.setHandled(true); @@ -382,28 +413,33 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase } } + /* ------------------------------------------------------------ */ protected static class TestHttpExchange extends ContentExchange { private boolean responseCompleted; private boolean failed = false; private boolean expired = false; + /* ------------------------------------------------------------ */ protected TestHttpExchange() { super(true); } + /* ------------------------------------------------------------ */ @Override protected synchronized void onResponseComplete() throws IOException { this.responseCompleted = true; } + /* ------------------------------------------------------------ */ public synchronized boolean isResponseCompleted() { return responseCompleted; } + /* ------------------------------------------------------------ */ @Override protected synchronized void onException(Throwable ex) { @@ -414,17 +450,20 @@ public abstract class AbstractHttpExchangeCancelTest extends TestCase failed = true; } + /* ------------------------------------------------------------ */ public synchronized boolean isFailed() { return failed; } + /* ------------------------------------------------------------ */ @Override protected synchronized void onExpire() { this.expired = true; } + /* ------------------------------------------------------------ */ public synchronized boolean isExpired() { return expired; diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/AsyncCallbackHttpExchangeTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/AsyncCallbackHttpExchangeTest.java index 85a8cb14be6..b4be686a42d 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/AsyncCallbackHttpExchangeTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/AsyncCallbackHttpExchangeTest.java @@ -14,6 +14,8 @@ package org.eclipse.jetty.client; +import static org.junit.Assert.assertNull; + import java.io.IOException; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; @@ -22,13 +24,15 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; -import junit.framework.TestCase; +import org.junit.Test; +/* ------------------------------------------------------------ */ /** * @version $Revision$ $Date$ */ -public class AsyncCallbackHttpExchangeTest extends TestCase +public class AsyncCallbackHttpExchangeTest { + /* ------------------------------------------------------------ */ /** * If the HttpExchange callbacks are called holding the lock on HttpExchange, * 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 */ + @Test public void testAsyncCallback() throws Exception { ExecutorService executor = Executors.newCachedThreadPool(); @@ -56,22 +61,26 @@ public class AsyncCallbackHttpExchangeTest extends TestCase } } + /* ------------------------------------------------------------ */ private class TestHttpExchange extends HttpExchange { private final ExecutorService executor; private final AtomicReference failure; + /* ------------------------------------------------------------ */ private TestHttpExchange(ExecutorService executor, AtomicReference failure) { this.executor = executor; this.failure = failure; } + /* ------------------------------------------------------------ */ @Override protected void onRequestCommitted() throws IOException { Future future = executor.submit(new Callable() { + /* ------------------------------------------------------------ */ public Integer call() throws Exception { // Method getStatus() reads synchronized state diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSslHttpExchangeTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSslHttpExchangeTest.java index 48030d4cbd3..f4103bd4e4d 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSslHttpExchangeTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSslHttpExchangeTest.java @@ -16,7 +16,7 @@ package org.eclipse.jetty.client; public class AsyncSslHttpExchangeTest extends SslHttpExchangeTest { @Override - protected void setUp() throws Exception + public void setUp() throws Exception { _scheme="https://"; startServer(); @@ -28,5 +28,4 @@ public class AsyncSslHttpExchangeTest extends SslHttpExchangeTest _httpClient.setMaxConnectionsPerAddress(2); _httpClient.start(); } - } diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSslSecurityListenerTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSslSecurityListenerTest.java index 2a7b1176da8..2c0032c00a6 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSslSecurityListenerTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSslSecurityListenerTest.java @@ -13,11 +13,16 @@ package org.eclipse.jetty.client; +import org.junit.Before; + +/* ------------------------------------------------------------ */ public class AsyncSslSecurityListenerTest extends SslSecurityListenerTest { + /* ------------------------------------------------------------ */ + @Before @Override - protected void setUp() throws Exception + public void setUp() throws Exception { _type = HttpClient.CONNECTOR_SELECT_CHANNEL; super.setUp(); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/BlockingHttpExchangeCancelTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/BlockingHttpExchangeCancelTest.java index ad66e2cce42..af5095135c8 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/BlockingHttpExchangeCancelTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/BlockingHttpExchangeCancelTest.java @@ -14,7 +14,11 @@ package org.eclipse.jetty.client; +import org.junit.After; +import org.junit.Before; + +/* ------------------------------------------------------------ */ /** * @version $Revision$ $Date$ */ @@ -22,8 +26,10 @@ public class BlockingHttpExchangeCancelTest extends AbstractHttpExchangeCancelTe { private HttpClient httpClient; + /* ------------------------------------------------------------ */ + @Before @Override - protected void setUp() throws Exception + public void setUp() throws Exception { super.setUp(); httpClient = new HttpClient(); @@ -31,13 +37,16 @@ public class BlockingHttpExchangeCancelTest extends AbstractHttpExchangeCancelTe httpClient.start(); } + /* ------------------------------------------------------------ */ + @After @Override - protected void tearDown() throws Exception + public void tearDown() throws Exception { httpClient.stop(); super.tearDown(); } + /* ------------------------------------------------------------ */ @Override protected HttpClient getHttpClient() { diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/CachedHeadersIsolationTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/CachedHeadersIsolationTest.java index 17ccef58903..8a599808386 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/CachedHeadersIsolationTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/CachedHeadersIsolationTest.java @@ -1,5 +1,7 @@ package org.eclipse.jetty.client; +import static org.junit.Assert.assertEquals; + import java.io.IOException; import java.util.Enumeration; @@ -7,26 +9,27 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import junit.framework.TestCase; - import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.AbstractHandler; 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; HttpClient client; int port; - @Override - protected void setUp() throws Exception + @Before + public void setUp() throws Exception { - super.setUp(); server = new Server(); Connector connector = new SelectChannelConnector(); @@ -35,7 +38,7 @@ public class CachedHeadersIsolationTest extends TestCase server.setHandler(new AbstractHandler() { - + /* ------------------------------------------------------------ */ public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, 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(); client.stop(); } + /* ------------------------------------------------------------ */ + @Test public void testHeaderWhenReadEarly() throws Exception { @@ -88,6 +93,8 @@ public class CachedHeadersIsolationTest extends TestCase assertEquals("Overwritten buffer","Value",e1.getResponseFields().getStringField("Name")); } + /* ------------------------------------------------------------ */ + @Test public void testHeaderWhenReadLate() throws Exception { diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ContentExchangeTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ContentExchangeTest.java index b1321af6e68..e004d71bb03 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/ContentExchangeTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ContentExchangeTest.java @@ -13,6 +13,9 @@ package org.eclipse.jetty.client; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; @@ -27,8 +30,6 @@ import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import junit.framework.TestCase; - import org.eclipse.jetty.client.security.Realm; import org.eclipse.jetty.client.security.SimpleRealmResolver; 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.ServletHolder; import org.eclipse.jetty.util.IO; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; public class ContentExchangeTest - extends TestCase { private static String _content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis felis nunc. "+ @@ -71,6 +74,8 @@ public class ContentExchangeTest private String _baseUrl; private String _requestContent; + /* ------------------------------------------------------------ */ + @Before public void setUp() throws Exception { @@ -91,6 +96,8 @@ public class ContentExchangeTest _baseUrl = _protocol+"://localhost:"+port+ "/"; } + /* ------------------------------------------------------------ */ + @After public void tearDown() throws Exception { @@ -101,6 +108,8 @@ public class ContentExchangeTest } } + /* ------------------------------------------------------------ */ + @Test public void testPut() throws Exception { startClient(_realm); @@ -124,6 +133,8 @@ public class ContentExchangeTest assertEquals(_content,content); } + /* ------------------------------------------------------------ */ + @Test public void testGet() throws Exception { startClient(_realm); @@ -148,6 +159,8 @@ public class ContentExchangeTest assertEquals(_content,content); } + /* ------------------------------------------------------------ */ + @Test public void testHead() throws Exception { startClient(_realm); @@ -166,6 +179,8 @@ public class ContentExchangeTest assertEquals(HttpStatus.OK_200,responseStatus); } + /* ------------------------------------------------------------ */ + @Test public void testPost() throws Exception { startClient(_realm); @@ -186,6 +201,7 @@ public class ContentExchangeTest assertEquals(_content,_requestContent); } + /* ------------------------------------------------------------ */ protected void configureServer(Server server) throws Exception { @@ -209,6 +225,7 @@ public class ContentExchangeTest } + /* ------------------------------------------------------------ */ protected void startClient(Realm realm) throws Exception { @@ -221,12 +238,14 @@ public class ContentExchangeTest _client.start(); } + /* ------------------------------------------------------------ */ protected void configureClient(HttpClient client) throws Exception { client.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL); } + /* ------------------------------------------------------------ */ protected void stopClient() throws Exception { @@ -237,41 +256,49 @@ public class ContentExchangeTest } } + /* ------------------------------------------------------------ */ protected String getBasePath() { return _docRoot.getAbsolutePath(); } + /* ------------------------------------------------------------ */ protected String getBaseUrl() { return _baseUrl; } + /* ------------------------------------------------------------ */ protected HttpClient getClient() { return _client; } + /* ------------------------------------------------------------ */ protected Realm getRealm() { return _realm; } + /* ------------------------------------------------------------ */ protected String getContent() { return _content; } + /* ------------------------------------------------------------ */ protected void setProtocol(String protocol) { _protocol = protocol; } + /* ------------------------------------------------------------ */ protected void setRealm(Realm realm) { _realm = realm; } + /* ------------------------------------------------------------ */ public static void copyStream(InputStream in, OutputStream out) { try @@ -293,13 +320,16 @@ public class ContentExchangeTest } } + /* ------------------------------------------------------------ */ protected class TestHandler extends AbstractHandler { private final String resourcePath; + /* ------------------------------------------------------------ */ public TestHandler(String repositoryPath) { this.resourcePath = repositoryPath; } + /* ------------------------------------------------------------ */ public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ErrorStatusTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ErrorStatusTest.java index 25b2e4655b6..46097f2336b 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/ErrorStatusTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ErrorStatusTest.java @@ -13,6 +13,8 @@ package org.eclipse.jetty.client; +import static org.junit.Assert.assertEquals; + import java.io.IOException; 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.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; +import org.junit.Test; +/* ------------------------------------------------------------ */ public class ErrorStatusTest extends ContentExchangeTest { + + /* ------------------------------------------------------------ */ + @Test public void testPutBadRequest() throws Exception { doPutFail(HttpStatus.BAD_REQUEST_400); } + /* ------------------------------------------------------------ */ + @Test public void testPutUnauthorized() throws Exception { doPutFail(HttpStatus.UNAUTHORIZED_401); } + /* ------------------------------------------------------------ */ + @Test public void testPutForbidden() throws Exception { doPutFail(HttpStatus.FORBIDDEN_403); } + /* ------------------------------------------------------------ */ + @Test public void testPutNotFound() throws Exception { doPutFail(HttpStatus.NOT_FOUND_404); } + /* ------------------------------------------------------------ */ + @Test public void testPutServerError() throws Exception { doPutFail(HttpStatus.INTERNAL_SERVER_ERROR_500); } + /* ------------------------------------------------------------ */ + @Test public void testGetBadRequest() throws Exception { doGetFail(HttpStatus.BAD_REQUEST_400); } + /* ------------------------------------------------------------ */ + @Test public void testGetUnauthorized() throws Exception { doGetFail(HttpStatus.UNAUTHORIZED_401); } + /* ------------------------------------------------------------ */ + @Test public void testGetNotFound() throws Exception { doGetFail(HttpStatus.NOT_FOUND_404); } + /* ------------------------------------------------------------ */ + @Test public void testGetServerError() throws Exception { doGetFail(HttpStatus.INTERNAL_SERVER_ERROR_500); } + /* ------------------------------------------------------------ */ + @Test public void testPostBadRequest() throws Exception { doPostFail(HttpStatus.BAD_REQUEST_400); } + /* ------------------------------------------------------------ */ + @Test public void testPostUnauthorized() throws Exception { doPostFail(HttpStatus.UNAUTHORIZED_401); } + /* ------------------------------------------------------------ */ + @Test public void testPostForbidden() throws Exception { doPostFail(HttpStatus.FORBIDDEN_403); } + /* ------------------------------------------------------------ */ + @Test public void testPostNotFound() throws Exception { doPostFail(HttpStatus.NOT_FOUND_404); } + /* ------------------------------------------------------------ */ + @Test public void testPostServerError() throws Exception { doPostFail(HttpStatus.INTERNAL_SERVER_ERROR_500); } + /* ------------------------------------------------------------ */ protected void doPutFail(int status) throws Exception { @@ -140,6 +174,7 @@ public class ErrorStatusTest assertEquals(status, responseStatus); } + /* ------------------------------------------------------------ */ protected void doGetFail(int status) throws Exception { @@ -164,6 +199,7 @@ public class ErrorStatusTest assertEquals(status, responseStatus); } + /* ------------------------------------------------------------ */ protected void doPostFail(int status) throws Exception { @@ -185,6 +221,7 @@ public class ErrorStatusTest assertEquals(status, responseStatus); } + /* ------------------------------------------------------------ */ protected void configureServer(Server server) throws Exception { @@ -208,7 +245,9 @@ public class ErrorStatusTest server.setHandler( handlers ); } + /* ------------------------------------------------------------ */ protected static class StatusHandler extends AbstractHandler { + /* ------------------------------------------------------------ */ public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ExternalKeyStoreAsyncSslHttpExchangeTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ExternalKeyStoreAsyncSslHttpExchangeTest.java index 9ef4e4e3c37..0f47db5f3f1 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/ExternalKeyStoreAsyncSslHttpExchangeTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ExternalKeyStoreAsyncSslHttpExchangeTest.java @@ -20,7 +20,7 @@ import org.eclipse.jetty.toolchain.test.MavenTestingUtils; public class ExternalKeyStoreAsyncSslHttpExchangeTest extends SslHttpExchangeTest { @Override - protected void setUp() throws Exception + public void setUp() throws Exception { _scheme = "https://"; startServer(); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpExchangeTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpExchangeTest.java index a6247dfa4ea..2c571d29f49 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpExchangeTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpExchangeTest.java @@ -13,6 +13,11 @@ 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.IOException; import java.io.InputStream; @@ -26,8 +31,6 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import junit.framework.TestCase; - import org.eclipse.jetty.client.security.ProxyAuthorization; import org.eclipse.jetty.http.HttpHeaders; 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.util.IO; import org.eclipse.jetty.util.log.Log; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +/* ------------------------------------------------------------ */ /** * Functional testing for HttpExchange. */ -public class HttpExchangeTest extends TestCase +public class HttpExchangeTest { protected int _maxConnectionsPerAddress = 2; protected String _scheme = "http://"; @@ -58,8 +65,9 @@ public class HttpExchangeTest extends TestCase protected Connector _connector; protected AtomicInteger _count = new AtomicInteger(); - @Override - protected void setUp() throws Exception + /* ------------------------------------------------------------ */ + @Before + public void setUp() throws Exception { startServer(); _httpClient=new HttpClient(); @@ -71,20 +79,25 @@ public class HttpExchangeTest extends TestCase _httpClient.start(); } - @Override - protected void tearDown() throws Exception + /* ------------------------------------------------------------ */ + @After + public void tearDown() throws Exception { _httpClient.stop(); Thread.sleep(500); stopServer(); } + /* ------------------------------------------------------------ */ + @Test public void testResetNewExchange() throws Exception { HttpExchange exchange = new HttpExchange(); exchange.reset(); } + /* ------------------------------------------------------------ */ + @Test public void testPerf() throws Exception { sender(1,false); @@ -104,6 +117,7 @@ public class HttpExchangeTest extends TestCase } } + /* ------------------------------------------------------------ */ /** * Test sending data through the exchange. * @@ -124,12 +138,15 @@ public class HttpExchangeTest extends TestCase { String result="pending"; int len=0; + + /* ------------------------------------------------------------ */ @Override protected void onRequestCommitted() { result="committed"; } + /* ------------------------------------------------------------ */ @Override protected void onRequestComplete() throws IOException { @@ -137,16 +154,19 @@ public class HttpExchangeTest extends TestCase } @Override + /* ------------------------------------------------------------ */ protected void onResponseStatus(Buffer version, int status, Buffer reason) { result="status"; } + /* ------------------------------------------------------------ */ @Override protected void onResponseHeader(Buffer name, Buffer value) { } + /* ------------------------------------------------------------ */ @Override protected void onResponseHeaderComplete() throws IOException { @@ -154,12 +174,14 @@ public class HttpExchangeTest extends TestCase super.onResponseHeaderComplete(); } + /* ------------------------------------------------------------ */ @Override protected void onResponseContent(Buffer content) { len+=content.length(); } + /* ------------------------------------------------------------ */ @Override protected void onResponseComplete() { @@ -173,6 +195,7 @@ public class HttpExchangeTest extends TestCase complete.countDown(); } + /* ------------------------------------------------------------ */ @Override protected void onConnectionFailed(Throwable ex) { @@ -182,6 +205,7 @@ public class HttpExchangeTest extends TestCase super.onConnectionFailed(ex); } + /* ------------------------------------------------------------ */ @Override protected void onException(Throwable ex) { @@ -191,6 +215,7 @@ public class HttpExchangeTest extends TestCase super.onException(ex); } + /* ------------------------------------------------------------ */ @Override protected void onExpire() { @@ -200,6 +225,7 @@ public class HttpExchangeTest extends TestCase super.onExpire(); } + /* ------------------------------------------------------------ */ @Override public String toString() { @@ -228,6 +254,8 @@ public class HttpExchangeTest extends TestCase assertEquals("nb="+nb+" close="+close,0,latch.getCount()); } + /* ------------------------------------------------------------ */ + @Test public void testPostWithContentExchange() throws Exception { for (int i=0;i<20;i++) @@ -246,6 +274,8 @@ public class HttpExchangeTest extends TestCase } } + /* ------------------------------------------------------------ */ + @Test public void testGetWithContentExchange() throws Exception { for (int i=0;i<10;i++) @@ -264,6 +294,8 @@ public class HttpExchangeTest extends TestCase } } + /* ------------------------------------------------------------ */ + @Test public void testLocalAddressAvailabilityWithContentExchange() throws Exception { for (int i=0;i<10;i++) @@ -287,6 +319,8 @@ public class HttpExchangeTest extends TestCase } } + /* ------------------------------------------------------------ */ + @Test public void testShutdownWithExchange() throws Exception { final AtomicReference throwable=new AtomicReference(); @@ -304,6 +338,10 @@ public class HttpExchangeTest extends TestCase throwable.set(x); } + /* ------------------------------------------------------------ */ + /** + * @see org.eclipse.jetty.client.HttpExchange#onConnectionFailed(java.lang.Throwable) + */ @Override protected void onConnectionFailed(Throwable x) { @@ -330,6 +368,8 @@ public class HttpExchangeTest extends TestCase assertEquals(HttpExchange.STATUS_EXCEPTED, status); } + /* ------------------------------------------------------------ */ + @Test public void testBigPostWithContentExchange() throws Exception { int size =32; @@ -370,6 +410,8 @@ public class HttpExchangeTest extends TestCase assertEquals(HttpExchange.STATUS_COMPLETED, status); } + /* ------------------------------------------------------------ */ + @Test public void testSlowPost() throws Exception { ContentExchange httpExchange=new ContentExchange() @@ -431,6 +473,8 @@ public class HttpExchangeTest extends TestCase assertEquals(data,result); } + /* ------------------------------------------------------------ */ + @Test public void testProxy() throws Exception { if (_scheme.equals("https://")) @@ -460,6 +504,8 @@ public class HttpExchangeTest extends TestCase } + /* ------------------------------------------------------------ */ + @Test public void testReserveConnections () throws Exception { 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 c = destination.reserveConnection(500); assertNotNull(c); - - } - public static void copyStrxeam(InputStream in, OutputStream out) + + /* ------------------------------------------------------------ */ + public static void copyStream(InputStream in, OutputStream out) { try { @@ -509,6 +555,7 @@ public class HttpExchangeTest extends TestCase } } + /* ------------------------------------------------------------ */ protected void newServer() throws Exception { _server=new Server(); @@ -521,6 +568,7 @@ public class HttpExchangeTest extends TestCase _server.setConnectors(new Connector[] { _connector }); } + /* ------------------------------------------------------------ */ protected void startServer() throws Exception { newServer(); @@ -587,6 +635,7 @@ public class HttpExchangeTest extends TestCase _port=_connector.getLocalPort(); } + /* ------------------------------------------------------------ */ private void stopServer() throws Exception { _server.stop(); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpGetRedirectTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpGetRedirectTest.java index 9ed69c079a2..4341c86aa84 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpGetRedirectTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpGetRedirectTest.java @@ -13,6 +13,8 @@ package org.eclipse.jetty.client; +import static org.junit.Assert.assertEquals; + import java.io.File; import java.io.IOException; import java.io.PrintWriter; @@ -21,8 +23,6 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import junit.framework.TestCase; - import org.eclipse.jetty.client.security.Realm; import org.eclipse.jetty.client.security.SimpleRealmResolver; 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.handler.AbstractHandler; import org.eclipse.jetty.server.nio.SelectChannelConnector; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; /* ------------------------------------------------------------ */ -/** - */ public class HttpGetRedirectTest - extends TestCase { private static String _content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis felis nunc. "+ @@ -62,6 +62,8 @@ public class HttpGetRedirectTest private String _requestUrl2; private RedirectHandler _handler; + /* ------------------------------------------------------------ */ + @Before public void setUp() throws Exception { @@ -81,6 +83,8 @@ public class HttpGetRedirectTest _handler._toURL=_protocol+"://localhost:"+connector.getLocalPort()+ "/moved.txt"; } + /* ------------------------------------------------------------ */ + @After public void tearDown() throws Exception { @@ -91,6 +95,8 @@ public class HttpGetRedirectTest } } + /* ------------------------------------------------------------ */ + @Test public void testGet() throws Exception { startClient(_realm); @@ -115,6 +121,7 @@ public class HttpGetRedirectTest stopClient(); } + /* ------------------------------------------------------------ */ protected void configureServer(Server server) throws Exception { @@ -128,6 +135,7 @@ public class HttpGetRedirectTest } + /* ------------------------------------------------------------ */ protected void startClient(Realm realm) throws Exception { @@ -139,6 +147,7 @@ public class HttpGetRedirectTest _client.start(); } + /* ------------------------------------------------------------ */ protected void stopClient() throws Exception { @@ -149,22 +158,26 @@ public class HttpGetRedirectTest } } + /* ------------------------------------------------------------ */ protected String getBasePath() { return _docRoot.getAbsolutePath(); } + /* ------------------------------------------------------------ */ protected void setProtocol(String protocol) { _protocol = protocol; } + /* ------------------------------------------------------------ */ protected void setRealm(Realm realm) { _realm = realm; } + /* ------------------------------------------------------------ */ private static class RedirectHandler extends AbstractHandler { @@ -174,6 +187,7 @@ public class HttpGetRedirectTest private int _redirectCount = 0; private String _toURL; + /* ------------------------------------------------------------ */ public RedirectHandler( final int code, final String fromURI, final String toURL, final int maxRedirects ) { this._code = code; @@ -186,6 +200,7 @@ public class HttpGetRedirectTest } + /* ------------------------------------------------------------ */ public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/NonBlockingHttpExchangeCancelTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/NonBlockingHttpExchangeCancelTest.java index 74266bba199..7fdde5b2a2c 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/NonBlockingHttpExchangeCancelTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/NonBlockingHttpExchangeCancelTest.java @@ -14,6 +14,10 @@ package org.eclipse.jetty.client; +import org.junit.After; +import org.junit.Before; + +/* ------------------------------------------------------------ */ /** * @version $Revision$ $Date$ */ @@ -21,8 +25,10 @@ public class NonBlockingHttpExchangeCancelTest extends AbstractHttpExchangeCance { private HttpClient httpClient; + /* ------------------------------------------------------------ */ + @Before @Override - protected void setUp() throws Exception + public void setUp() throws Exception { super.setUp(); httpClient = new HttpClient(); @@ -30,13 +36,16 @@ public class NonBlockingHttpExchangeCancelTest extends AbstractHttpExchangeCance httpClient.start(); } + /* ------------------------------------------------------------ */ + @After @Override - protected void tearDown() throws Exception + public void tearDown() throws Exception { httpClient.stop(); super.tearDown(); } + /* ------------------------------------------------------------ */ @Override protected HttpClient getHttpClient() { diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SecuredErrorStatusTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/SecuredErrorStatusTest.java index e06f457e2ce..7af4be89281 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/SecuredErrorStatusTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/SecuredErrorStatusTest.java @@ -34,6 +34,7 @@ import org.eclipse.jetty.servlet.DefaultServlet; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.junit.Test; public class SecuredErrorStatusTest extends ErrorStatusTest @@ -41,6 +42,8 @@ public class SecuredErrorStatusTest private Realm _testRealm; private Realm _dummyRealm; + /* ------------------------------------------------------------ */ + @Test @Override public void testPutUnauthorized() throws Exception @@ -52,6 +55,8 @@ public class SecuredErrorStatusTest setRealm(_testRealm); } + /* ------------------------------------------------------------ */ + @Test public void testPutWrongPassword() throws Exception { @@ -62,6 +67,8 @@ public class SecuredErrorStatusTest setRealm(_testRealm); } + /* ------------------------------------------------------------ */ + @Test @Override public void testGetUnauthorized() throws Exception @@ -73,6 +80,8 @@ public class SecuredErrorStatusTest setRealm(_testRealm); } + /* ------------------------------------------------------------ */ + @Test public void testGetWrongPassword() throws Exception { @@ -83,6 +92,7 @@ public class SecuredErrorStatusTest setRealm(_testRealm); } + /* ------------------------------------------------------------ */ @Override protected void configureServer(Server server) throws Exception @@ -91,16 +101,19 @@ public class SecuredErrorStatusTest _testRealm = new Realm() { + /* ------------------------------------------------------------ */ public String getId() { return "MyRealm"; } + /* ------------------------------------------------------------ */ public String getPrincipal() { return "jetty"; } + /* ------------------------------------------------------------ */ public String getCredentials() { return "jetty"; @@ -109,16 +122,19 @@ public class SecuredErrorStatusTest _dummyRealm = new Realm() { + /* ------------------------------------------------------------ */ public String getId() { return "MyRealm"; } + /* ------------------------------------------------------------ */ public String getPrincipal() { return "jetty"; } + /* ------------------------------------------------------------ */ public String getCredentials() { return "dummy"; diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SecurityListenerTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/SecurityListenerTest.java index 0c1b6b87989..133cf476c92 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/SecurityListenerTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/SecurityListenerTest.java @@ -13,6 +13,9 @@ package org.eclipse.jetty.client; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -25,8 +28,6 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import junit.framework.TestCase; - import org.eclipse.jetty.client.security.Realm; import org.eclipse.jetty.client.security.SimpleRealmResolver; 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.nio.SelectChannelConnector; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +/* ------------------------------------------------------------ */ /** * Functional testing for HttpExchange. - * - * - * */ -public class SecurityListenerTest extends TestCase +public class SecurityListenerTest { - private Server _server; private int _port; private HttpClient _httpClient; @@ -62,8 +63,9 @@ public class SecurityListenerTest extends TestCase private Realm _jettyRealm; private static final String APP_CONTEXT = "localhost /"; - @Override - protected void setUp() throws Exception + /* ------------------------------------------------------------ */ + @Before + public void setUp() throws Exception { startServer(); _httpClient=new HttpClient(); @@ -92,13 +94,16 @@ public class SecurityListenerTest extends TestCase _httpClient.setRealmResolver( new SimpleRealmResolver(_jettyRealm) ); } - @Override - protected void tearDown() throws Exception + /* ------------------------------------------------------------ */ + @After + public void tearDown() throws Exception { stopServer(); _httpClient.stop(); } + /* ------------------------------------------------------------ */ +// @Test public void xtestPerf() throws Exception { sender(1); @@ -112,6 +117,7 @@ public class SecurityListenerTest extends TestCase sender(10000); } + /* ------------------------------------------------------------ */ public void sender(final int nb) throws Exception { final CountDownLatch latch=new CountDownLatch(nb); @@ -204,6 +210,8 @@ public class SecurityListenerTest extends TestCase // } + /* ------------------------------------------------------------ */ + @Test public void testDestinationSecurityCaching() throws Exception { final CyclicBarrier barrier = new CyclicBarrier(2); @@ -248,6 +256,7 @@ public class SecurityListenerTest extends TestCase } + /* ------------------------------------------------------------ */ public static void copyStream(InputStream in, OutputStream out) { try @@ -269,6 +278,7 @@ public class SecurityListenerTest extends TestCase } } + /* ------------------------------------------------------------ */ private void startServer() throws Exception { _server = new Server(); @@ -332,7 +342,7 @@ public class SecurityListenerTest extends TestCase _port = connector.getLocalPort(); } - + /* ------------------------------------------------------------ */ private void stopServer() throws Exception { _server.stop(); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslHttpExchangeTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/SslHttpExchangeTest.java index 6bb182ce225..eec253367b1 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/SslHttpExchangeTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/SslHttpExchangeTest.java @@ -21,7 +21,11 @@ import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ssl.SslSocketConnector; 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.Before; +import org.junit.Test; /** * Functional testing for HttpExchange. @@ -31,8 +35,10 @@ import org.junit.Assume; */ public class SslHttpExchangeTest extends HttpExchangeTest { + /* ------------------------------------------------------------ */ + @Before @Override - protected void setUp() throws Exception + public void setUp() throws Exception { _scheme="https://"; startServer(); @@ -46,6 +52,7 @@ public class SslHttpExchangeTest extends HttpExchangeTest _httpClient.start(); } + /* ------------------------------------------------------------ */ @Override protected void newServer() { @@ -67,7 +74,9 @@ public class SslHttpExchangeTest extends HttpExchangeTest _connector=connector; } - private void IgnoreTestOnBuggyIBM() { + /* ------------------------------------------------------------ */ + private void IgnoreTestOnBuggyIBM() + { // 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. 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() */ + @Test @Override public void testGetWithContentExchange() throws Exception { @@ -89,9 +99,13 @@ public class SslHttpExchangeTest extends HttpExchangeTest /** * @see org.eclipse.jetty.client.HttpExchangeTest#testPerf() */ + @Test @Override 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 IgnoreTestOnBuggyIBM(); super.testPerf(); @@ -101,6 +115,7 @@ public class SslHttpExchangeTest extends HttpExchangeTest /** * @see org.eclipse.jetty.client.HttpExchangeTest#testPostWithContentExchange() */ + @Test @Override public void testPostWithContentExchange() throws Exception { @@ -113,6 +128,7 @@ public class SslHttpExchangeTest extends HttpExchangeTest /** * @see org.eclipse.jetty.client.HttpExchangeTest#testReserveConnections() */ + @Test @Override public void testReserveConnections() throws Exception { diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslSecuredErrorStatusTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/SslSecuredErrorStatusTest.java index 426b44bcd9f..4b4c4dcf19f 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/SslSecuredErrorStatusTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/SslSecuredErrorStatusTest.java @@ -34,13 +34,17 @@ import org.eclipse.jetty.servlet.DefaultServlet; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.junit.Test; +/* ------------------------------------------------------------ */ public class SslSecuredErrorStatusTest extends ErrorStatusTest { private Realm _testRealm; private Realm _dummyRealm; + /* ------------------------------------------------------------ */ + @Test public void testPutUnauthorized() throws Exception { @@ -50,7 +54,9 @@ public class SslSecuredErrorStatusTest setRealm(_testRealm); } - + + /* ------------------------------------------------------------ */ + @Test public void testPutWrongPassword() throws Exception { @@ -61,6 +67,8 @@ public class SslSecuredErrorStatusTest setRealm(_testRealm); } + /* ------------------------------------------------------------ */ + @Test public void testGetUnauthorized() throws Exception { @@ -71,6 +79,8 @@ public class SslSecuredErrorStatusTest setRealm(_testRealm); } + /* ------------------------------------------------------------ */ + @Test public void testGetWrongPassword() throws Exception { @@ -81,6 +91,7 @@ public class SslSecuredErrorStatusTest setRealm(_testRealm); } + /* ------------------------------------------------------------ */ protected void configureServer(Server server) throws Exception { @@ -88,16 +99,19 @@ public class SslSecuredErrorStatusTest _testRealm = new Realm() { + /* ------------------------------------------------------------ */ public String getId() { return "MyRealm"; } + /* ------------------------------------------------------------ */ public String getPrincipal() { return "jetty"; } + /* ------------------------------------------------------------ */ public String getCredentials() { return "jetty"; @@ -106,16 +120,19 @@ public class SslSecuredErrorStatusTest _dummyRealm = new Realm() { + /* ------------------------------------------------------------ */ public String getId() { return "MyRealm"; } + /* ------------------------------------------------------------ */ public String getPrincipal() { return "jetty"; } + /* ------------------------------------------------------------ */ public String getCredentials() { return "dummy"; diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslSecurityListenerTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/SslSecurityListenerTest.java index 49b714fc501..bab72e9a961 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/SslSecurityListenerTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/SslSecurityListenerTest.java @@ -13,6 +13,9 @@ package org.eclipse.jetty.client; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -28,8 +31,6 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import junit.framework.TestCase; - import org.eclipse.jetty.client.security.HashRealmResolver; import org.eclipse.jetty.client.security.Realm; 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.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.util.log.Log; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +/* ------------------------------------------------------------ */ /** * Functional testing. */ -public class SslSecurityListenerTest extends TestCase +public class SslSecurityListenerTest { protected Server _server; protected int _port; @@ -62,8 +67,9 @@ public class SslSecurityListenerTest extends TestCase protected int _type = HttpClient.CONNECTOR_SOCKET; private static final String APP_CONTEXT = "localhost /"; - @Override - protected void setUp() throws Exception + /* ------------------------------------------------------------ */ + @Before + public void setUp() throws Exception { startServer(); _httpClient = new HttpClient(); @@ -73,16 +79,19 @@ public class SslSecurityListenerTest extends TestCase _jettyRealm = new Realm() { + /* ------------------------------------------------------------ */ public String getId() { return "MyRealm"; } + /* ------------------------------------------------------------ */ public String getPrincipal() { return "jetty"; } + /* ------------------------------------------------------------ */ public String getCredentials() { return "jetty"; @@ -94,8 +103,9 @@ public class SslSecurityListenerTest extends TestCase _httpClient.setRealmResolver(resolver); } - @Override - protected void tearDown() throws Exception + /* ------------------------------------------------------------ */ + @After + public void tearDown() throws Exception { Thread.sleep(1000); _httpClient.stop(); @@ -103,6 +113,8 @@ public class SslSecurityListenerTest extends TestCase stopServer(); } + /* ------------------------------------------------------------ */ + @Test public void testSslGet() throws Exception { // 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) { + /* ------------------------------------------------------------ */ @Override protected void onResponseComplete() throws IOException { @@ -138,6 +151,7 @@ public class SslSecurityListenerTest extends TestCase } + /* ------------------------------------------------------------ */ protected void startServer() throws Exception { _server = new Server(); @@ -180,7 +194,7 @@ public class SslSecurityListenerTest extends TestCase Handler testHandler = new AbstractHandler() { - + /* ------------------------------------------------------------ */ public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { // System.err.println("passed authentication!\n"+((Request)request).getConnection().getRequestFields()); @@ -216,6 +230,7 @@ public class SslSecurityListenerTest extends TestCase _port = connector.getLocalPort(); } + /* ------------------------------------------------------------ */ public static void copyStream(InputStream in, OutputStream out) { try @@ -237,6 +252,7 @@ public class SslSecurityListenerTest extends TestCase } } + /* ------------------------------------------------------------ */ private void stopServer() throws Exception { _server.stop(); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/WebSocketUpgradeTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/WebSocketUpgradeTest.java index 4173d7d3c17..f29bc05d57d 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/WebSocketUpgradeTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/WebSocketUpgradeTest.java @@ -13,6 +13,8 @@ package org.eclipse.jetty.client; +import static org.junit.Assert.assertEquals; + import java.io.IOException; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; @@ -21,8 +23,6 @@ import java.util.concurrent.TimeUnit; import javax.servlet.http.HttpServletRequest; -import junit.framework.TestCase; - import org.eclipse.jetty.http.HttpMethods; import org.eclipse.jetty.io.Buffer; 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.WebSocketConnectionD00; import org.eclipse.jetty.websocket.WebSocketHandler; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +/* ------------------------------------------------------------ */ /** * Functional testing for HttpExchange. */ -public class WebSocketUpgradeTest extends TestCase +public class WebSocketUpgradeTest { protected Server _server; protected int _port; @@ -49,8 +53,9 @@ public class WebSocketUpgradeTest extends TestCase protected TestWebSocket _websocket; final BlockingQueue _results = new ArrayBlockingQueue(100); - @Override - protected void setUp() throws Exception + /* ------------------------------------------------------------ */ + @Before + public void setUp() throws Exception { startServer(); _httpClient=new HttpClient(); @@ -62,25 +67,29 @@ public class WebSocketUpgradeTest extends TestCase _httpClient.start(); } - @Override - protected void tearDown() throws Exception + /* ------------------------------------------------------------ */ + @After + public void tearDown() throws Exception { _httpClient.stop(); Thread.sleep(500); stopServer(); } - + /* ------------------------------------------------------------ */ + @Test public void testGetWithContentExchange() throws Exception { final WebSocket clientWS = new WebSocket.OnTextMessage() { Connection _connection; + /* ------------------------------------------------------------ */ public void onClose(int closeCode, String message) { } + /* ------------------------------------------------------------ */ public void onOpen(Connection connection) { _connection=connection; @@ -88,6 +97,7 @@ public class WebSocketUpgradeTest extends TestCase _results.add(_connection); } + /* ------------------------------------------------------------ */ public void onMessage(String data) { _results.add("clientWS.onMessage"); @@ -126,6 +136,7 @@ public class WebSocketUpgradeTest extends TestCase return connection; } + /* ------------------------------------------------------------ */ private void waitFor(int results) { try @@ -176,6 +187,7 @@ public class WebSocketUpgradeTest extends TestCase } + /* ------------------------------------------------------------ */ protected void newServer() throws Exception { _server=new Server(); @@ -186,11 +198,13 @@ public class WebSocketUpgradeTest extends TestCase _server.setConnectors(new Connector[] { _connector }); } + /* ------------------------------------------------------------ */ protected void startServer() throws Exception { newServer(); _handler= new WebSocketHandler() { + /* ------------------------------------------------------------ */ public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol) { _websocket = new TestWebSocket(); @@ -203,18 +217,19 @@ public class WebSocketUpgradeTest extends TestCase _port=_connector.getLocalPort(); } + /* ------------------------------------------------------------ */ private void stopServer() throws Exception { _server.stop(); _server.join(); } - /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ class TestWebSocket implements WebSocket.OnTextMessage { Connection _connection; + /* ------------------------------------------------------------ */ public void onOpen(Connection connection) { _connection=connection; @@ -223,18 +238,21 @@ public class WebSocketUpgradeTest extends TestCase _results.add(this); } + /* ------------------------------------------------------------ */ public void onMessage(final String data) { _results.add("serverWS.onMessage"); _results.add(data); } + /* ------------------------------------------------------------ */ public void onClose(int code, String message) { _results.add("onDisconnect"); _webSockets.remove(this); } + /* ------------------------------------------------------------ */ public void sendMessage(String msg) throws IOException { _connection.sendMessage(msg); diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/GlobalWebappConfigBinding.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/GlobalWebappConfigBinding.java index d48592a947d..9e9a9cf41f8 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/GlobalWebappConfigBinding.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/GlobalWebappConfigBinding.java @@ -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"); } - Resource globalContextSettings = new FileResource(new URL(_jettyXml)); + Resource globalContextSettings = Resource.newResource(_jettyXml); if (globalContextSettings.exists()) { diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/bindings/GlobalWebappConfigBindingTest.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/bindings/GlobalWebappConfigBindingTest.java index 953c4875f2a..4d93154dfa1 100644 --- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/bindings/GlobalWebappConfigBindingTest.java +++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/bindings/GlobalWebappConfigBindingTest.java @@ -18,11 +18,13 @@ package org.eclipse.jetty.deploy.bindings; import static org.hamcrest.Matchers.*; import java.io.File; +import java.util.List; import org.eclipse.jetty.deploy.providers.ScanningAppProvider; import org.eclipse.jetty.deploy.test.XmlConfiguredJetty; import org.eclipse.jetty.toolchain.test.IO; 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.webapp.WebAppContext; import org.junit.After; @@ -62,13 +64,20 @@ public class GlobalWebappConfigBindingTest @Test 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.load(); jetty.start(); - WebAppContext context = jetty.getWebAppContexts().get(0); + List 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); String defaultClasses[] = context.getDefaultServerClasses(); diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderRuntimeUpdatesTest.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderRuntimeUpdatesTest.java index 7741259f079..b54addf5e5f 100644 --- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderRuntimeUpdatesTest.java +++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderRuntimeUpdatesTest.java @@ -21,10 +21,12 @@ import java.util.concurrent.atomic.AtomicInteger; import org.eclipse.jetty.deploy.AppProvider; import org.eclipse.jetty.deploy.DeploymentManager; 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.util.Scanner; import org.eclipse.jetty.util.log.Log; import org.junit.After; +import org.junit.Assume; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -137,6 +139,10 @@ public class ScanningAppProviderRuntimeUpdatesTest @Test 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.copyContext("foo.xml","foo.xml"); diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java index 62ab9e64dad..db047df32e3 100644 --- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java +++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java @@ -123,7 +123,7 @@ public class XmlConfiguredJetty properties.setProperty("test.workdir",workishDir.getAbsolutePath()); // 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); properties.store(out,"Generated by " + XmlConfiguredJetty.class.getName()); for (Object key:properties.keySet()) diff --git a/jetty-deploy/src/test/resources/binding-test-contexts-1.xml b/jetty-deploy/src/test/resources/binding-test-contexts-1.xml index 059fa0bb9c5..65e13ab5cf0 100644 --- a/jetty-deploy/src/test/resources/binding-test-contexts-1.xml +++ b/jetty-deploy/src/test/resources/binding-test-contexts-1.xml @@ -36,7 +36,7 @@ - file:///context-binding-test-1.xml + /context-binding-test-1.xml @@ -52,7 +52,7 @@ - /xml-configured-jetty.properties + /xml-configured-jetty.properties diff --git a/jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml b/jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml index f383239947a..c542672b856 100644 --- a/jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml +++ b/jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml @@ -20,7 +20,7 @@ - /xml-configured-jetty.properties + /xml-configured-jetty.properties diff --git a/jetty-distribution/src/main/resources/bin/jetty.sh b/jetty-distribution/src/main/resources/bin/jetty.sh index a916ad12af8..7f6b5494639 100755 --- a/jetty-distribution/src/main/resources/bin/jetty.sh +++ b/jetty-distribution/src/main/resources/bin/jetty.sh @@ -444,7 +444,7 @@ case "$ACTION" in chown "$JETTY_USER" "$JETTY_PID" # FIXME: Broken solution: wordsplitting, pathname expansion, arbitrary command execution, etc. su - "$JETTY_USER" -c " - ${RUN_CMD[*]} --daemon & + exec ${RUN_CMD[*]} --daemon & disown \$! echo \$! > '$JETTY_PID'" else diff --git a/jetty-http/pom.xml b/jetty-http/pom.xml index ba6abb7f21a..52a2628028f 100644 --- a/jetty-http/pom.xml +++ b/jetty-http/pom.xml @@ -17,6 +17,12 @@ jetty-io ${project.version} + + ${servlet.spec.groupId} + ${servlet.spec.artifactId} + ${servlet.spec.version} + provided + junit junit diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipResponseWrapper.java b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipResponseWrapper.java new file mode 100644 index 00000000000..e53f20ee236 --- /dev/null +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipResponseWrapper.java @@ -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 _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 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)); + } +} + diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipStream.java b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipStream.java new file mode 100644 index 00000000000..cf44c479b4a --- /dev/null +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipStream.java @@ -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=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)); + } +} + diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java index 9e57ff263f8..21919c5fe12 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java @@ -169,13 +169,13 @@ public interface EndPoint * the {@link java.net.Socket#getSoTimeout()} for blocking connections, * but {@link AsyncEndPoint} implementations must use other mechanisms * 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(); /* ------------------------------------------------------------ */ /** 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. */ public void setMaxIdleTime(int timeMs) throws IOException; diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java index decf75d076e..1f642abeda9 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java @@ -154,49 +154,39 @@ public class ChannelEndPoint implements EndPoint final NIOBuffer nbuf = (NIOBuffer)buf; final ByteBuffer bbuf=nbuf.getByteBuffer(); //noinspection SynchronizationOnLocalVariableOrMethodParameter - synchronized(bbuf) + + try { - try - { - 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) + synchronized(bbuf) { 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()); - bbuf.position(0); + close(); } + catch (IOException xx) + { + Log.ignore(xx); + } + + if (len>=0) + throw x; } } else diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java index 6fb4b47bf14..252163d3413 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java @@ -326,7 +326,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo try { updateKey(); - this.wait(end-now); + this.wait(timeoutMs>=0?(end-now):10000); } catch (InterruptedException e) { @@ -337,7 +337,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo now=_selectSet.getNow(); } - if (_readBlocked && now>=end) + if (_readBlocked && timeoutMs>0 && now>=end) return false; } } @@ -371,7 +371,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo try { updateKey(); - this.wait(end-now); + this.wait(timeoutMs>=0?(end-now):10000); } catch (InterruptedException e) { @@ -381,7 +381,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo { now=_selectSet.getNow(); } - if (_writeBlocked && now>=end) + if (_writeBlocked && timeoutMs>0 && now>=end) return false; } } diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java index 23390b84453..04ae39cff0e 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java @@ -434,6 +434,10 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa key.attach(endpoint); endpoint.schedule(); } + else if (change instanceof ChangeTask) + { + ((Runnable)change).run(); + } else if (change instanceof Runnable) { dispatch((Runnable)change); @@ -441,6 +445,10 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa else throw new IllegalArgumentException(change.toString()); } + catch (CancelledKeyException e) + { + Log.ignore(e); + } catch (Throwable e) { if (e instanceof ThreadDeath) @@ -450,17 +458,14 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa Log.warn(e); else Log.debug(e); - - if(ch!=null && key==null) + + try { - try - { - ch.close(); - } - catch(IOException e2) - { - Log.debug(e2); - } + ch.close(); + } + catch(IOException e2) + { + Log.debug(e2); } } } @@ -518,6 +523,8 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa // Look for things to do for (SelectionKey key: selector.selectedKeys()) { + SocketChannel channel=null; + try { if (!key.isValid()) @@ -538,7 +545,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa else if (key.isConnectable()) { // Complete a connection of a registered channel - SocketChannel channel = (SocketChannel)key.channel(); + channel = (SocketChannel)key.channel(); boolean connected=false; try { @@ -566,7 +573,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa else { // Wrap readable registered channel in an endpoint - SocketChannel channel = (SocketChannel)key.channel(); + channel = (SocketChannel)key.channel(); SelectChannelEndPoint endpoint = createEndPoint(channel,key); key.attach(endpoint); if (key.isReadable()) @@ -585,6 +592,16 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa else Log.ignore(e); + try + { + if (channel!=null) + channel.close(); + } + catch(IOException e2) + { + Log.debug(e2); + } + if (key != null && !(key.channel() instanceof ServerSocketChannel) && key.isValid()) key.cancel(); } @@ -839,6 +856,14 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa } catch(Exception e) { + addChange(new ChangeTask() + { + public void run() + { + renewSelector(); + } + }); + renewSelector(); } } @@ -1011,4 +1036,11 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa _deferringInterestedOps0 = deferringInterestedOps0; } + + /* ------------------------------------------------------------ */ + /* ------------------------------------------------------------ */ + /* ------------------------------------------------------------ */ + private interface ChangeTask extends Runnable + {} + } diff --git a/jetty-jaspi/pom.xml b/jetty-jaspi/pom.xml index ee5d6b7c05d..3762acea913 100644 --- a/jetty-jaspi/pom.xml +++ b/jetty-jaspi/pom.xml @@ -46,6 +46,20 @@ + + + repository.apache.org + Apache Snapshot Repository + default + http://repository.apache.org/content/groups/snapshots/ + + true + + + false + + + diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java index 1792350b03a..5371c8b60dc 100644 --- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java +++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java @@ -17,6 +17,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; 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.Dumpable; import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; 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 { + private final static Logger __log = Log.getLogger(MBeanContainer.class.getName()); + private final MBeanServer _server; private final WeakHashMap _beans = new WeakHashMap(); private final HashMap _unique = new HashMap(); - private final MultiMap _relations = new MultiMap(); + private final WeakHashMap> _relations = new WeakHashMap>(); private String _domain = null; /** @@ -89,7 +93,7 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste } 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) { + __log.debug("add {}",relationship); ObjectName parent = _beans.get(relationship.getParent()); if (parent == null) { @@ -145,7 +150,15 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste } if (parent != null && child != null) - _relations.add(parent, relationship); + { + List rels = _relations.get(parent); + if (rels==null) + { + rels=new ArrayList(); + _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) { + __log.debug("remove {}",relationship); ObjectName parent = _beans.get(relationship.getParent()); ObjectName child = _beans.get(relationship.getChild()); if (parent != null && child != null) - _relations.removeValue(parent, relationship); + { + List rels = _relations.get(parent); + if (rels!=null) + { + for (Iterator 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) { + __log.debug("removeBean {}",obj); ObjectName bean = _beans.remove(obj); if (bean != null) { - List beanRelations = _relations.getValues(bean); - if (beanRelations != null && beanRelations.size() > 0) + List beanRelations= _relations.remove(bean); + if (beanRelations != null) { - Log.debug("Unregister {}", beanRelations); + __log.debug("Unregister {}", beanRelations); List removeList = new ArrayList(beanRelations); for (Object r : removeList) { @@ -188,15 +214,15 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste try { _server.unregisterMBean(bean); - Log.debug("Unregistered {}", bean); + __log.debug("Unregistered {}", bean); } catch (javax.management.InstanceNotFoundException e) { - Log.ignore(e); + __log.ignore(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) { + __log.debug("addBean {}",obj); try { if (obj == null || _beans.containsKey(obj)) @@ -271,13 +298,13 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste } ObjectInstance oinstance = _server.registerMBean(mbean, oname); - Log.debug("Registered {}", oinstance.getObjectName()); + __log.debug("Registered {}", oinstance.getObjectName()); _beans.put(obj, oinstance.getObjectName()); } catch (Exception e) { - Log.warn("bean: " + obj, e); + __log.warn("bean: " + obj, e); } } diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ObjectMBean.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ObjectMBean.java index 31a8986c861..6a1ca446729 100644 --- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ObjectMBean.java +++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ObjectMBean.java @@ -139,7 +139,12 @@ public class ObjectMBean implements DynamicMBean } 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); else Log.warn(e); diff --git a/jetty-osgi/jetty-osgi-boot/META-INF/MANIFEST.MF b/jetty-osgi/jetty-osgi-boot/META-INF/MANIFEST.MF index fda1e53a20b..dd7d7e3523b 100644 --- a/jetty-osgi/jetty-osgi-boot/META-INF/MANIFEST.MF +++ b/jetty-osgi/jetty-osgi-boot/META-INF/MANIFEST.MF @@ -16,6 +16,19 @@ Import-Package: javax.mail;version="1.4.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.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.service.cm;version="1.2.0", org.osgi.service.packageadmin, @@ -29,25 +42,8 @@ Import-Package: javax.mail;version="1.4.0";resolution:=optional, org.xml.sax.helpers Bundle-RequiredExecutionEnvironment: JavaSE-1.6 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", + org.eclipse.jetty.osgi.nested;version="8.0.0", org.eclipse.jetty.osgi.boot.utils;version="8.0.0", org.eclipse.jetty.osgi.annotations;version="8.0.0" +DynamicImport-Package: org.eclipse.jetty.*;version="[8.0,9)" diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-osgi-nested-default.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-osgi-nested-default.xml index a732f69a484..67d84e9df8f 100644 --- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-osgi-nested-default.xml +++ b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-osgi-nested-default.xml @@ -16,7 +16,10 @@ false - 8443 + true + x-forwarded_for + sslclientcipher + sslsessionid diff --git a/jetty-osgi/jetty-osgi-boot/pom.xml b/jetty-osgi/jetty-osgi-boot/pom.xml index ce612299395..3e975658e8a 100644 --- a/jetty-osgi/jetty-osgi-boot/pom.xml +++ b/jetty-osgi/jetty-osgi-boot/pom.xml @@ -53,7 +53,7 @@ process-resources - + @@ -105,7 +105,7 @@ - org.eclipse.jetty.osgi.boot;singleton:=true + org.eclipse.jetty.osgi.boot org.eclipse.jetty.osgi.boot;version="${parsedVersion.osgiVersion}",org.eclipse.jetty.osgi.boot.utils,org.eclipse.jetty.osgi.nested;version="${parsedVersion.osgiVersion}" org.eclipse.jetty.osgi.boot.JettyBootstrapActivator "+url); + if (debug != 0) + _log.debug(debug + " proxy " + uri + "-->" + url); - if (url==null) + if (url == null) { response.sendError(HttpServletResponse.SC_FORBIDDEN); return; @@ -343,15 +441,15 @@ public class ProxyServlet implements Servlet protected void onResponseComplete() throws IOException { - if (debug!=0) - _log.debug(debug+" complete"); + if (debug != 0) + _log.debug(debug + " complete"); continuation.complete(); } protected void onResponseContent(Buffer content) throws IOException { - if (debug!=0) - _log.debug(debug+" content"+content.length()); + if (debug != 0) + _log.debug(debug + " content" + content.length()); content.writeTo(out); } @@ -361,10 +459,10 @@ public class ProxyServlet implements Servlet protected void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException { - if (debug!=0) - _log.debug(debug+" "+version+" "+status+" "+reason); + if (debug != 0) + _log.debug(debug + " " + version + " " + status + " " + reason); - if (reason!=null && reason.length()>0) + if (reason != null && reason.length() > 0) response.setStatus(status,reason.toString()); else response.setStatus(status); @@ -373,22 +471,27 @@ public class ProxyServlet implements Servlet protected void onResponseHeader(Buffer name, Buffer value) throws IOException { String s = name.toString().toLowerCase(); - if (!_DontProxyHeaders.contains(s) || - (HttpHeaders.CONNECTION_BUFFER.equals(name) && - HttpHeaderValues.CLOSE_BUFFER.equals(value))) + if (!_DontProxyHeaders.contains(s) || (HttpHeaders.CONNECTION_BUFFER.equals(name) && HttpHeaderValues.CLOSE_BUFFER.equals(value))) { - if (debug!=0) - _log.debug(debug+" "+name+": "+value); + if (debug != 0) + _log.debug(debug + " " + name + ": " + value); response.addHeader(name.toString(),value.toString()); } - else if (debug!=0) - _log.debug(debug+" "+name+"! "+value); + else if (debug != 0) + _log.debug(debug + " " + name + "! " + value); } 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) @@ -398,17 +501,19 @@ public class ProxyServlet implements Servlet Log.ignore(ex); return; } - Log.warn(ex.toString()); - Log.debug(ex); - if (!response.isCommitted()) - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - continuation.complete(); + handleOnException(ex,request,response); + + // it is possible this might trigger before the + // continuation.suspend() + if (!continuation.isInitial()) + { + continuation.complete(); + } } protected void onExpire() { - if (!response.isCommitted()) - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + handleOnExpire(request,response); continuation.complete(); } @@ -419,61 +524,61 @@ public class ProxyServlet implements Servlet exchange.setURL(url.toString()); 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 String connectionHdr = request.getHeader("Connection"); - if (connectionHdr!=null) + if (connectionHdr != null) { - connectionHdr=connectionHdr.toLowerCase(); - if (connectionHdr.indexOf("keep-alive")<0 && - connectionHdr.indexOf("close")<0) - connectionHdr=null; + connectionHdr = connectionHdr.toLowerCase(); + if (connectionHdr.indexOf("keep-alive") < 0 && connectionHdr.indexOf("close") < 0) + connectionHdr = null; } // force host - if (_hostHeader!=null) + if (_hostHeader != null) exchange.setRequestHeader("Host",_hostHeader); // copy headers - boolean xForwardedFor=false; - boolean hasContent=false; - long contentLength=-1; + boolean xForwardedFor = false; + boolean hasContent = false; + long contentLength = -1; Enumeration enm = request.getHeaderNames(); while (enm.hasMoreElements()) { // TODO could be better than this! - String hdr=(String)enm.nextElement(); - String lhdr=hdr.toLowerCase(); + String hdr = (String)enm.nextElement(); + String lhdr = hdr.toLowerCase(); if (_DontProxyHeaders.contains(lhdr)) continue; - if (connectionHdr!=null && connectionHdr.indexOf(lhdr)>=0) + if (connectionHdr != null && connectionHdr.indexOf(lhdr) >= 0) continue; - if (_hostHeader!=null && "host".equals(lhdr)) + if (_hostHeader != null && "host".equals(lhdr)) continue; if ("content-type".equals(lhdr)) - hasContent=true; + hasContent = true; else if ("content-length".equals(lhdr)) { - contentLength=request.getContentLength(); + contentLength = request.getContentLength(); exchange.setRequestHeader(HttpHeaders.CONTENT_LENGTH,Long.toString(contentLength)); - if (contentLength>0) - hasContent=true; + if (contentLength > 0) + hasContent = true; } else if ("x-forwarded-for".equals(lhdr)) - xForwardedFor=true; + xForwardedFor = true; Enumeration vals = request.getHeaders(hdr); while (vals.hasMoreElements()) { String val = (String)vals.nextElement(); - if (val!=null) + if (val != null) { - if (debug!=0) - _log.debug(debug+" "+hdr+": "+val); + if (debug != 0) + _log.debug(debug + " " + hdr + ": " + val); exchange.setRequestHeader(hdr,val); } @@ -484,19 +589,36 @@ public class ProxyServlet implements Servlet exchange.setRequestHeader("Via","1.1 (jetty)"); if (!xForwardedFor) { - exchange.addRequestHeader("X-Forwarded-For", - request.getRemoteAddr()); - exchange.addRequestHeader("X-Forwarded-Proto", - request.getScheme()); - exchange.addRequestHeader("X-Forwarded-Host", - request.getServerName()); - exchange.addRequestHeader("X-Forwarded-Server", - request.getLocalName()); + exchange.addRequestHeader("X-Forwarded-For",request.getRemoteAddr()); + exchange.addRequestHeader("X-Forwarded-Proto",request.getScheme()); + exchange.addRequestHeader("X-Forwarded-Host",request.getServerName()); + exchange.addRequestHeader("X-Forwarded-Server",request.getLocalName()); } if (hasContent) 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); _client.send(exchange); @@ -504,11 +626,8 @@ public class ProxyServlet implements Servlet } } - /* ------------------------------------------------------------ */ - public void handleConnect(HttpServletRequest request, - HttpServletResponse response) - throws IOException + public void handleConnect(HttpServletRequest request, HttpServletResponse response) throws IOException { String uri = request.getRequestURI(); @@ -516,27 +635,26 @@ public class ProxyServlet implements Servlet String host = ""; 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); - if (host.indexOf('/')>0) - host = host.substring(host.indexOf('/')+1); + if (host.indexOf('/') > 0) + host = host.substring(host.indexOf('/') + 1); } // 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)) - //{ - // sendForbid(request,response,uri); - //} - //else + // if (isForbidden(HttpMessage.__SSL_SCHEME,addrPort.getHost(),addrPort.getPort(),false)) + // { + // sendForbid(request,response,uri); + // } + // else { - InputStream in=request.getInputStream(); - OutputStream out=response.getOutputStream(); + InputStream in = request.getInputStream(); + OutputStream out = response.getOutputStream(); 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) - throws MalformedURLException + protected HttpURI proxyHttpURI(String scheme, String serverName, int serverPort, String uri) throws MalformedURLException { - if (!validateDestination(serverName, uri)) + if (!validateDestination(serverName,uri)) 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() */ public String getServletInfo() @@ -569,17 +687,85 @@ public class ProxyServlet implements 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. - * - * This convenience extension to ProxyServlet configures the servlet as a transparent proxy. - * The servlet is configured with init parameters: + * + * This convenience extension to ProxyServlet configures the servlet as a transparent proxy. The servlet is configured with init parameters: *
    *
  • ProxyTo - a URI like http://host:80/context to which the request is proxied. *
  • Prefix - a URI prefix that is striped from the start of the forwarded URI. *
- * For example, if a request was received at /foo/bar and the ProxyTo was http://host:80/context - * and the Prefix was /foo, then the request would be proxied to http://host:80/context/bar + * For example, if a request was received at /foo/bar and the ProxyTo was http://host:80/context and the Prefix was /foo, then the request would be proxied + * to http://host:80/context/bar * */ public static class Transparent extends ProxyServlet @@ -633,7 +819,7 @@ public class ProxyServlet implements Servlet if (!_prefix.startsWith("/")) throw new UnavailableException("Prefix parameter must start with a '/'."); - _log.info(config.getServletName()+" @ " + _prefix + " to " + _proxyTo); + _log.info(config.getServletName() + " @ " + _prefix + " to " + _proxyTo); } @Override diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterTest.java new file mode 100644 index 00000000000..b1e41f6a4c8 --- /dev/null +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterTest.java @@ -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")); + } +} diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterTest.java new file mode 100644 index 00000000000..3ad66eab23f --- /dev/null +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterTest.java @@ -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")); + } +} diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java b/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java index f4d0a94db79..4e2d6115f9c 100644 --- a/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java +++ b/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java @@ -562,7 +562,15 @@ public class Main if (_exec) { 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.getInputStream(),System.out); copyInThread(System.in,process.getOutputStream()); diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java b/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java index ba0fd87a93d..24914935709 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java @@ -231,7 +231,10 @@ public class UrlEncoded extends MultiMap key = encoded ?decodeString(content,mark+1,content.length()-mark-1,charset) :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) 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); return; diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/component/Container.java b/jetty-util/src/main/java/org/eclipse/jetty/util/component/Container.java index 4622c6662aa..0cec73d2463 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/component/Container.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/component/Container.java @@ -12,6 +12,7 @@ // ======================================================================== package org.eclipse.jetty.util.component; +import java.lang.ref.WeakReference; import java.util.EventListener; import java.util.concurrent.CopyOnWriteArrayList; @@ -225,20 +226,19 @@ public class Container /* ------------------------------------------------------------ */ /** A Container event. * @see Listener - * */ public static class Relationship { - private Object _parent; - private Object _child; + private final WeakReference _parent; + private final WeakReference _child; private String _relationship; private Container _container; private Relationship(Container container, Object parent,Object child, String relationship) { _container=container; - _parent=parent; - _child=child; + _parent=new WeakReference(parent); + _child=new WeakReference(child); _relationship=relationship; } @@ -249,12 +249,12 @@ public class Container public Object getChild() { - return _child; + return _child.get(); } public Object getParent() { - return _parent; + return _parent.get(); } public String getRelationship() @@ -280,7 +280,7 @@ public class Container if (o==null || !(o instanceof Relationship)) return false; 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); } } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java index 14004a62b18..ae3945f7376 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java @@ -536,7 +536,7 @@ public abstract class Resource implements ResourceFactory buf.append("\">"); buf.append(deTag(ls[i])); buf.append(" "); - buf.append(""); + buf.append(""); buf.append(item.length()); buf.append(" bytes "); buf.append(dfmt.format(new Date(item.lastModified()))); diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/ScannerTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/ScannerTest.java index c43167f1279..8a85c295627 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/ScannerTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/ScannerTest.java @@ -87,6 +87,7 @@ public class ScannerTest @Test public void testAddedChangeRemove() throws Exception { + // TODO needs to be further investigated Assume.assumeTrue(!OS.IS_WINDOWS && !OS.IS_OSX); touch("a0"); @@ -195,6 +196,7 @@ public class ScannerTest @Test public void testSizeChange() throws Exception { + // TODO needs to be further investigated Assume.assumeTrue(!OS.IS_WINDOWS && !OS.IS_OSX); touch("tsc0"); diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/URLEncodedTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/URLEncodedTest.java index ac8866b62b8..30f70621404 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/URLEncodedTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/URLEncodedTest.java @@ -19,6 +19,7 @@ import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.io.UnsupportedEncodingException; +import org.junit.Ignore; import org.junit.Test; @@ -28,13 +29,30 @@ import org.junit.Test; */ 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 public void testUrlEncoded() throws UnsupportedEncodingException { 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.decode("Name1=Value1"); @@ -156,6 +174,7 @@ public class URLEncodedTest {StringUtil.__UTF16,StringUtil.__UTF16}, }; + for (int i=0;i toList(Enumeration e) { - List list = new ArrayList(); - while (e!=null && e.hasMoreElements()) - list.add(e.nextElement()); - return list; + if (e==null) + return new ArrayList(); + return Collections.list(e); } /* ------------------------------------------------------------ */ diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/AbstractExtension.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/AbstractExtension.java index a81223729f9..ba6e4d7b892 100644 --- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/AbstractExtension.java +++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/AbstractExtension.java @@ -11,36 +11,16 @@ import org.eclipse.jetty.websocket.WebSocketParser.FrameHandler; public class AbstractExtension implements Extension { + private static final int[] __mask = { -1, 0x04, 0x02, 0x01}; private final String _name; - private final byte[] _dataOpcodes; - private final byte[] _controlOpcodes; - private final byte[] _bitMasks; private final Map _parameters=new HashMap(); private FrameHandler _inbound; private WebSocketGenerator _outbound; private WebSocket.FrameConnection _connection; - public AbstractExtension(String name,int dataCodes, int controlCodes, int flags) + public AbstractExtension(String 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() @@ -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; _inbound=incoming; _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() @@ -130,46 +102,27 @@ public class AbstractExtension implements Extension // System.err.printf("addFrame %s %x %x %d\n",getExtensionName(),flags,opcode,length); _outbound.addFrame(flags,opcode,content,offset,length); } - - public byte dataOpcode(int i) + + public byte setFlag(byte flags,int rsv) { - return _dataOpcodes[i]; - } - - public int dataIndex(byte op) - { - 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; + if (rsv<1||rsv>3) + throw new IllegalArgumentException("rsv"+rsv); + byte b=(byte)(flags | __mask[rsv]); + return b; } - public byte setFlag(byte flags,int flag) + public byte clearFlag(byte flags,int rsv) { - return (byte)(flags | _bitMasks[flag]); - } - - public byte clearFlag(byte flags,int flag) - { - return (byte)(flags & ~_bitMasks[flag]); + if (rsv<1||rsv>3) + throw new IllegalArgumentException("rsv"+rsv); + return (byte)(flags & ~__mask[rsv]); } - 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() diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/DeflateFrameExtension.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/DeflateFrameExtension.java index c8b5dd100ca..68bf4f222d5 100644 --- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/DeflateFrameExtension.java +++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/DeflateFrameExtension.java @@ -13,13 +13,13 @@ import org.eclipse.jetty.util.log.Log; public class DeflateFrameExtension extends AbstractExtension { - private int _minLength=64; + private int _minLength=8; private Deflater _deflater; private Inflater _inflater; public DeflateFrameExtension() { - super("x-deflate-frame",0,0,1); + super("x-deflate-frame"); } @Override @@ -45,12 +45,12 @@ public class DeflateFrameExtension extends AbstractExtension @Override 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); return; } - + if (buffer.array()==null) buffer=buffer.asMutableBuffer(); @@ -61,7 +61,8 @@ public class DeflateFrameExtension extends AbstractExtension length=0; while(b-->0) length=0x100*length+(0xff&buffer.get()); - } + } + // TODO check a max framesize _inflater.setInput(buffer.array(),buffer.getIndex(),buffer.length()); @@ -76,12 +77,12 @@ public class DeflateFrameExtension extends AbstractExtension buf.setPutIndex(buf.putIndex()+inflated); } - super.onFrame(clearFlag(flags,0),opcode,buf); + super.onFrame(clearFlag(flags,1),opcode,buf); } catch(DataFormatException 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 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; } @@ -133,8 +134,8 @@ public class DeflateFrameExtension extends AbstractExtension int l = _deflater.deflate(out,out_offset,length-out_offset); 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 - super.addFrame(clearFlag(flags,0),opcode,content,offset,length); + super.addFrame(clearFlag(flags,1),opcode,content,offset,length); } } diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/Extension.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/Extension.java index 2d725f52365..b3c93ec4600 100644 --- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/Extension.java +++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/Extension.java @@ -6,11 +6,8 @@ public interface Extension extends WebSocketParser.FrameHandler, WebSocketGenera { public String getName(); public String getParameterizedName(); - public int getDataOpcodes(); - public int getControlOpcodes(); - public int getReservedBits(); public boolean init(Map 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); } diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/FragmentExtension.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/FragmentExtension.java index 23211249087..106f718be53 100644 --- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/FragmentExtension.java +++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/FragmentExtension.java @@ -10,7 +10,7 @@ public class FragmentExtension extends AbstractExtension public FragmentExtension() { - super("fragment",0,0,0); + super("fragment"); } @Override diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/IdentityExtension.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/IdentityExtension.java index 4f2aeb9cf68..c8036c69d92 100644 --- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/IdentityExtension.java +++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/IdentityExtension.java @@ -4,6 +4,6 @@ public class IdentityExtension extends AbstractExtension { public IdentityExtension() { - super("identity",0,0,0); + super("identity"); } } diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/TestClient.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/TestClient.java index fc41fc04889..f865a93bd10 100644 --- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/TestClient.java +++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/TestClient.java @@ -37,8 +37,8 @@ public class TestClient private final BufferedWriter _output; private final BufferedReader _input; private final SocketEndPoint _endp; - private final WebSocketGeneratorD07 _generator; - private final WebSocketParserD07 _parser; + private final WebSocketGeneratorD7_9 _generator; + private final WebSocketParserD7_9 _parser; private int _framesSent; private int _messagesSent; private int _framesReceived; @@ -59,19 +59,19 @@ public class TestClient { _framesReceived++; _frames++; - if (opcode == WebSocketConnectionD07.OP_CLOSE) + if (opcode == WebSocketConnectionD7_9.OP_CLOSE) { byte[] data=buffer.asArray(); // 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(); _socket.shutdownOutput(); _socket.close(); 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(); } @@ -81,7 +81,7 @@ public class TestClient _opcode=opcode; - if (WebSocketConnectionD07.isLastFrame(flags)) + if (WebSocketConnectionD7_9.isLastFrame(flags)) { _messagesReceived++; Long start=_starts.take(); @@ -123,8 +123,8 @@ public class TestClient _input = new BufferedReader(new InputStreamReader(_socket.getInputStream(), "ISO-8859-1")); _endp=new SocketEndPoint(_socket); - _generator = new WebSocketGeneratorD07(new WebSocketBuffers(32*1024),_endp,new WebSocketGeneratorD07.FixedMaskGen(new byte[4])); - _parser = new WebSocketParserD07(new WebSocketBuffers(32*1024),_endp,_handler,false); + _generator = new WebSocketGeneratorD7_9(new WebSocketBuffers(32*1024),_endp,new WebSocketGeneratorD7_9.FixedMaskGen(new byte[4])); + _parser = new WebSocketParserD7_9(new WebSocketBuffers(32*1024),_endp,_handler,false); } public int getSize() @@ -170,7 +170,7 @@ public class TestClient if (line.startsWith("Sec-WebSocket-Accept:")) { 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:")) { @@ -205,7 +205,7 @@ public class TestClient break; byte data[]=null; - if (opcode==WebSocketConnectionD07.OP_TEXT) + if (opcode==WebSocketConnectionD7_9.OP_TEXT) { StringBuilder b = new StringBuilder(); while (b.length()<_size) @@ -228,7 +228,7 @@ public class TestClient { _framesSent++; 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) 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(); 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 - client.ping(count,WebSocketConnectionD07.OP_PING,-1); + client.ping(count,WebSocketConnectionD7_9.OP_PING,-1); } finally { diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD07.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD7_9.java similarity index 89% rename from jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD07.java rename to jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD7_9.java index da85e08593d..12c3d91a85a 100644 --- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD07.java +++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD7_9.java @@ -38,7 +38,7 @@ import org.eclipse.jetty.websocket.WebSocket.OnTextMessage; import org.eclipse.jetty.websocket.WebSocket.OnBinaryMessage; 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_TEXT = 0x01; @@ -69,9 +69,9 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc private final static byte[] MAGIC; private final IdleCheck _idle; private final List _extensions; - private final WebSocketParserD07 _parser; + private final WebSocketParserD7_9 _parser; private final WebSocketParser.FrameHandler _inbound; - private final WebSocketGeneratorD07 _generator; + private final WebSocketGeneratorD7_9 _generator; private final WebSocketGenerator _outbound; private final WebSocket _webSocket; private final OnFrame _onFrame; @@ -79,6 +79,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc private final OnTextMessage _onTextMessage; private final OnControl _onControl; private final String _protocol; + private final int _draft; private boolean _closedIn; private boolean _closedOut; 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 extensions) + public WebSocketConnectionD7_9(WebSocket websocket, EndPoint endpoint, WebSocketBuffers buffers, long timestamp, int maxIdleTime, String protocol, List extensions,int draft) throws IOException { super(endpoint,timestamp); @@ -115,6 +116,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc if (endpoint instanceof AsyncEndPoint) ((AsyncEndPoint)endpoint).cancelIdle(); + _draft=draft; _endp.setMaxIdleTime(maxIdleTime); _webSocket = websocket; @@ -122,35 +124,18 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc _onTextMessage=_webSocket instanceof OnTextMessage ? (OnTextMessage)_webSocket : null; _onBinaryMessage=_webSocket instanceof OnBinaryMessage ? (OnBinaryMessage)_webSocket : null; _onControl=_webSocket instanceof OnControl ? (OnControl)_webSocket : null; - _generator = new WebSocketGeneratorD07(buffers, _endp,null); + _generator = new WebSocketGeneratorD7_9(buffers, _endp,null); _extensions=extensions; if (_extensions!=null) { - byte data_op=OP_EXT_DATA; - byte ctrl_op=OP_EXT_CTRL; - byte flag_mask=0x4; int e=0; for (Extension extension : _extensions) { - byte[] data_ops=new byte[extension.getDataOpcodes()]; - for (int i=0;i>1); - } - extension.bind( _connection, e==extensions.size()-1?_frameHandler:extensions.get(e+1), - e==0?_generator:extensions.get(e-1), - data_ops,ctrl_ops,flag_masks); + e==0?_generator:extensions.get(e-1)); e++; } } @@ -158,7 +143,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc _outbound=_extensions.size()==0?_generator:extensions.get(extensions.size()-1); _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; @@ -266,7 +251,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc @Override 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() { - _webSocket.onClose(WebSocketConnectionD07.CLOSE_NORMAL,""); + _webSocket.onClose(WebSocketConnectionD7_9.CLOSE_NORMAL,""); } /* ------------------------------------------------------------ */ @@ -313,11 +298,11 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc else { if (code<=0) - code=WebSocketConnectionD07.CLOSE_NORMAL; + code=WebSocketConnectionD7_9.CLOSE_NORMAL; byte[] bytes = ("xx"+(message==null?"":message)).getBytes(StringUtil.__ISO_8859_1); bytes[0]=(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(); @@ -353,8 +338,8 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc private class FrameConnectionD07 implements WebSocket.FrameConnection { volatile boolean _disconnecting; - int _maxTextMessage=WebSocketConnectionD07.this._maxTextMessageSize; - int _maxBinaryMessage=WebSocketConnectionD07.this._maxBinaryMessageSize; + int _maxTextMessage=WebSocketConnectionD7_9.this._maxTextMessageSize; + int _maxBinaryMessage=WebSocketConnectionD7_9.this._maxBinaryMessageSize; /* ------------------------------------------------------------ */ public synchronized void sendMessage(String content) throws IOException @@ -362,7 +347,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc if (_closedOut) throw new IOException("closing"); 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(); _idle.access(_endp); } @@ -372,7 +357,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc { if (_closedOut) 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(); _idle.access(_endp); } @@ -415,7 +400,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc if (_disconnecting) return; _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); - synchronized(WebSocketConnectionD07.this) + synchronized(WebSocketConnectionD7_9.this) { // Ignore incoming after a close if (_closedIn) @@ -565,10 +550,10 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc switch(opcode) { - case WebSocketConnectionD07.OP_CONTINUATION: + case WebSocketConnectionD7_9.OP_CONTINUATION: { // 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())) { @@ -583,7 +568,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc } 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(); _opcode=-1; } @@ -592,7 +577,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc { 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(); _opcode=-1; } @@ -617,21 +602,21 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc } break; } - case WebSocketConnectionD07.OP_PING: + case WebSocketConnectionD7_9.OP_PING: { Log.debug("PING {}",this); 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; } - case WebSocketConnectionD07.OP_PONG: + case WebSocketConnectionD7_9.OP_PONG: { Log.debug("PONG {}",this); break; } - case WebSocketConnectionD07.OP_CLOSE: + case WebSocketConnectionD7_9.OP_CLOSE: { int code=-1; 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) { @@ -661,12 +646,12 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc { // If this is a text fragment, append to buffer if (_utf8.append(buffer.array(),buffer.getIndex(),buffer.length(),_connection.getMaxTextMessageSize())) - _opcode=WebSocketConnectionD07.OP_TEXT; + _opcode=WebSocketConnectionD7_9.OP_TEXT; else { _utf8.reset(); _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()) { - _connection.close(WebSocketConnectionD07.CLOSE_LARGE,"Message size > "+_connection.getMaxBinaryMessageSize()); + _connection.close(WebSocketConnectionD7_9.CLOSE_LARGE,"Message size > "+_connection.getMaxBinaryMessageSize()); if (_aggregate!=null) _aggregate.clear(); _opcode=-1; @@ -726,7 +711,7 @@ public class WebSocketConnectionD07 extends AbstractConnection implements WebSoc 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); } } + + /* ------------------------------------------------------------ */ + public String toString() + { + return "WS/D"+_draft+"-"+_endp; + } } diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketFactory.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketFactory.java index ba37fc0294f..d1cceda2640 100644 --- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketFactory.java +++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketFactory.java @@ -164,8 +164,10 @@ public class WebSocketFactory connection = new WebSocketConnectionD06(websocket, endp, _buffers, http.getTimeStamp(), _maxIdleTime, protocol); break; case 7: - extensions= initExtensions(extensions_requested,8-WebSocketConnectionD07.OP_EXT_DATA, 16-WebSocketConnectionD07.OP_EXT_CTRL,3); - connection = new WebSocketConnectionD07(websocket, endp, _buffers, http.getTimeStamp(), _maxIdleTime, protocol,extensions); + case 8: + 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; default: Log.warn("Unsupported Websocket version: "+draft); @@ -256,14 +258,8 @@ public class WebSocketFactory if (extension.init(parameters)) { - if (extension.getDataOpcodes()<=maxDataOpcodes && extension.getControlOpcodes()<=maxControlOpcodes && extension.getReservedBits()<=maxReservedBits) - { - Log.debug("add {} {}",extName,parameters); - extensions.add(extension); - maxDataOpcodes-=extension.getDataOpcodes(); - maxControlOpcodes-=extension.getControlOpcodes(); - maxReservedBits-=extension.getReservedBits(); - } + Log.debug("add {} {}",extName,parameters); + extensions.add(extension); } } Log.debug("extensions={}",extensions); diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketGeneratorD07.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketGeneratorD7_9.java similarity index 95% rename from jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketGeneratorD07.java rename to jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketGeneratorD7_9.java index 4cc6d3dd601..f6a12c90b6b 100644 --- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketGeneratorD07.java +++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketGeneratorD7_9.java @@ -30,7 +30,7 @@ import org.eclipse.jetty.util.TypeUtil; * threads will call the addMessage methods while other * threads are flushing the generator. */ -public class WebSocketGeneratorD07 implements WebSocketGenerator +public class WebSocketGeneratorD7_9 implements WebSocketGenerator { final private WebSocketBuffers _buffers; 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; _endp=endp; _maskGen=null; } - public WebSocketGeneratorD07(WebSocketBuffers buffers, EndPoint endp, MaskGen maskGen) + public WebSocketGeneratorD7_9(WebSocketBuffers buffers, EndPoint endp, MaskGen maskGen) { _buffers=buffers; _endp=endp; @@ -118,14 +118,14 @@ public class WebSocketGeneratorD07 implements WebSocketGenerator if (_buffer==null) _buffer=mask?_buffers.getBuffer():_buffers.getDirectBuffer(); - boolean last=WebSocketConnectionD07.isLastFrame(flags); + boolean last=WebSocketConnectionD7_9.isLastFrame(flags); byte orig=opcode; int space=mask?14:10; do { - opcode = _opsent?WebSocketConnectionD07.OP_CONTINUATION:opcode; + opcode = _opsent?WebSocketConnectionD7_9.OP_CONTINUATION:opcode; opcode=(byte)(((0xf&flags)<<4)+(0xf&opcode)); _opsent=true; diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketParserD07.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketParserD7_9.java similarity index 94% rename from jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketParserD07.java rename to jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketParserD7_9.java index 896370592ec..8b4f889aa11 100644 --- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketParserD07.java +++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketParserD7_9.java @@ -29,7 +29,7 @@ import org.eclipse.jetty.util.log.Log; * Parser the WebSocket protocol. * */ -public class WebSocketParserD07 implements WebSocketParser +public class WebSocketParserD7_9 implements WebSocketParser { public enum State { @@ -72,7 +72,7 @@ public class WebSocketParserD07 implements WebSocketParser * @param endp * @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; _endp=endp; @@ -160,11 +160,11 @@ public class WebSocketParserD07 implements WebSocketParser _opcode=(byte)(b&0xf); _flags=(byte)(0xf&(b>>4)); - if (WebSocketConnectionD07.isControlFrame(_opcode)&&!WebSocketConnectionD07.isLastFrame(_flags)) + if (WebSocketConnectionD7_9.isControlFrame(_opcode)&&!WebSocketConnectionD7_9.isLastFrame(_flags)) { events++; Log.warn("Fragmented Control from "+_endp); - _handler.close(WebSocketConnectionD07.CLOSE_PROTOCOL,"Fragmented control"); + _handler.close(WebSocketConnectionD7_9.CLOSE_PROTOCOL,"Fragmented control"); _skip=true; } @@ -205,7 +205,7 @@ public class WebSocketParserD07 implements WebSocketParser if (_length>_buffer.capacity()) { events++; - _handler.close(WebSocketConnectionD07.CLOSE_LARGE,"frame size "+_length+">"+_buffer.capacity()); + _handler.close(WebSocketConnectionD7_9.CLOSE_LARGE,"frame size "+_length+">"+_buffer.capacity()); _skip=true; } @@ -224,7 +224,7 @@ public class WebSocketParserD07 implements WebSocketParser if (_length>=_buffer.capacity()) { events++; - _handler.close(WebSocketConnectionD07.CLOSE_LARGE,"frame size "+_length+">"+_buffer.capacity()); + _handler.close(WebSocketConnectionD7_9.CLOSE_LARGE,"frame size "+_length+">"+_buffer.capacity()); _skip=true; } @@ -267,7 +267,7 @@ public class WebSocketParserD07 implements WebSocketParser _buffer.skip(_bytesNeeded); _state=State.START; events++; - _handler.close(WebSocketConnectionD07.CLOSE_PROTOCOL,"bad mask"); + _handler.close(WebSocketConnectionD7_9.CLOSE_PROTOCOL,"bad mask"); } else { diff --git a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketGeneratorD07Test.java b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketGeneratorD7_9Test.java similarity index 91% rename from jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketGeneratorD07Test.java rename to jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketGeneratorD7_9Test.java index 1560bb44f26..0fe9eedd9ae 100644 --- a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketGeneratorD07Test.java +++ b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketGeneratorD7_9Test.java @@ -11,7 +11,7 @@ import org.junit.Test; /** * @version $Revision$ $Date$ */ -public class WebSocketGeneratorD07Test +public class WebSocketGeneratorD7_9Test { private ByteArrayBuffer _out; private WebSocketGenerator _generator; @@ -20,7 +20,7 @@ public class WebSocketGeneratorD07Test byte[] _mask = new byte[4]; 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}); @Before @@ -42,7 +42,7 @@ public class WebSocketGeneratorD07Test @Test 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); _generator.addFrame((byte)0x8,(byte)0x04,data,0,data.length); @@ -69,7 +69,7 @@ public class WebSocketGeneratorD07Test @Test public void testOneBuffer() throws Exception { - _generator = new WebSocketGeneratorD07(_buffers, _endPoint,null); + _generator = new WebSocketGeneratorD7_9(_buffers, _endPoint,null); String string = "Hell\uFF4F W\uFF4Frld"; byte[] bytes=string.getBytes(StringUtil.__UTF8); @@ -97,7 +97,7 @@ public class WebSocketGeneratorD07Test @Test public void testOneLongBuffer() throws Exception { - _generator = new WebSocketGeneratorD07(_buffers, _endPoint,null); + _generator = new WebSocketGeneratorD7_9(_buffers, _endPoint,null); byte[] b=new byte[150]; for (int i=0;i "+message); diff --git a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageD07Test.java b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageD7_9Test.java similarity index 96% rename from jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageD07Test.java rename to jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageD7_9Test.java index a38973bcbc2..1c097edb924 100644 --- a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageD07Test.java +++ b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageD7_9Test.java @@ -34,7 +34,7 @@ import org.junit.Test; /** * @version $Revision$ $Date$ */ -public class WebSocketMessageD07Test +public class WebSocketMessageD7_9Test { private static Server _server; private static Connector _connector; @@ -75,7 +75,7 @@ public class WebSocketMessageD07Test @Test public void testHash() { - assertEquals("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",WebSocketConnectionD07.hashKey("dGhlIHNhbXBsZSBub25jZQ==")); + assertEquals("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",WebSocketConnectionD7_9.hashKey("dGhlIHNhbXBsZSBub25jZQ==")); } @Test @@ -116,7 +116,7 @@ public class WebSocketMessageD07Test String data=message.toString(); _serverWebSocket.connection.sendMessage(data); - assertEquals(WebSocketConnectionD07.OP_TEXT,input.read()); + assertEquals(WebSocketConnectionD7_9.OP_TEXT,input.read()); assertEquals(0x7e,input.read()); assertEquals(0x1f,input.read()); assertEquals(0xf6,input.read()); @@ -272,7 +272,7 @@ public class WebSocketMessageD07Test "Sec-WebSocket-Origin: http://example.com\r\n"+ "Sec-WebSocket-Protocol: echo\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"+ "\r\n").getBytes("ISO-8859-1")); output.flush(); @@ -322,8 +322,7 @@ public class WebSocketMessageD07Test output.write(buf,0,l+3); output.flush(); - - assertEquals(0x40+WebSocketConnectionD07.OP_TEXT,input.read()); + assertEquals(0x40+WebSocketConnectionD7_9.OP_TEXT,input.read()); assertEquals(0x20+3,input.read()); assertEquals(0x7e,input.read()); assertEquals(0x02,input.read()); @@ -491,7 +490,7 @@ public class WebSocketMessageD07Test output.write(bytes[i]^0xff); output.flush(); - assertEquals(0x80|WebSocketConnectionD07.OP_CLOSE,input.read()); + assertEquals(0x80|WebSocketConnectionD7_9.OP_CLOSE,input.read()); assertEquals(30,input.read()); int code=(0xff&input.read())*0x100+(0xff&input.read()); 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()); int code=(0xff&input.read())*0x100+(0xff&input.read()); assertEquals(1004,code); @@ -578,7 +577,7 @@ public class WebSocketMessageD07Test assertNotNull(_serverWebSocket.connection); _serverWebSocket.getConnection().setMaxBinaryMessageSize(1024); - output.write(WebSocketConnectionD07.OP_BINARY); + output.write(WebSocketConnectionD7_9.OP_BINARY); output.write(0x8a); output.write(0xff); output.write(0xff); @@ -599,7 +598,7 @@ public class WebSocketMessageD07Test output.write(bytes[i]^0xff); output.flush(); - assertEquals(0x80+WebSocketConnectionD07.OP_BINARY,input.read()); + assertEquals(0x80+WebSocketConnectionD7_9.OP_BINARY,input.read()); assertEquals(20,input.read()); lookFor("01234567890123456789",input); } @@ -656,7 +655,7 @@ public class WebSocketMessageD07Test output.flush(); - assertEquals(0x80|WebSocketConnectionD07.OP_CLOSE,input.read()); + assertEquals(0x80|WebSocketConnectionD7_9.OP_CLOSE,input.read()); assertEquals(19,input.read()); int code=(0xff&input.read())*0x100+(0xff&input.read()); assertEquals(1004,code); @@ -705,7 +704,7 @@ public class WebSocketMessageD07Test output.write(bytes[i]^0xff); output.flush(); - assertEquals(0x80|WebSocketConnectionD07.OP_CLOSE,input.read()); + assertEquals(0x80|WebSocketConnectionD7_9.OP_CLOSE,input.read()); assertEquals(19,input.read()); int code=(0xff&input.read())*0x100+(0xff&input.read()); assertEquals(1004,code); @@ -831,14 +830,14 @@ public class WebSocketMessageD07Test final AtomicReference received = new AtomicReference(); 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); gen.addFrame((byte)0x8,(byte)0x4,data,0,data.length); 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) { @@ -863,15 +862,15 @@ public class WebSocketMessageD07Test final AtomicReference received = new AtomicReference(); 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); gen.addFrame((byte)0x8,(byte)0x1,data,0,data.length); 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) { @@ -994,9 +993,9 @@ public class WebSocketMessageD07Test { switch(opcode) { - case WebSocketConnectionD07.OP_CLOSE: - case WebSocketConnectionD07.OP_PING: - case WebSocketConnectionD07.OP_PONG: + case WebSocketConnectionD7_9.OP_CLOSE: + case WebSocketConnectionD7_9.OP_PING: + case WebSocketConnectionD7_9.OP_PONG: break; default: diff --git a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketParserD07Test.java b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketParserD7_9Test.java similarity index 97% rename from jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketParserD07Test.java rename to jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketParserD7_9Test.java index d3ce5fe003f..2611715c243 100644 --- a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketParserD07Test.java +++ b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketParserD7_9Test.java @@ -20,7 +20,7 @@ import org.junit.Test; /** * @version $Revision$ $Date$ */ -public class WebSocketParserD07Test +public class WebSocketParserD7_9Test { private MaskedByteArrayBuffer _in; private Handler _handler; @@ -87,7 +87,7 @@ public class WebSocketParserD07Test ByteArrayEndPoint endPoint = new ByteArrayEndPoint(); endPoint.setNonBlocking(true); _handler = new Handler(); - _parser=new WebSocketParserD07(buffers, endPoint,_handler,true); + _parser=new WebSocketParserD7_9(buffers, endPoint,_handler,true); _in = new MaskedByteArrayBuffer(); endPoint.setIn(_in); @@ -187,7 +187,7 @@ public class WebSocketParserD07Test { WebSocketBuffers buffers = new WebSocketBuffers(0x20000); 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); endPoint.setIn(in); @@ -261,7 +261,7 @@ public class WebSocketParserD07Test assertTrue(progress>0); - assertEquals(WebSocketConnectionD07.CLOSE_LARGE,_handler._code); + assertEquals(WebSocketConnectionD7_9.CLOSE_LARGE,_handler._code); for (int i=0;i<2048;i++) _in.put((byte)'a'); progress =_parser.parseNext(); diff --git a/pom.xml b/pom.xml index 799af9442a7..fe5f18b4926 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-parent - 17 + 18 org.eclipse.jetty jetty-project @@ -23,13 +23,13 @@ servlet-api 3.0.20100224 1.0 - 1.5 + 1.6 1.2 - scm:svn:http://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/branches/jetty-8 - scm:svn:svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/branches/jetty-8 - http://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/branches/jetty-8 + scm:git:http://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.project.git + scm:git:ssh://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.project.git + http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree install @@ -45,7 +45,6 @@ maven-release-plugin - svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/tags true @@ -420,14 +419,10 @@ --> osgi - - false - jetty-osgi diff --git a/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/HttpTester.java b/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/HttpTester.java index edbcd5a4bd5..c7b63308bef 100644 --- a/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/HttpTester.java +++ b/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/HttpTester.java @@ -140,6 +140,23 @@ public class HttpTester 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 { @@ -438,6 +455,16 @@ public class HttpTester return null; } + /* ------------------------------------------------------------ */ + public byte[] getContentBytes() + { + if (_parsedContent!=null) + return _parsedContent.toByteArray(); + if (_genContent!=null) + return _genContent; + return null; + } + /* ------------------------------------------------------------ */ public void setContent(String content) { diff --git a/test-jetty-webapp/src/main/java/com/acme/Dump.java b/test-jetty-webapp/src/main/java/com/acme/Dump.java index e59c7948878..fba961cda7a 100644 --- a/test-jetty-webapp/src/main/java/com/acme/Dump.java +++ b/test-jetty-webapp/src/main/java/com/acme/Dump.java @@ -22,6 +22,9 @@ import java.io.PrintWriter; import java.io.Reader; import java.lang.reflect.Array; import java.lang.reflect.Field; +import java.net.URL; +import java.util.Collections; +import java.util.Collection; import java.util.Date; import java.util.Enumeration; import java.util.Locale; @@ -700,6 +703,13 @@ public class Dump extends HttpServlet pout.write("\n"); pout.write("Thread.currentThread().getContextClassLoader().getResource(...): "); pout.write(""+Thread.currentThread().getContextClassLoader().getResource(res)+""); + pout.write("\n"); + pout.write("Thread.currentThread().getContextClassLoader().getResources(...): "); + Enumeration urls = Thread.currentThread().getContextClassLoader().getResources(res); + if (urls==null) + pout.write("null"); + else + pout.write(""+Collections.list(urls)+""); } diff --git a/test-jetty-webapp/src/main/java/com/acme/RewriteServlet.java b/test-jetty-webapp/src/main/java/com/acme/RewriteServlet.java index b7f219dd5b9..d0efe956132 100644 --- a/test-jetty-webapp/src/main/java/com/acme/RewriteServlet.java +++ b/test-jetty-webapp/src/main/java/com/acme/RewriteServlet.java @@ -64,6 +64,6 @@ public class RewriteServlet extends HttpServlet @Override public String getServletInfo() { - return "Rewrite sServlet"; + return "Rewrite Servlet"; } } diff --git a/test-jetty-webapp/src/main/webapp/rewrite/index.html b/test-jetty-webapp/src/main/webapp/rewrite/index.html index 7f19c2f1b1f..fd9e22ffc38 100644 --- a/test-jetty-webapp/src/main/webapp/rewrite/index.html +++ b/test-jetty-webapp/src/main/webapp/rewrite/index.html @@ -8,6 +8,6 @@

Rewrite not enabled

The rewrite handler is currently not enabled. To enable this demo, start up Jetty with:

-java -jar start.jar OPTIONS=default,rewrite etc/jetty.xml etc/jetty-rewrite.xml +java -jar start.jar OPTIONS=rewrite etc/jetty-rewrite.xml diff --git a/test-jetty-webapp/src/main/webapp/rewrite/info.html b/test-jetty-webapp/src/main/webapp/rewrite/info.html index 88e87b1406e..f273b665865 100644 --- a/test-jetty-webapp/src/main/webapp/rewrite/info.html +++ b/test-jetty-webapp/src/main/webapp/rewrite/info.html @@ -11,23 +11,23 @@

Internal URI rewrite

-
Rewrite "/some/old/context" to "/rewritten/newcontext"
+
Rewrite "../some/old/context" to "../rewritten/newcontext"
This demo shows how the entire request URI can be internally rewritten to point to another context, using simple text matching
-
Rewrite "/rewrite/for/beginning" to "/rewritten/beginning"
+
Rewrite "../rewrite/for/beginning" to "../rewritten/beginning"
This demo shows how the beginning of the request URI can be rewritten, while keeping the ending section
-
Rewrite "bar/foo" to "foo/bar" using regex
+
Rewrite "bar/foo" to "foo/bar" using regex
This demo shows how sections of the request URI can be rearranged. It uses regex to parse out each section, and then return them in reverse order
-
Rewrite the beginning, and reverse the path sections
+
Rewrite the beginning, and reverse the path sections
This demo shows how rewrite patterns can be chained.
-
Rewrite "bar/foo" to "foo/bar", full dump view
+
Rewrite "bar/foo" to "foo/bar", full dump view
This demo rewrites "bar/foo" to "foo/bar" the same as earlier, but shows a full dump of the request

Redirect

-
Redirect "/redirect/this" to "/redirected/this"
+
Redirect "../redirect/this" to "../redirected/this"
This demo redirects the request in a manner visible to the user agent, instead of doing an internal rewrite.

Cookie

@@ -35,7 +35,7 @@
This demo rule sets a "visited" cookie for each page you visit. The second time you go to any of the links above, you will see an additional line, "Previously visited: yes".

Response Code

-
Return a 400 error status
+
Return a 400 error status
This demo shows how to modify the response code of a page to an error, based on its URL
diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/MaxInactiveMigrationTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/MaxInactiveMigrationTest.java new file mode 100644 index 00000000000..3dcfdb05c17 --- /dev/null +++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/MaxInactiveMigrationTest.java @@ -0,0 +1,141 @@ +// ======================================================================== +// Copyright 2011 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.session; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.io.PrintWriter; +import java.sql.DriverManager; +import java.sql.SQLException; + +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.eclipse.jetty.client.ContentExchange; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.http.HttpMethods; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.util.log.Log; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + + +/** + * MaxInactiveMigrationTest + * + * Test + */ +public class MaxInactiveMigrationTest +{ + private JdbcTestServer testServer1; + private JdbcTestServer testServer2; + private HttpClient client; + private String sessionCookie; + + @Test + public void testFailover() throws Exception { + String response1 = sendRequest( testServer1 ); + String response2 = sendRequest( testServer2 ); + + assertEquals( "Hello World 1", response1 ); + assertEquals( "Hello World 2", response2 ); + } + + @Before + public void setUp() throws Exception { + testServer1 = new JdbcTestServer(0, -1, 2); + testServer2 = new JdbcTestServer(0, -1, 2); + ServletContextHandler context = testServer1.addContext(""); + context.addServlet(TestServlet.class, "/test"); + ServletContextHandler context2 = testServer2.addContext(""); + context2.addServlet(TestServlet.class, "/test"); + testServer1.start(); + testServer2.start(); + client = new HttpClient(); + client.setConnectorType(HttpClient.CONNECTOR_SOCKET); + client.start(); + } + + @After + public void tearDown() throws Exception { + + testServer1.stop(); + testServer2.stop(); + client.stop(); + try + { + DriverManager.getConnection( "jdbc:derby:sessions;shutdown=true" ); + } + catch( SQLException expected ) + { + } + } + + + + private String sendRequest( JdbcTestServer server ) throws Exception { + + int port=server.getPort(); + + //Log.getLog().setDebugEnabled(true); + + ContentExchange exchange1 = new ContentExchange(true); + exchange1.setMethod(HttpMethods.GET); + exchange1.setURL("http://localhost:" + port + "" + "/test"); + if (sessionCookie != null) + exchange1.getRequestFields().add("Cookie", sessionCookie); + client.send(exchange1); + exchange1.waitForDone(); + assertEquals(HttpServletResponse.SC_OK, exchange1.getResponseStatus()); + + sessionCookie = exchange1.getResponseFields().getStringField("Set-Cookie"); + assertTrue( sessionCookie != null ); + // Mangle the cookie, replacing Path with $Path, etc. + sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path="); + + return exchange1.getResponseContent(); + } + + + + public static class TestServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + private static final String ATTR_COUNTER = "counter"; + + protected void doGet( HttpServletRequest request, HttpServletResponse response ) + throws IOException + { + HttpSession session = request.getSession( true ); + Integer counter = ( Integer )session.getAttribute( ATTR_COUNTER ); + if( counter == null ) { + counter = new Integer( 0 ); + } + counter = new Integer( counter.intValue() + 1 ); + session.setAttribute( ATTR_COUNTER, counter ); + PrintWriter writer = response.getWriter(); + writer.write( "Hello World " + counter.intValue() ); + writer.flush(); + } + + public String getServletInfo() { + return "Test Servlet"; + } + } + +}