Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--VERSION.txt39
-rw-r--r--example-jetty-embedded/pom.xml13
-rw-r--r--example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java1
-rw-r--r--example-jetty-embedded/src/test/java/org/eclipse/jetty/embedded/GzipHandlerTest.java126
-rw-r--r--icon.jpgbin0 -> 2290 bytes
-rw-r--r--jetty-client/src/main/java/org/eclipse/jetty/client/HttpExchange.java2
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpExchangeCancelTest.java53
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/AsyncCallbackHttpExchangeTest.java13
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSslHttpExchangeTest.java3
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSslSecurityListenerTest.java7
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/BlockingHttpExchangeCancelTest.java13
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/CachedHeadersIsolationTest.java27
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/ContentExchangeTest.java36
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/ErrorStatusTest.java39
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/ExternalKeyStoreAsyncSslHttpExchangeTest.java2
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/HttpExchangeTest.java69
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/HttpGetRedirectTest.java25
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/NonBlockingHttpExchangeCancelTest.java13
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/SecuredErrorStatusTest.java16
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/SecurityListenerTest.java34
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/SslHttpExchangeTest.java20
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/SslSecuredErrorStatusTest.java19
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/SslSecurityListenerTest.java32
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/WebSocketUpgradeTest.java36
-rw-r--r--jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/GlobalWebappConfigBinding.java2
-rw-r--r--jetty-deploy/src/test/java/org/eclipse/jetty/deploy/bindings/GlobalWebappConfigBindingTest.java13
-rw-r--r--jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderRuntimeUpdatesTest.java6
-rw-r--r--jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java2
-rw-r--r--jetty-deploy/src/test/resources/binding-test-contexts-1.xml4
-rw-r--r--jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml2
-rwxr-xr-xjetty-distribution/src/main/resources/bin/jetty.sh2
-rw-r--r--jetty-http/pom.xml6
-rw-r--r--jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipResponseWrapper.java394
-rw-r--r--jetty-http/src/main/java/org/eclipse/jetty/http/gzip/GzipStream.java300
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java4
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java56
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java8
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java56
-rw-r--r--jetty-jaspi/pom.xml14
-rw-r--r--jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java51
-rw-r--r--jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ObjectMBean.java7
-rw-r--r--jetty-osgi/jetty-osgi-boot/META-INF/MANIFEST.MF34
-rw-r--r--jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-osgi-nested-default.xml5
-rw-r--r--jetty-osgi/jetty-osgi-boot/pom.xml4
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java36
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiAppProvider.java319
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java27
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleTrackerCustomizer.java9
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java1
-rw-r--r--jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/PackageAdminServiceTracker.java119
-rw-r--r--jetty-policy/src/test/java/org/eclipse/jetty/policy/JettyPolicyRuntimeTest.java2
-rw-r--r--jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewritePatternRule.java10
-rw-r--r--jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java23
-rw-r--r--jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/Rule.java10
-rw-r--r--jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java9
-rw-r--r--jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteHandlerTest.java40
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/Response.java29
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/handler/GzipHandler.java306
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java25
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java25
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java27
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/BlockingChannelCloseTest.java29
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/ConnectorCloseTestBase.java232
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/HttpURITest.java1
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java15
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelConnectorCloseTest.java31
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/SocketConnectorCloseTest.java31
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/StressTest.java6
-rw-r--r--jetty-servlets/pom.xml5
-rw-r--r--jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java2
-rw-r--r--jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java473
-rw-r--r--jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java20
-rw-r--r--jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java510
-rw-r--r--jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterTest.java115
-rw-r--r--jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterTest.java115
-rw-r--r--jetty-start/src/main/java/org/eclipse/jetty/start/Main.java10
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java14
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/component/Container.java16
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java2
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/ScannerTest.java2
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/URLEncodedTest.java42
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceTest.java1
-rw-r--r--jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppClassLoader.java7
-rw-r--r--jetty-websocket/src/main/java/org/eclipse/jetty/websocket/AbstractExtension.java79
-rw-r--r--jetty-websocket/src/main/java/org/eclipse/jetty/websocket/DeflateFrameExtension.java23
-rw-r--r--jetty-websocket/src/main/java/org/eclipse/jetty/websocket/Extension.java5
-rw-r--r--jetty-websocket/src/main/java/org/eclipse/jetty/websocket/FragmentExtension.java2
-rw-r--r--jetty-websocket/src/main/java/org/eclipse/jetty/websocket/IdentityExtension.java2
-rw-r--r--jetty-websocket/src/main/java/org/eclipse/jetty/websocket/TestClient.java28
-rw-r--r--jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD7_9.java (renamed from jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD07.java)85
-rw-r--r--jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketFactory.java16
-rw-r--r--jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketGeneratorD7_9.java (renamed from jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketGeneratorD07.java)10
-rw-r--r--jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketParserD7_9.java (renamed from jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketParserD07.java)14
-rw-r--r--jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketGeneratorD7_9Test.java (renamed from jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketGeneratorD07Test.java)16
-rw-r--r--jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketLoadD7_9Test.java (renamed from jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketLoadD07Test.java)12
-rw-r--r--jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageD7_9Test.java (renamed from jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageD07Test.java)39
-rw-r--r--jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketParserD7_9Test.java (renamed from jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketParserD07Test.java)8
-rw-r--r--pom.xml17
-rw-r--r--test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/HttpTester.java27
-rw-r--r--test-jetty-webapp/src/main/java/com/acme/Dump.java10
-rw-r--r--test-jetty-webapp/src/main/java/com/acme/RewriteServlet.java2
-rw-r--r--test-jetty-webapp/src/main/webapp/rewrite/index.html2
-rw-r--r--test-jetty-webapp/src/main/webapp/rewrite/info.html14
-rw-r--r--tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/MaxInactiveMigrationTest.java141
104 files changed, 3726 insertions, 1130 deletions
diff --git a/VERSION.txt b/VERSION.txt
index 402907dfb2..b8f1973929 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 edcbdf5a15..3affc94f6d 100644
--- a/example-jetty-embedded/pom.xml
+++ b/example-jetty-embedded/pom.xml
@@ -6,7 +6,7 @@
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>example-jetty-embedded</artifactId>
- <name>Example :: Embedded Jetty Examples</name>
+ <name>Example :: Jetty Embedded</name>
<description>Jetty Embedded Examples</description>
<build>
<plugins>
@@ -48,5 +48,16 @@
<artifactId>jetty-websocket</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>test-jetty-servlet</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
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 95c7b60b45..8e533d8296 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 0000000000..56122ea150
--- /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 0000000000..d2b7ab5241
--- /dev/null
+++ b/icon.jpg
Binary files 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 36b32f5e70..da5b6e55c4 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 93c3c076b3..3123cee07d 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 85a8cb14be..b4be686a42 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<Exception> failure;
+ /* ------------------------------------------------------------ */
private TestHttpExchange(ExecutorService executor, AtomicReference<Exception> failure)
{
this.executor = executor;
this.failure = failure;
}
+ /* ------------------------------------------------------------ */
@Override
protected void onRequestCommitted() throws IOException
{
Future<Integer> future = executor.submit(new Callable<Integer>()
{
+ /* ------------------------------------------------------------ */
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 48030d4cbd..f4103bd4e4 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 2a7b1176da..2c0032c00a 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 ad66e2cce4..af5095135c 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 17ccef5890..8a59980838 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 b1321af6e6..e004d71bb0 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 25b2e4655b..46097f2336 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 9ef4e4e3c3..0f47db5f3f 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 a6247dfa4e..2c571d29f4 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> throwable=new AtomicReference<Throwable>();
@@ -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 9ed69c079a..4341c86aa8 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 74266bba19..7fdde5b2a2 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 e06f457e2c..7af4be8928 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 0c1b6b8798..133cf476c9 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 6bb182ce22..eec253367b 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 426b44bcd9..4b4c4dcf19 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 49b714fc50..bab72e9a96 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 4173d7d3c1..f29bc05d57 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<Object> _results = new ArrayBlockingQueue<Object>(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,6 +217,7 @@ public class WebSocketUpgradeTest extends TestCase
_port=_connector.getLocalPort();
}
+ /* ------------------------------------------------------------ */
private void stopServer() throws Exception
{
_server.stop();
@@ -210,11 +225,11 @@ public class WebSocketUpgradeTest extends TestCase
}
/* ------------------------------------------------------------ */
- /* ------------------------------------------------------------ */
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 d48592a947..9e9a9cf41f 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 953c4875f2..4d93154dfa 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<WebAppContext> contexts = jetty.getWebAppContexts();
+ Assert.assertThat("List of Contexts", contexts, hasSize(greaterThan(0)));
+
+ WebAppContext context = contexts.get(0);
Assert.assertNotNull("Context should not be null",context);
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 7741259f07..b54addf5e5 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 62ab9e64da..db047df32e 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 059fa0bb9c..65e13ab5cf 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 @@
<Call name="addLifeCycleBinding">
<Arg>
<New class="org.eclipse.jetty.deploy.bindings.GlobalWebappConfigBinding">
- <Set name="jettyXml">file://<SystemProperty name="jetty.home" />/context-binding-test-1.xml</Set>
+ <Set name="jettyXml"><SystemProperty name="jetty.home" />/context-binding-test-1.xml</Set>
</New>
</Arg>
</Call>
@@ -52,7 +52,7 @@
<Set name="configurationManager">
<New class="org.eclipse.jetty.deploy.FileConfigurationManager">
<Set name="file">
- <Property name="test.targetdir" default="target" />/xml-configured-jetty.properties
+ <SystemProperty name="jetty.home"/>/xml-configured-jetty.properties
</Set>
</New>
</Set>
diff --git a/jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml b/jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml
index f383239947..c542672b85 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 @@
<Set name="configurationManager">
<New class="org.eclipse.jetty.deploy.FileConfigurationManager">
<Set name="file">
- <Property name="test.targetdir" default="target" />/xml-configured-jetty.properties
+ <SystemProperty name="jetty.home"/>/xml-configured-jetty.properties
</Set>
</New>
</Set>
diff --git a/jetty-distribution/src/main/resources/bin/jetty.sh b/jetty-distribution/src/main/resources/bin/jetty.sh
index a916ad12af..7f6b549463 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 ba6abb7f21..52a2628028 100644
--- a/jetty-http/pom.xml
+++ b/jetty-http/pom.xml
@@ -18,6 +18,12 @@
<version>${project.version}</version>
</dependency>
<dependency>
+ <groupId>${servlet.spec.groupId}</groupId>
+ <artifactId>${servlet.spec.artifactId}</artifactId>
+ <version>${servlet.spec.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
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 0000000000..e53f20ee23
--- /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<String> _mimeTypes;
+ private int _bufferSize=8192;
+ private int _minGzipSize=256;
+
+ private PrintWriter _writer;
+ private GzipStream _gzStream;
+ private long _contentLength=-1;
+ private boolean _noGzip;
+
+ /**
+ * Instantiates a new gzip response wrapper.
+ *
+ * @param request the request
+ * @param response the response
+ */
+ public GzipResponseWrapper(HttpServletRequest request, HttpServletResponse response)
+ {
+ super(response);
+ _request=request;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Sets the mime types.
+ *
+ * @param mimeTypes the new mime types
+ */
+ public void setMimeTypes(Set<String> mimeTypes)
+ {
+ _mimeTypes = mimeTypes;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see javax.servlet.ServletResponseWrapper#setBufferSize(int)
+ */
+ public void setBufferSize(int bufferSize)
+ {
+ _bufferSize = bufferSize;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Sets the min gzip size.
+ *
+ * @param minGzipSize the new min gzip size
+ */
+ public void setMinGzipSize(int minGzipSize)
+ {
+ _minGzipSize = minGzipSize;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see javax.servlet.ServletResponseWrapper#setContentType(java.lang.String)
+ */
+ public void setContentType(String ct)
+ {
+ super.setContentType(ct);
+
+ if (ct!=null)
+ {
+ int colon=ct.indexOf(";");
+ if (colon>0)
+ ct=ct.substring(0,colon);
+ }
+
+ if ((_gzStream==null || _gzStream._out==null) &&
+ (_mimeTypes==null && "application/gzip".equalsIgnoreCase(ct) ||
+ _mimeTypes!=null && (ct==null||!_mimeTypes.contains(StringUtil.asciiToLowerCase(ct)))))
+ {
+ noGzip();
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see javax.servlet.http.HttpServletResponseWrapper#setStatus(int, java.lang.String)
+ */
+ public void setStatus(int sc, String sm)
+ {
+ super.setStatus(sc,sm);
+ if (sc<200||sc>=300)
+ noGzip();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see javax.servlet.http.HttpServletResponseWrapper#setStatus(int)
+ */
+ public void setStatus(int sc)
+ {
+ super.setStatus(sc);
+ if (sc<200||sc>=300)
+ noGzip();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see javax.servlet.ServletResponseWrapper#setContentLength(int)
+ */
+ public void setContentLength(int length)
+ {
+ _contentLength=length;
+ if (_gzStream!=null)
+ _gzStream.setContentLength(length);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see javax.servlet.http.HttpServletResponseWrapper#addHeader(java.lang.String, java.lang.String)
+ */
+ public void addHeader(String name, String value)
+ {
+ if ("content-length".equalsIgnoreCase(name))
+ {
+ _contentLength=Long.parseLong(value);
+ if (_gzStream!=null)
+ _gzStream.setContentLength(_contentLength);
+ }
+ else if ("content-type".equalsIgnoreCase(name))
+ {
+ setContentType(value);
+ }
+ else if ("content-encoding".equalsIgnoreCase(name))
+ {
+ super.addHeader(name,value);
+ if (!isCommitted())
+ {
+ noGzip();
+ }
+ }
+ else
+ super.addHeader(name,value);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see javax.servlet.http.HttpServletResponseWrapper#setHeader(java.lang.String, java.lang.String)
+ */
+ public void setHeader(String name, String value)
+ {
+ if ("content-length".equalsIgnoreCase(name))
+ {
+ _contentLength=Long.parseLong(value);
+ if (_gzStream!=null)
+ _gzStream.setContentLength(_contentLength);
+ }
+ else if ("content-type".equalsIgnoreCase(name))
+ {
+ setContentType(value);
+ }
+ else if ("content-encoding".equalsIgnoreCase(name))
+ {
+ super.setHeader(name,value);
+ if (!isCommitted())
+ {
+ noGzip();
+ }
+ }
+ else
+ super.setHeader(name,value);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see javax.servlet.http.HttpServletResponseWrapper#setIntHeader(java.lang.String, int)
+ */
+ public void setIntHeader(String name, int value)
+ {
+ if ("content-length".equalsIgnoreCase(name))
+ {
+ _contentLength=value;
+ if (_gzStream!=null)
+ _gzStream.setContentLength(_contentLength);
+ }
+ else
+ super.setIntHeader(name,value);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see javax.servlet.ServletResponseWrapper#flushBuffer()
+ */
+ public void flushBuffer() throws IOException
+ {
+ if (_writer!=null)
+ _writer.flush();
+ if (_gzStream!=null)
+ _gzStream.finish();
+ else
+ getResponse().flushBuffer();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see javax.servlet.ServletResponseWrapper#reset()
+ */
+ public void reset()
+ {
+ super.reset();
+ if (_gzStream!=null)
+ _gzStream.resetBuffer();
+ _writer=null;
+ _gzStream=null;
+ _noGzip=false;
+ _contentLength=-1;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see javax.servlet.ServletResponseWrapper#resetBuffer()
+ */
+ public void resetBuffer()
+ {
+ super.resetBuffer();
+ if (_gzStream!=null)
+ _gzStream.resetBuffer();
+ _writer=null;
+ _gzStream=null;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see javax.servlet.http.HttpServletResponseWrapper#sendError(int, java.lang.String)
+ */
+ public void sendError(int sc, String msg) throws IOException
+ {
+ resetBuffer();
+ super.sendError(sc,msg);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see javax.servlet.http.HttpServletResponseWrapper#sendError(int)
+ */
+ public void sendError(int sc) throws IOException
+ {
+ resetBuffer();
+ super.sendError(sc);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see javax.servlet.http.HttpServletResponseWrapper#sendRedirect(java.lang.String)
+ */
+ public void sendRedirect(String location) throws IOException
+ {
+ resetBuffer();
+ super.sendRedirect(location);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see javax.servlet.ServletResponseWrapper#getOutputStream()
+ */
+ public ServletOutputStream getOutputStream() throws IOException
+ {
+ if (_gzStream==null)
+ {
+ if (getResponse().isCommitted() || _noGzip)
+ return getResponse().getOutputStream();
+
+ _gzStream=newGzipStream(_request,(HttpServletResponse)getResponse(),_contentLength,_bufferSize,_minGzipSize);
+ }
+ else if (_writer!=null)
+ throw new IllegalStateException("getWriter() called");
+
+ return _gzStream;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see javax.servlet.ServletResponseWrapper#getWriter()
+ */
+ public PrintWriter getWriter() throws IOException
+ {
+ if (_writer==null)
+ {
+ if (_gzStream!=null)
+ throw new IllegalStateException("getOutputStream() called");
+
+ if (getResponse().isCommitted() || _noGzip)
+ return getResponse().getWriter();
+
+ _gzStream=newGzipStream(_request,(HttpServletResponse)getResponse(),_contentLength,_bufferSize,_minGzipSize);
+ _writer=newWriter(_gzStream,getCharacterEncoding());
+ }
+ return _writer;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * No gzip.
+ */
+ public void noGzip()
+ {
+ _noGzip=true;
+ if (_gzStream!=null)
+ {
+ try
+ {
+ _gzStream.doNotGzip();
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException(e);
+ }
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Finish.
+ *
+ * @throws IOException Signals that an I/O exception has occurred.
+ */
+ public void finish() throws IOException
+ {
+ if (_writer!=null && !_gzStream._closed)
+ _writer.flush();
+ if (_gzStream!=null)
+ _gzStream.finish();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Allows derived implementations to replace GzipStream implementation.
+ *
+ * @param request the request
+ * @param response the response
+ * @param contentLength the content length
+ * @param bufferSize the buffer size
+ * @param minGzipSize the min gzip size
+ * @return the gzip stream
+ * @throws IOException Signals that an I/O exception has occurred.
+ */
+ protected GzipStream newGzipStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minGzipSize) throws IOException
+ {
+ return new GzipStream(request,response,contentLength,bufferSize,minGzipSize);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Allows derived implementations to replace PrintWriter implementation.
+ *
+ * @param out the out
+ * @param encoding the encoding
+ * @return the prints the writer
+ * @throws UnsupportedEncodingException the unsupported encoding exception
+ */
+ protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
+ {
+ return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
+ }
+}
+
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 0000000000..cf44c479b4
--- /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<Integer.MAX_VALUE)
+ _response.setContentLength((int)_contentLength);
+ else
+ _response.setHeader("Content-Length",Long.toString(_contentLength));
+ }
+
+ if (_bOut!=null)
+ _out.write(_bOut.getBuf(),0,_bOut.getCount());
+ _bOut=null;
+ }
+ }
+
+ /**
+ * Check out.
+ *
+ * @param length the length
+ * @throws IOException Signals that an I/O exception has occurred.
+ */
+ private void checkOut(int length) throws IOException
+ {
+ if (_closed)
+ throw new IOException("CLOSED");
+
+ if (_out==null)
+ {
+ if (_response.isCommitted() || (_contentLength>=0 && _contentLength<_minGzipSize))
+ doNotGzip();
+ else if (length>_minGzipSize)
+ doGzip();
+ else
+ _out=_bOut=new ByteArrayOutputStream2(_bufferSize);
+ }
+ else if (_bOut!=null)
+ {
+ if (_response.isCommitted() || (_contentLength>=0 && _contentLength<_minGzipSize))
+ doNotGzip();
+ else if (length>=(_bOut.getBuf().length -_bOut.getCount()))
+ doGzip();
+ }
+ }
+
+ /**
+ * Allows derived implementations to replace PrintWriter implementation.
+ */
+ protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
+ {
+ return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
+ }
+}
+
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 9e57ff263f..21919c5fe1 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 decf75d076..1f642abeda 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 6fb4b47bf1..252163d341 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 23390b8445..04ae39cff0 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 ee5d6b7c05..3762acea91 100644
--- a/jetty-jaspi/pom.xml
+++ b/jetty-jaspi/pom.xml
@@ -46,6 +46,20 @@
</plugin>
</plugins>
</build>
+ <repositories>
+ <repository>
+ <id>repository.apache.org</id>
+ <name>Apache Snapshot Repository</name>
+ <layout>default</layout>
+ <url>http://repository.apache.org/content/groups/snapshots/</url>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ </repository>
+ </repositories>
<dependencies>
<dependency>
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 1792350b03..5371c8b60d 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<Object, ObjectName> _beans = new WeakHashMap<Object, ObjectName>();
private final HashMap<String, Integer> _unique = new HashMap<String, Integer>();
- private final MultiMap<ObjectName> _relations = new MultiMap<ObjectName>();
+ private final WeakHashMap<ObjectName,List<Container.Relationship>> _relations = new WeakHashMap<ObjectName,List<Container.Relationship>>();
private String _domain = null;
/**
@@ -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<Container.Relationship> rels = _relations.get(parent);
+ if (rels==null)
+ {
+ rels=new ArrayList<Container.Relationship>();
+ _relations.put(parent,rels);
+ }
+ rels.add(relationship);
+ }
}
/**
@@ -155,11 +168,23 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
*/
public synchronized void remove(Relationship relationship)
{
+ __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<Container.Relationship> rels = _relations.get(parent);
+ if (rels!=null)
+ {
+ for (Iterator<Container.Relationship> i=rels.iterator();i.hasNext();)
+ {
+ Container.Relationship r = i.next();
+ if (relationship.equals(r) || r.getChild()==null)
+ i.remove();
+ }
+ }
+ }
}
/**
@@ -169,14 +194,15 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
*/
public synchronized void removeBean(Object obj)
{
+ __log.debug("removeBean {}",obj);
ObjectName bean = _beans.remove(obj);
if (bean != null)
{
- List<?> beanRelations = _relations.getValues(bean);
- if (beanRelations != null && beanRelations.size() > 0)
+ List<Container.Relationship> beanRelations= _relations.remove(bean);
+ if (beanRelations != null)
{
- Log.debug("Unregister {}", beanRelations);
+ __log.debug("Unregister {}", beanRelations);
List<?> removeList = new ArrayList<Object>(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 31a8986c86..6a1ca44672 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 fda1e53a20..dd7d7e3523 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 a732f69a48..67d84e9df8 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 @@
<Arg>
<New id="NestedConnector" class="org.eclipse.jetty.nested.NestedConnector">
<Set name="statsOn">false</Set>
- <Set name="confidentialPort">8443</Set>
+ <Set name="forwarded">true</Set>
+ <Set name="forwardedHostHeader">x-forwarded_for</Set>
+ <Set name="forwardedCipherSuiteHeader">sslclientcipher</Set>
+ <Set name="forwardedSslSessionIdHeader">sslsessionid</Set>
<Call name="addLifeCycleListener">
<Arg>
<New class="org.eclipse.jetty.osgi.nested.NestedConnectorListener" id="NestedConnectorListener">
diff --git a/jetty-osgi/jetty-osgi-boot/pom.xml b/jetty-osgi/jetty-osgi-boot/pom.xml
index ce61229939..3e975658e8 100644
--- a/jetty-osgi/jetty-osgi-boot/pom.xml
+++ b/jetty-osgi/jetty-osgi-boot/pom.xml
@@ -53,7 +53,7 @@
<phase>process-resources</phase>
<configuration>
<tasks>
- <delete file="target/classes/META-INF/MANIFEST.MF" />
+ <!--delete file="target/classes/META-INF/MANIFEST.MF" /-->
<copy todir="target/classes/jettyhome">
<fileset dir="jettyhome">
<exclude name="**/*.log" />
@@ -105,7 +105,7 @@
</executions>
<configuration>
<instructions>
- <Bundle-SymbolicName>org.eclipse.jetty.osgi.boot;singleton:=true</Bundle-SymbolicName>
+ <Bundle-SymbolicName>org.eclipse.jetty.osgi.boot</Bundle-SymbolicName>
<Export-Package>org.eclipse.jetty.osgi.boot;version="${parsedVersion.osgiVersion}",org.eclipse.jetty.osgi.boot.utils,org.eclipse.jetty.osgi.nested;version="${parsedVersion.osgiVersion}"</Export-Package>
<Bundle-Activator>org.eclipse.jetty.osgi.boot.JettyBootstrapActivator</Bundle-Activator>
<!-- disable the uses directive: jetty will accomodate pretty much any versions
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java
index 74c910c525..e3c0f9040d 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java
@@ -70,6 +70,7 @@ public class JettyBootstrapActivator implements BundleActivator
private JettyContextHandlerServiceTracker _jettyContextHandlerTracker;
private PackageAdminServiceTracker _packageAdminServiceTracker;
private BundleTracker _webBundleTracker;
+ private BundleContext _bundleContext;
// private ServiceRegistration _jettyServerFactoryService;
private JettyServerServiceTracker _jettyServerServiceTracker;
@@ -86,6 +87,7 @@ public class JettyBootstrapActivator implements BundleActivator
public void start(BundleContext context) throws Exception
{
INSTANCE = this;
+ _bundleContext = context;
// track other bundles and fragments attached to this bundle that we
// should activate.
@@ -298,18 +300,28 @@ public class JettyBootstrapActivator implements BundleActivator
*/
private static void checkBundleActivated()
{
- if (INSTANCE == null) {
- Bundle thisBundle = FrameworkUtil.getBundle(JettyBootstrapActivator.class);
- try
- {
- thisBundle.start();
- }
- catch (BundleException e)
- {
- //nevermind.
- }
- }
+ if (INSTANCE == null)
+ {
+ Bundle thisBundle = FrameworkUtil.getBundle(JettyBootstrapActivator.class);
+ try
+ {
+ thisBundle.start();
+ }
+ catch (BundleException e)
+ {
+ // nevermind.
+ }
+ }
+ }
+
+ /**
+ * @return The bundle context for this bundle.
+ */
+ public static BundleContext getBundleContext()
+ {
+ checkBundleActivated();
+ return INSTANCE._bundleContext;
}
-} \ No newline at end of file
+}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiAppProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiAppProvider.java
index 4fa93cebad..7ace17162e 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiAppProvider.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiAppProvider.java
@@ -17,17 +17,26 @@ package org.eclipse.jetty.osgi.boot;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
+import java.util.HashSet;
+import java.util.Iterator;
import java.util.Map.Entry;
+import java.util.Set;
import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.AppProvider;
import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.deploy.providers.ContextProvider;
import org.eclipse.jetty.deploy.providers.ScanningAppProvider;
+import org.eclipse.jetty.osgi.boot.utils.internal.PackageAdminServiceTracker;
import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.util.Scanner;
+import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.WebAppContext;
import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
/**
* AppProvider for OSGi. Supports the configuration of ContextHandlers and
@@ -42,6 +51,12 @@ import org.osgi.framework.Bundle;
* it supports the deployment of WebAppContexts. Except for the scanning of the
* webapps directory.
* </p>
+ * <p>
+ * When the parameter autoInstallOSGiBundles is set to true, OSGi bundles that
+ * are located in the monitored directory are installed and started after the
+ * framework as finished auto-starting all the other bundles.
+ * Warning: only use this for development.
+ * </p>
*/
public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
{
@@ -51,7 +66,12 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
private String _defaultsDescriptor;
private String _tldBundles;
private String[] _configurationClasses;
+ private boolean _autoInstallOSGiBundles = true;
+ //Keep track of the bundles that were installed and that are waiting for the
+ //framework to complete its initialization.
+ Set<Bundle> _pendingBundlesToStart = null;
+
/**
* When a context file corresponds to a deployed bundle and is changed we
* reload the corresponding bundle.
@@ -59,10 +79,15 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
private static class Filter implements FilenameFilter
{
OSGiAppProvider _enclosedInstance;
-
+
public boolean accept(File dir, String name)
{
- if (!new File(dir,name).isDirectory())
+ File file = new File(dir,name);
+ if (fileMightBeAnOSGiBundle(file))
+ {
+ return true;
+ }
+ if (!file.isDirectory())
{
String contextName = getDeployedAppName(name);
if (contextName != null)
@@ -352,6 +377,24 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
_extractWars=extract;
}
+ /**
+ * @return true when this app provider locates osgi bundles and features in
+ * its monitored directory and installs them. By default true if there is a folder to monitor.
+ */
+ public boolean isAutoInstallOSGiBundles()
+ {
+ return _autoInstallOSGiBundles;
+ }
+
+ /**
+ * &lt;autoInstallOSGiBundles&gt;true&lt;/autoInstallOSGiBundles&gt;
+ * @param installingOSGiBundles
+ */
+ public void setAutoInstallOSGiBundles(boolean installingOSGiBundles)
+ {
+ _autoInstallOSGiBundles=installingOSGiBundles;
+ }
+
/* ------------------------------------------------------------ */
/**
@@ -361,6 +404,10 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
* directory, then the ContextXmlDir is examined to see if a foo.xml file
* exists. If it does, then this deployer will not deploy the webapp and the
* ContextProvider should be used to act on the foo.xml file.
+ * </p>
+ * <p>
+ * Also if this directory contains some osgi bundles, it will install them.
+ * </p>
*
* @see ContextProvider
* @param contextsDir
@@ -405,5 +452,273 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
return _configurationClasses;
}
+ /**
+ * Overridden to install the OSGi bundles found in the monitored folder.
+ */
+ protected void doStart() throws Exception
+ {
+ if (isAutoInstallOSGiBundles())
+ {
+ if (getMonitoredDirResource() == null)
+ {
+ setAutoInstallOSGiBundles(false);
+ Log.info("Disable autoInstallOSGiBundles as there is not contexts folder to monitor.");
+ }
+ else
+ {
+ File scandir = null;
+ try
+ {
+ scandir = getMonitoredDirResource().getFile();
+ if (!scandir.exists() || !scandir.isDirectory())
+ {
+ setAutoInstallOSGiBundles(false);
+ Log.warn("Disable autoInstallOSGiBundles as the contexts folder '" + scandir.getAbsolutePath() + " does not exist.");
+ scandir = null;
+ }
+ }
+ catch (IOException ioe)
+ {
+ setAutoInstallOSGiBundles(false);
+ Log.warn("Disable autoInstallOSGiBundles as the contexts folder '" + getMonitoredDirResource().getURI() + " does not exist.");
+ scandir = null;
+ }
+ if (scandir != null)
+ {
+ for (File file : scandir.listFiles())
+ {
+ if (fileMightBeAnOSGiBundle(file))
+ {
+ installBundle(file, false);
+ }
+ }
+ }
+ }
+ }
+ super.doStart();
+ if (isAutoInstallOSGiBundles())
+ {
+ Scanner.ScanCycleListener scanCycleListner = new AutoStartWhenFrameworkHasCompleted(this);
+ super.addScannerListener(scanCycleListner);
+ }
+ }
+
+ /**
+ * When the file is a jar or a folder, we look if it looks like an OSGi bundle.
+ * In that case we install it and start it.
+ * <p>
+ * Really a simple trick to get going quickly with development.
+ * </p>
+ */
+ @Override
+ protected void fileAdded(String filename) throws Exception
+ {
+ File file = new File(filename);
+ if (isAutoInstallOSGiBundles() && file.exists() && fileMightBeAnOSGiBundle(file))
+ {
+ installBundle(file, true);
+ }
+ else
+ {
+ super.fileAdded(filename);
+ }
+ }
+
+ /**
+ * @param file
+ * @return
+ */
+ private static boolean fileMightBeAnOSGiBundle(File file)
+ {
+ if (file.isDirectory())
+ {
+ if (new File(file,"META-INF/MANIFEST.MF").exists())
+ {
+ return true;
+ }
+ }
+ else if (file.getName().endsWith(".jar"))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected void fileChanged(String filename) throws Exception
+ {
+ File file = new File(filename);
+ if (isAutoInstallOSGiBundles() && fileMightBeAnOSGiBundle(file))
+ {
+ updateBundle(file);
+ }
+ else
+ {
+ super.fileChanged(filename);
+ }
+ }
+
+ @Override
+ protected void fileRemoved(String filename) throws Exception
+ {
+ File file = new File(filename);
+ if (isAutoInstallOSGiBundles() && fileMightBeAnOSGiBundle(file))
+ {
+ uninstallBundle(file);
+ }
+ else
+ {
+ super.fileRemoved(filename);
+ }
+ }
+
+ /**
+ * Returns a bundle according to its location.
+ * In the version 1.6 of org.osgi.framework, BundleContext.getBundle(String) is what we want.
+ * However to support older versions of OSGi. We use our own local refrence mechanism.
+ * @param location
+ * @return
+ */
+ protected Bundle getBundle(BundleContext bc, String location)
+ {
+ //not available in older versions of OSGi:
+ //return bc.getBundle(location);
+ for (Bundle b : bc.getBundles())
+ {
+ if (b.getLocation().equals(location))
+ {
+ return b;
+ }
+ }
+ return null;
+ }
+
+ protected synchronized Bundle installBundle(File file, boolean start)
+ {
+
+ try
+ {
+ BundleContext bc = JettyBootstrapActivator.getBundleContext();
+ String location = file.toURI().toString();
+ Bundle b = getBundle(bc, location);
+ if (b == null)
+ {
+ b = bc.installBundle(location);
+ }
+ if (b == null)
+ {
+ //not sure we will ever be here,
+ //most likely a BundleException was thrown
+ Log.warn("The file " + location + " is not an OSGi bundle.");
+ return null;
+ }
+ if (start && b.getHeaders().get(Constants.FRAGMENT_HOST) == null)
+ {//not a fragment, try to start it. if the framework has finished auto-starting.
+ if (!PackageAdminServiceTracker.INSTANCE.frameworkHasCompletedAutostarts())
+ {
+ if (_pendingBundlesToStart == null)
+ {
+ _pendingBundlesToStart = new HashSet<Bundle>();
+ }
+ _pendingBundlesToStart.add(b);
+ return null;
+ }
+ else
+ {
+ b.start();
+ }
+ }
+ return b;
+ }
+ catch (BundleException e)
+ {
+ Log.warn("Unable to " + (start? "start":"install") + " the bundle " + file.getAbsolutePath(), e);
+ }
+ return null;
+ }
+
+ protected void uninstallBundle(File file)
+ {
+ try
+ {
+ Bundle b = getBundle(JettyBootstrapActivator.getBundleContext(), file.toURI().toString());
+ b.stop();
+ b.uninstall();
+ }
+ catch (BundleException e)
+ {
+ Log.warn("Unable to uninstall the bundle " + file.getAbsolutePath(), e);
+ }
+ }
+
+ protected void updateBundle(File file)
+ {
+ try
+ {
+ Bundle b = getBundle(JettyBootstrapActivator.getBundleContext(), file.toURI().toString());
+ if (b == null)
+ {
+ installBundle(file, true);
+ }
+ else if (b.getState() == Bundle.ACTIVE)
+ {
+ b.update();
+ }
+ else
+ {
+ b.start();
+ }
+ }
+ catch (BundleException e)
+ {
+ Log.warn("Unable to update the bundle " + file.getAbsolutePath(), e);
+ }
+ }
+
}
+/**
+ * At the end of each scan, if there are some bundles to be started,
+ * look if the framework has completed its autostart. In that case start those bundles.
+ */
+class AutoStartWhenFrameworkHasCompleted implements Scanner.ScanCycleListener
+{
+ private final OSGiAppProvider _appProvider;
+
+ AutoStartWhenFrameworkHasCompleted(OSGiAppProvider appProvider)
+ {
+ _appProvider = appProvider;
+ }
+
+ public void scanStarted(int cycle) throws Exception
+ {
+ }
+
+ public void scanEnded(int cycle) throws Exception
+ {
+ if (_appProvider._pendingBundlesToStart != null && PackageAdminServiceTracker.INSTANCE.frameworkHasCompletedAutostarts())
+ {
+ Iterator<Bundle> it = _appProvider._pendingBundlesToStart.iterator();
+ while (it.hasNext())
+ {
+ Bundle b = it.next();
+ if (b.getHeaders().get(Constants.FRAGMENT_HOST) != null)
+ {
+ continue;
+ }
+ try
+ {
+ b.start();
+ }
+ catch (BundleException e)
+ {
+ Log.warn("Unable to start the bundle " + b.getLocation(), e);
+ }
+
+ }
+ _appProvider._pendingBundlesToStart = null;
+ }
+ }
+
+}
+
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java
index 3911a9309e..4b7876b52e 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java
@@ -5,7 +5,6 @@
// 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.
@@ -534,7 +533,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
+ " the fragment '" + frag.getSymbolicName() + "'");
}
fragUrl = DefaultFileLocatorHelper.getLocalURL(fragUrl);
- String key = patchFragFolder.startsWith("/") ? patchFragFolder.substring(1) : patchFragFolder;
+ String key = fragFolder.startsWith("/") ? fragFolder.substring(1) : fragFolder;
appendedResourcesPath.put(key + ";" + frag.getSymbolicName(), Resource.newResource(fragUrl));
}
if (patchFragFolder != null)
@@ -595,13 +594,23 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
}
if (resEnum != null && resEnum.hasMoreElements())
{
- if (resfrags == null)
- {
- resfrags = new ArrayList<Resource>();
- wah.setAttribute(WebInfConfiguration.RESOURCE_URLS, resfrags);
- }
- resfrags.add(Resource.newResource(
- DefaultFileLocatorHelper.getLocalURL(frag.getEntry("/META-INF/resources"))));
+ URL resourcesEntry = frag.getEntry("/META-INF/resources/");
+ if (resourcesEntry == null)
+ {
+ //probably we found some fragments to a bundle.
+ //those are already contributed.
+ //so we skip this.
+ }
+ else
+ {
+ if (resfrags == null)
+ {
+ resfrags = new ArrayList<Resource>();
+ wah.setAttribute(WebInfConfiguration.RESOURCE_URLS, resfrags);
+ }
+ resfrags.add(Resource.newResource(
+ DefaultFileLocatorHelper.getLocalURL(resourcesEntry)));
+ }
}
if (tldEnum != null && tldEnum.hasMoreElements())
{
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleTrackerCustomizer.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleTrackerCustomizer.java
index f83e40d19b..bf91995e5f 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleTrackerCustomizer.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleTrackerCustomizer.java
@@ -17,6 +17,7 @@ import java.util.Dictionary;
import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator;
import org.eclipse.jetty.osgi.boot.OSGiWebappConstants;
+import org.eclipse.jetty.util.log.Log;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleEvent;
import org.osgi.util.tracker.BundleTracker;
@@ -151,7 +152,10 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer {
String contextPath = (String)dic.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH);
if (contextPath == null || !contextPath.startsWith("/"))
{
- throw new IllegalArgumentException();
+ Log.warn("The manifest header '" + OSGiWebappConstants.JETTY_WAR_FOLDER_PATH +
+ ": " + warFolderRelativePath + "' in the bundle " + bundle.getSymbolicName() +
+ " is not valid: there is no Web-ContextPath defined in the manifest.");
+ return false;
}
// create the corresponding service and publish it in the context of
// the contributor bundle.
@@ -162,8 +166,7 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer {
}
catch (Throwable e)
{
- // TODO Auto-generated catch block
- e.printStackTrace();
+ Log.warn("Starting the web-bundle " + bundle.getSymbolicName() + " threw an exception.", e);
return true;//maybe it did not work maybe it did. safer to track this bundle.
}
}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java
index 88d15559b0..33344060fa 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java
@@ -285,6 +285,7 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
return (URL)BUNDLE_URL_CONNECTION_getLocalURL.invoke(conn, null);
}
} catch (Throwable t) {
+ System.err.println("Unable to locate the OSGi url: '" + url + "'.");
t.printStackTrace();
}
}
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/PackageAdminServiceTracker.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/PackageAdminServiceTracker.java
index 386ae779a1..9a8b6de5d8 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/PackageAdminServiceTracker.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/PackageAdminServiceTracker.java
@@ -13,9 +13,9 @@
package org.eclipse.jetty.osgi.boot.utils.internal;
import java.util.ArrayList;
-import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
-import java.util.Set;
+import java.util.Map;
import java.util.StringTokenizer;
import org.osgi.framework.Bundle;
@@ -26,11 +26,11 @@ import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.service.startlevel.StartLevel;
/**
* When the PackageAdmin service is activated we can look for the fragments
* attached to this bundle and "activate" them.
- *
*/
public class PackageAdminServiceTracker implements ServiceListener
{
@@ -38,6 +38,9 @@ public class PackageAdminServiceTracker implements ServiceListener
private List<BundleActivator> _activatedFragments = new ArrayList<BundleActivator>();
private boolean _fragmentsWereActivated = false;
+ //Use the deprecated StartLevel to stay compatible with older versions of OSGi.
+ private StartLevel _startLevel;
+ private int _maxStartLevel = 6;
public static PackageAdminServiceTracker INSTANCE = null;
public PackageAdminServiceTracker(BundleContext context)
@@ -66,6 +69,21 @@ public class PackageAdminServiceTracker implements ServiceListener
_fragmentsWereActivated = sr != null;
if (sr != null)
invokeFragmentActivators(sr);
+
+ sr = _context.getServiceReference(StartLevel.class.getName());
+ if (sr != null)
+ {
+ _startLevel = (StartLevel)_context.getService(sr);
+ try
+ {
+ _maxStartLevel = Integer.parseInt(System.getProperty("osgi.startLevel","6"));
+ }
+ catch (Exception e)
+ {
+ //nevermind default on the usual.
+ _maxStartLevel = 6;
+ }
+ }
return _fragmentsWereActivated;
}
@@ -105,8 +123,9 @@ public class PackageAdminServiceTracker implements ServiceListener
}
/**
- * Returns the fragments and the required-bundles that have a jetty-web annotation attribute
- * compatible with the webFragOrAnnotationOrResources.
+ * Returns the fragments and the required-bundles of a bundle.
+ * Recursively collect the required-bundles and fragment when the directive visibility:=reexport
+ * is added to a required-bundle.
* @param bundle
* @param webFragOrAnnotationOrResources
* @return
@@ -119,60 +138,50 @@ public class PackageAdminServiceTracker implements ServiceListener
return null;
}
PackageAdmin admin = (PackageAdmin)_context.getService(sr);
+ LinkedHashMap<String,Bundle> deps = new LinkedHashMap<String,Bundle>();
+ collectFragmentsAndRequiredBundles(bundle, admin, deps, false);
+ return deps.values().toArray(new Bundle[deps.size()]);
+ }
+ /**
+ * Returns the fragments and the required-bundles. Collects them transitively when the directive 'visibility:=reexport'
+ * is added to a required-bundle.
+ * @param bundle
+ * @param webFragOrAnnotationOrResources
+ * @return
+ */
+ protected void collectFragmentsAndRequiredBundles(Bundle bundle, PackageAdmin admin, Map<String,Bundle> deps, boolean onlyReexport)
+ {
Bundle[] fragments = admin.getFragments(bundle);
- //get the required bundles. we can't use the org.osgi.framework.wiring package
- //just yet: it is not supported by enough osgi implementations.
- List<Bundle> requiredBundles = getRequiredBundles(bundle, admin);
if (fragments != null)
{
- Set<String> already = new HashSet<String>();
- for (Bundle b : requiredBundles)
- {
- already.add(b.getSymbolicName());
- }
//Also add the bundles required by the fragments.
//this way we can inject onto an existing web-bundle a set of bundles that extend it
for (Bundle f : fragments)
{
- List<Bundle> requiredBundlesByFragment = getRequiredBundles(f, admin);
- for (Bundle b : requiredBundlesByFragment)
+ if (!deps.keySet().contains(f.getSymbolicName()))
{
- if (already.add(b.getSymbolicName()))
- {
- requiredBundles.add(b);
- }
+ deps.put(f.getSymbolicName(), f);
+ collectRequiredBundles(f, admin, deps, onlyReexport);
}
}
}
- ArrayList<Bundle> bundles = new ArrayList<Bundle>(
- (fragments != null ? fragments.length : 0) +
- (requiredBundles != null ? requiredBundles.size() : 0));
- if (fragments != null)
- {
- for (Bundle f : fragments)
- {
- bundles.add(f);
- }
- }
- if (requiredBundles != null)
- {
- bundles.addAll(requiredBundles);
- }
- return bundles.toArray(new Bundle[bundles.size()]);
+ collectRequiredBundles(bundle, admin, deps, onlyReexport);
}
/**
* A simplistic but good enough parser for the Require-Bundle header.
+ * Parses the version range attribute and the visibility directive.
+ *
+ * @param onlyReexport true to collect resources and web-fragments transitively if and only if the directive visibility is reexport.
* @param bundle
* @return The map of required bundles associated to the value of the jetty-web attribute.
*/
- protected List<Bundle> getRequiredBundles(Bundle bundle, PackageAdmin admin)
+ protected void collectRequiredBundles(Bundle bundle, PackageAdmin admin, Map<String,Bundle> deps, boolean onlyReexport)
{
- List<Bundle> res = new ArrayList<Bundle>();
String requiredBundleHeader = (String)bundle.getHeaders().get("Require-Bundle");
if (requiredBundleHeader == null)
{
- return res;
+ return;
}
StringTokenizer tokenizer = new StringTokenizer(requiredBundleHeader, ",");
while (tokenizer.hasMoreTokens())
@@ -180,7 +189,13 @@ public class PackageAdminServiceTracker implements ServiceListener
String tok = tokenizer.nextToken().trim();
StringTokenizer tokenizer2 = new StringTokenizer(tok, ";");
String symbolicName = tokenizer2.nextToken().trim();
+ if (deps.keySet().contains(symbolicName))
+ {
+ //was already added. 2 dependencies pointing at the same bundle.
+ continue;
+ }
String versionRange = null;
+ boolean reexport = false;
while (tokenizer2.hasMoreTokens())
{
String next = tokenizer2.nextToken().trim();
@@ -195,21 +210,37 @@ public class PackageAdminServiceTracker implements ServiceListener
versionRange = next.substring("bundle-version=".length());
}
}
+ else if (next.equals("visibility:=reexport"))
+ {
+ reexport = true;
+ }
+ }
+ if (!reexport && onlyReexport)
+ {
+ return;
}
Bundle[] reqBundles = admin.getBundles(symbolicName, versionRange);
- if (reqBundles != null)
+ if (reqBundles != null && reqBundles.length != 0)
{
+ Bundle reqBundle = null;
for (Bundle b : reqBundles)
{
if (b.getState() == Bundle.ACTIVE || b.getState() == Bundle.STARTING)
{
- res.add(b);
+ reqBundle = b;
break;
}
}
+ if (reqBundle == null)
+ {
+ //strange? in OSGi with Require-Bundle,
+ //the dependent bundle is supposed to be active already
+ reqBundle = reqBundles[0];
+ }
+ deps.put(reqBundle.getSymbolicName(),reqBundle);
+ collectFragmentsAndRequiredBundles(reqBundle, admin, deps, true);
}
}
- return res;
}
@@ -273,6 +304,14 @@ public class PackageAdminServiceTracker implements ServiceListener
}
}
}
+
+ /**
+ * @return true if the framework has completed all the start levels.
+ */
+ public boolean frameworkHasCompletedAutostarts()
+ {
+ return _startLevel == null ? true : _startLevel.getStartLevel() >= _maxStartLevel;
+ }
}
diff --git a/jetty-policy/src/test/java/org/eclipse/jetty/policy/JettyPolicyRuntimeTest.java b/jetty-policy/src/test/java/org/eclipse/jetty/policy/JettyPolicyRuntimeTest.java
index 2f557e078e..8c1a2e3d05 100644
--- a/jetty-policy/src/test/java/org/eclipse/jetty/policy/JettyPolicyRuntimeTest.java
+++ b/jetty-policy/src/test/java/org/eclipse/jetty/policy/JettyPolicyRuntimeTest.java
@@ -59,6 +59,7 @@ public class JettyPolicyRuntimeTest
@Test
public void testSimplePolicyReplacement() throws Exception
{
+ Assume.assumeTrue(!OS.IS_WINDOWS); // Ignore test if running under windows.
JettyPolicy ap = new JettyPolicy(MavenTestingUtils.getTestResourceDir("runtime-test-1").getAbsolutePath(), evaluator);
ap.refresh();
@@ -73,6 +74,7 @@ public class JettyPolicyRuntimeTest
@Test
public void testRepeatedPolicyReplacement() throws Exception
{
+ Assume.assumeTrue(!OS.IS_WINDOWS); // Ignore test if running under windows.
JettyPolicy ap = new JettyPolicy(MavenTestingUtils.getTestResourceDir("runtime-test-2/a").getAbsolutePath(),evaluator);
ap.refresh();
diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewritePatternRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewritePatternRule.java
index 9e134acac9..fe36b62a97 100644
--- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewritePatternRule.java
+++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewritePatternRule.java
@@ -18,12 +18,13 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.PathMap;
+import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.URIUtil;
/**
* Rewrite the URI by replacing the matched {@link PathMap} path with a fixed string.
*/
-public class RewritePatternRule extends PatternRule
+public class RewritePatternRule extends PatternRule implements Rule.ApplyURI
{
private String _replacement;
@@ -57,6 +58,13 @@ public class RewritePatternRule extends PatternRule
}
/* ------------------------------------------------------------ */
+ public void applyURI(Request request, String oldTarget, String newTarget) throws IOException
+ {
+ String uri = URIUtil.addPaths(_replacement, PathMap.pathInfo(_pattern,request.getRequestURI()));
+ request.setRequestURI(uri);
+ }
+
+ /* ------------------------------------------------------------ */
/**
* Returns the replacement string.
*/
diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java
index 20e31d2aed..f606e8ec69 100644
--- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java
+++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java
@@ -18,11 +18,13 @@ import java.util.regex.Matcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.server.Request;
+
/**
* Rewrite the URI by matching with a regular expression.
* The replacement string may use $n" to replace the nth capture group.
*/
-public class RewriteRegexRule extends RegexRule
+public class RewriteRegexRule extends RegexRule implements Rule.ApplyURI
{
private String _replacement;
@@ -62,6 +64,25 @@ public class RewriteRegexRule extends RegexRule
}
/* ------------------------------------------------------------ */
+ public void applyURI(Request request, String oldTarget, String newTarget) throws IOException
+ {
+ Matcher matcher=_regex.matcher(request.getRequestURI());
+ boolean matches = matcher.matches();
+ if (matches)
+ {
+ String uri=_replacement;
+ for (int g=1;g<=matcher.groupCount();g++)
+ {
+ String group = matcher.group(g);
+ uri=uri.replaceAll("\\$"+g,group);
+ }
+ request.setRequestURI(uri);
+ }
+ else
+ request.setRequestURI(newTarget);
+ }
+
+ /* ------------------------------------------------------------ */
/**
* Returns the replacement string.
*/
diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/Rule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/Rule.java
index d27fdbe188..26866d7b3e 100644
--- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/Rule.java
+++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/Rule.java
@@ -17,11 +17,21 @@ import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.server.Request;
+
/**
* An abstract rule for creating rewrite rules.
*/
public abstract class Rule
{
+ /**
+ * Interface used to apply a changed target if {@link RuleContainer#setRewriteRequestURI(boolean)} is true.
+ */
+ public interface ApplyURI
+ {
+ void applyURI(Request request, String oldTarget, String newTarget) throws IOException;
+ }
+
protected boolean _terminating;
protected boolean _handling;
diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java
index cf71228f15..2b95d12143 100644
--- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java
+++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java
@@ -203,9 +203,14 @@ public class RuleContainer extends Rule
original_set=true;
request.setAttribute(_originalPathAttribute, target);
}
-
+
if (_rewriteRequestURI)
- ((Request)request).setRequestURI(applied);
+ {
+ if (rule instanceof Rule.ApplyURI && !target.equals(request.getRequestURI()))
+ ((Rule.ApplyURI)rule).applyURI((Request)request, target, applied);
+ else
+ ((Request)request).setRequestURI(applied);
+ }
if (_rewritePathInfo)
((Request)request).setPathInfo(applied);
diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteHandlerTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteHandlerTest.java
index be50988ca4..bfdc2a5c9d 100644
--- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteHandlerTest.java
+++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteHandlerTest.java
@@ -31,6 +31,7 @@ public class RewriteHandlerTest extends AbstractRuleTestCase
private RewritePatternRule _rule1;
private RewritePatternRule _rule2;
private RewritePatternRule _rule3;
+ private RewriteRegexRule _rule4;
@Before
public void init() throws Exception
@@ -58,8 +59,11 @@ public class RewriteHandlerTest extends AbstractRuleTestCase
_rule3 = new RewritePatternRule();
_rule3.setPattern("/ccc/*");
_rule3.setReplacement("/ddd");
+ _rule4 = new RewriteRegexRule();
+ _rule4.setRegex("/xxx/(.*)");
+ _rule4.setReplacement("/$1/zzz");
- _handler.setRules(new Rule[]{_rule1,_rule2,_rule3});
+ _handler.setRules(new Rule[]{_rule1,_rule2,_rule3,_rule4});
start(false);
}
@@ -136,4 +140,38 @@ public class RewriteHandlerTest extends AbstractRuleTestCase
assertEquals("/aaa/bar",_request.getAttribute("before"));
assertTrue(_request.isHandled());
}
+
+
+ public void testEncodedPattern() throws Exception
+ {
+ _response.setStatus(200);
+ _request.setHandled(false);
+ _handler.setOriginalPathAttribute("/before");
+ _handler.setRewriteRequestURI(true);
+ _handler.setRewritePathInfo(false);
+ _request.setRequestURI("/ccc/x%2Fy");
+ _request.setPathInfo("/ccc/x/y");
+ _handler.handle("/ccc/x/y",_request,_request, _response);
+ assertEquals(201,_response.getStatus());
+ assertEquals("/ddd/x/y",_request.getAttribute("target"));
+ assertEquals("/ddd/x%2Fy",_request.getAttribute("URI"));
+ assertEquals("/ccc/x/y",_request.getAttribute("info"));
+
+ }
+ public void testEncodedRegex() throws Exception
+ {
+ _response.setStatus(200);
+ _request.setHandled(false);
+ _handler.setOriginalPathAttribute("/before");
+ _handler.setRewriteRequestURI(true);
+ _handler.setRewritePathInfo(false);
+ _request.setRequestURI("/xxx/x%2Fy");
+ _request.setPathInfo("/xxx/x/y");
+ _handler.handle("/xxx/x/y",_request,_request, _response);
+ assertEquals(201,_response.getStatus());
+ assertEquals("/x/y/zzz",_request.getAttribute("target"));
+ assertEquals("/x%2Fy/zzz",_request.getAttribute("URI"));
+ assertEquals("/xxx/x/y",_request.getAttribute("info"));
+
+ }
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java
index fffa3c42f3..cac3791497 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java
@@ -149,15 +149,18 @@ public class Response implements HttpServletResponse
if (sessionManager==null)
return url;
+ HttpURI uri = null;
if (sessionManager.isCheckingRemoteSessionIdEncoding() && URIUtil.hasScheme(url))
{
- HttpURI uri = new HttpURI(url);
+ uri = new HttpURI(url);
+ String path = uri.getPath();
+ path = (path == null?"":path);
int port=uri.getPort();
if (port<0)
port = HttpSchemes.HTTPS.equalsIgnoreCase(uri.getScheme())?443:80;
if (!request.getServerName().equalsIgnoreCase(uri.getHost()) ||
request.getServerPort()!=port ||
- !uri.getPath().startsWith(request.getContextPath()))
+ !path.startsWith(request.getContextPath())) //TODO the root context path is "", with which every non null string starts
return url;
}
@@ -198,6 +201,10 @@ public class Response implements HttpServletResponse
String id=sessionManager.getNodeId(session);
+ if (uri == null)
+ uri = new HttpURI(url);
+
+
// Already encoded
int prefix=url.indexOf(sessionURLPrefix);
if (prefix!=-1)
@@ -216,9 +223,16 @@ public class Response implements HttpServletResponse
int suffix=url.indexOf('?');
if (suffix<0)
suffix=url.indexOf('#');
- if (suffix<0)
- return url+sessionURLPrefix+id;
+ if (suffix<0)
+ {
+ return url+
+ ((HttpSchemes.HTTPS.equalsIgnoreCase(uri.getScheme()) || HttpSchemes.HTTP.equalsIgnoreCase(uri.getScheme())) && uri.getPath()==null?"/":"") + //if no path, insert the root path
+ sessionURLPrefix+id;
+ }
+
+
return url.substring(0,suffix)+
+ ((HttpSchemes.HTTPS.equalsIgnoreCase(uri.getScheme()) || HttpSchemes.HTTP.equalsIgnoreCase(uri.getScheme())) && uri.getPath()==null?"/":"")+ //if no path so insert the root path
sessionURLPrefix+id+url.substring(suffix);
}
@@ -1037,12 +1051,7 @@ public class Response implements HttpServletResponse
public void fwdReset()
{
resetBuffer();
- _mimeType=null;
- _cachedMimeType=null;
- _contentType=null;
- _characterEncoding=null;
- _explicitEncoding=false;
- _locale=null;
+
_outputState=NONE;
_writer=null;
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/GzipHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/GzipHandler.java
new file mode 100644
index 0000000000..003846cfc4
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/GzipHandler.java
@@ -0,0 +1,306 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+
+package org.eclipse.jetty.server.handler;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.continuation.Continuation;
+import org.eclipse.jetty.continuation.ContinuationListener;
+import org.eclipse.jetty.continuation.ContinuationSupport;
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.http.gzip.GzipResponseWrapper;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.util.log.Log;
+
+/* ------------------------------------------------------------ */
+/**
+ * GZIP Handler This handler will gzip the content of a response if:
+ * <ul>
+ * <li>The filter is mapped to a matching path</li>
+ * <li>The response status code is >=200 and <300
+ * <li>The content length is unknown or more than the <code>minGzipSize</code> initParameter or the minGzipSize is 0(default)</li>
+ * <li>The content-type is in the comma separated list of mimeTypes set in the <code>mimeTypes</code> initParameter or if no mimeTypes are defined the
+ * content-type is not "application/gzip"</li>
+ * <li>No content-encoding is specified by the resource</li>
+ * </ul>
+ *
+ * <p>
+ * Compressing the content can greatly improve the network bandwidth usage, but at a cost of memory and CPU cycles. If this handler is used for static content,
+ * then use of efficient direct NIO may be prevented, thus use of the gzip mechanism of the {@link org.eclipse.jetty.servlet.DefaultServlet} is advised instead.
+ * </p>
+ */
+public class GzipHandler extends HandlerWrapper
+{
+ protected Set<String> _mimeTypes;
+ protected Set<String> _excluded;
+ protected int _bufferSize = 8192;
+ protected int _minGzipSize = 256;
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Instantiates a new gzip handler.
+ */
+ public GzipHandler()
+ {
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Get the mime types.
+ *
+ * @return mime types to set
+ */
+ public Set<String> getMimeTypes()
+ {
+ return _mimeTypes;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set the mime types.
+ *
+ * @param mimeTypes
+ * the mime types to set
+ */
+ public void setMimeTypes(Set<String> mimeTypes)
+ {
+ _mimeTypes = mimeTypes;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set the mime types.
+ *
+ * @param mimeTypes
+ * the mime types to set
+ */
+ public void setMimeTypes(String mimeTypes)
+ {
+ if (mimeTypes != null)
+ {
+ _mimeTypes = new HashSet<String>();
+ StringTokenizer tok = new StringTokenizer(mimeTypes,",",false);
+ while (tok.hasMoreTokens())
+ {
+ _mimeTypes.add(tok.nextToken());
+ }
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Get the excluded user agents.
+ *
+ * @return excluded user agents
+ */
+ public Set<String> getExcluded()
+ {
+ return _excluded;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set the excluded user agents.
+ *
+ * @param excluded
+ * excluded user agents to set
+ */
+ public void setExcluded(Set<String> excluded)
+ {
+ _excluded = excluded;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set the excluded user agents.
+ *
+ * @param excluded
+ * excluded user agents to set
+ */
+ public void setExcluded(String excluded)
+ {
+ if (excluded != null)
+ {
+ _excluded = new HashSet<String>();
+ StringTokenizer tok = new StringTokenizer(excluded,",",false);
+ while (tok.hasMoreTokens())
+ _excluded.add(tok.nextToken());
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Get the buffer size.
+ *
+ * @return the buffer size
+ */
+ public int setBufferSize()
+ {
+ return _bufferSize;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set the buffer size.
+ *
+ * @param bufferSize
+ * buffer size to set
+ */
+ public void setBufferSize(int bufferSize)
+ {
+ _bufferSize = bufferSize;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Get the minimum reponse size.
+ *
+ * @return minimum reponse size
+ */
+ public int getMinGzipSize()
+ {
+ return _minGzipSize;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set the minimum reponse size.
+ *
+ * @param minGzipSize
+ * minimum reponse size
+ */
+ public void setMinGzipSize(int minGzipSize)
+ {
+ _minGzipSize = minGzipSize;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.handler.HandlerWrapper#handle(java.lang.String, org.eclipse.jetty.server.Request, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ @Override
+ public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ {
+ if (_handler!=null && isStarted())
+ {
+ String ae = request.getHeader("accept-encoding");
+ if (ae != null && ae.indexOf("gzip")>=0 && !response.containsHeader("Content-Encoding")
+ && !HttpMethods.HEAD.equalsIgnoreCase(request.getMethod()))
+ {
+ if (_excluded!=null)
+ {
+ String ua = request.getHeader("User-Agent");
+ if (_excluded.contains(ua))
+ {
+ _handler.handle(target,baseRequest, request, response);
+ return;
+ }
+ }
+
+ final GzipResponseWrapper wrappedResponse = newGzipResponseWrapper(request,response);
+
+ boolean exceptional=true;
+ try
+ {
+ _handler.handle(target, baseRequest, request, wrappedResponse);
+ exceptional=false;
+ }
+ finally
+ {
+ Continuation continuation = ContinuationSupport.getContinuation(request);
+ if (continuation.isSuspended() && continuation.isResponseWrapped())
+ {
+ continuation.addContinuationListener(new ContinuationListener()
+ {
+ public void onComplete(Continuation continuation)
+ {
+ try
+ {
+ wrappedResponse.finish();
+ }
+ catch(IOException e)
+ {
+ Log.warn(e);
+ }
+ }
+
+ public void onTimeout(Continuation continuation)
+ {}
+ });
+ }
+ else if (exceptional && !response.isCommitted())
+ {
+ wrappedResponse.resetBuffer();
+ wrappedResponse.noGzip();
+ }
+ else
+ wrappedResponse.finish();
+ }
+ }
+ else
+ {
+ _handler.handle(target,baseRequest, request, response);
+ }
+ }
+ }
+
+ /**
+ * Allows derived implementations to replace ResponseWrapper implementation.
+ *
+ * @param request the request
+ * @param response the response
+ * @return the gzip response wrapper
+ */
+ protected GzipResponseWrapper newGzipResponseWrapper(HttpServletRequest request, HttpServletResponse response)
+ {
+ return new GzipResponseWrapper(request, response)
+ {
+ {
+ _mimeTypes = GzipHandler.this._mimeTypes;
+ _bufferSize = GzipHandler.this._bufferSize;
+ _minGzipSize = GzipHandler.this._minGzipSize;
+ }
+
+ @Override
+ protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
+ {
+ return GzipHandler.this.newWriter(out,encoding);
+ }
+ };
+ }
+
+ /**
+ * Allows derived implementations to replace PrintWriter implementation.
+ *
+ * @param out the out
+ * @param encoding the encoding
+ * @return the prints the writer
+ * @throws UnsupportedEncodingException
+ */
+ protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
+ {
+ return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
+ }
+}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java
index 61154f5533..4e1e291ffb 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java
@@ -102,17 +102,6 @@ public class SelectChannelConnector extends AbstractNIOConnector
{
synchronized(this)
{
- if(_manager.isRunning())
- {
- try
- {
- _manager.stop();
- }
- catch (Exception e)
- {
- Log.warn(e);
- }
- }
if (_acceptChannel != null)
_acceptChannel.close();
_acceptChannel = null;
@@ -297,6 +286,20 @@ public class SelectChannelConnector extends AbstractNIOConnector
@Override
protected void doStop() throws Exception
{
+ synchronized(this)
+ {
+ if(_manager.isRunning())
+ {
+ try
+ {
+ _manager.stop();
+ }
+ catch (Exception e)
+ {
+ Log.warn(e);
+ }
+ }
+ }
super.doStop();
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java
index e1e48a3b4e..2135947bb4 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java
@@ -496,11 +496,13 @@ public class JDBCSessionManager extends AbstractSessionManager
if (Log.isDebugEnabled())
{
if (session==null)
- Log.debug("now="+now+
+ Log.debug("getSession("+idInCluster+"): not in session map,"+
+ " now="+now+
" lastSaved="+(session==null?0:session._data._lastSaved)+
" interval="+(_saveIntervalSec * 1000));
else
- Log.debug("now="+now+
+ Log.debug("getSession("+idInCluster+"): in session map, "+
+ " now="+now+
" lastSaved="+(session==null?0:session._data._lastSaved)+
" interval="+(_saveIntervalSec * 1000)+
" lastNode="+session._data.getLastNode()+
@@ -510,16 +512,17 @@ public class JDBCSessionManager extends AbstractSessionManager
if (session==null || ((now - session._data._lastSaved) >= (_saveIntervalSec * 1000)))
{
- Log.debug("no session ",idInCluster);
+ Log.debug("getSession("+idInCluster+"): no session in session map or stale session. Reloading session data from db.");
data = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context));
}
else if ((now - session._data._lastSaved) >= (_saveIntervalSec * 1000))
{
- Log.debug("old session",idInCluster);
+ Log.debug("getSession("+idInCluster+"): stale session. Reloading session data from db.");
data = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context));
}
else
{
+ Log.debug("getSession("+idInCluster+"): session in session map");
data = session._data;
}
@@ -527,10 +530,11 @@ public class JDBCSessionManager extends AbstractSessionManager
{
if (!data.getLastNode().equals(getIdManager().getWorkerName()) || session==null)
{
- //if the session in the database has not already expired
- if (data._expiryTime > now)
+ //if the session has no expiry, or it is not already expired
+ if (data._expiryTime <= 0 || data._expiryTime > now)
{
- Log.debug("expired session",idInCluster);
+ Log.debug("getSession("+idInCluster+"): lastNode="+data.getLastNode()+" thisNode="+getIdManager().getWorkerName());
+ data.setLastNode(getIdManager().getWorkerName());
//session last used on a different node, or we don't have it in memory
session = new Session(now,data);
_sessions.put(idInCluster, session);
@@ -539,16 +543,19 @@ public class JDBCSessionManager extends AbstractSessionManager
//the _dirty flag?
updateSessionNode(data);
}
+ else
+ if (Log.isDebugEnabled()) Log.debug("getSession("+idInCluster+"): Session has expired");
+
}
else
- if (Log.isDebugEnabled()) Log.debug("Session not stale "+session._data);
+ if (Log.isDebugEnabled()) Log.debug("getSession("+idInCluster+"): Session not stale "+session._data);
//session in db shares same id, but is not for this context
}
else
{
//No session in db with matching id and context path.
session=null;
- if (Log.isDebugEnabled()) Log.debug("No session in database matching id="+idInCluster);
+ if (Log.isDebugEnabled()) Log.debug("getSession("+idInCluster+"): No session in database matching id="+idInCluster);
}
return session;
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java
index af5cc382d4..d60f82dea6 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java
@@ -564,28 +564,19 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements
*/
protected SSLEngine createSSLEngine(SocketChannel channel) throws IOException
{
- try
+ SSLEngine engine;
+ if (channel != null && _sslContextFactory.isSessionCachingEnabled())
{
- SSLEngine engine;
- if (channel != null && _sslContextFactory.isSessionCachingEnabled())
- {
- String peerHost = channel.socket().getInetAddress().getHostAddress();
- int peerPort = channel.socket().getPort();
- engine = _sslContextFactory.getSslContext().createSSLEngine(peerHost, peerPort);
- }
- else
- {
- engine = _sslContextFactory.getSslContext().createSSLEngine();
- }
- customizeEngine(engine);
- return engine;
+ String peerHost = channel.socket().getInetAddress().getHostAddress();
+ int peerPort = channel.socket().getPort();
+ engine = _sslContextFactory.getSslContext().createSSLEngine(peerHost, peerPort);
}
- catch (Exception x)
+ else
{
- Log.warn("Error creating SSLEngine -- closing this connector", x);
- close();
- throw new IllegalStateException(x);
+ engine = _sslContextFactory.getSslContext().createSSLEngine();
}
+ customizeEngine(engine);
+ return engine;
}
/* ------------------------------------------------------------ */
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/BlockingChannelCloseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/BlockingChannelCloseTest.java
new file mode 100644
index 0000000000..5081a80fbd
--- /dev/null
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/BlockingChannelCloseTest.java
@@ -0,0 +1,29 @@
+// ========================================================================
+// Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+
+package org.eclipse.jetty.server;
+
+import org.eclipse.jetty.server.nio.BlockingChannelConnector;
+import org.junit.BeforeClass;
+
+/**
+ * HttpServer Tester.
+ */
+public class BlockingChannelCloseTest extends HttpServerTestBase
+{
+ @BeforeClass
+ public static void init() throws Exception
+ {
+ startServer(new BlockingChannelConnector());
+ }
+}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectorCloseTestBase.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectorCloseTestBase.java
new file mode 100644
index 0000000000..3056d83eba
--- /dev/null
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectorCloseTestBase.java
@@ -0,0 +1,232 @@
+//========================================================================
+//Copyright (c) Webtide LLC
+//------------------------------------------------------------------------
+//All rights reserved. This program and the accompanying materials
+//are made available under the terms of the Eclipse Public License v1.0
+//and Apache License v2.0 which accompanies this distribution.
+//
+//The Eclipse Public License is available at
+//http://www.eclipse.org/legal/epl-v10.html
+//
+//The Apache License v2.0 is available at
+//http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+//You may elect to redistribute this code under either of these licenses.
+//========================================================================
+
+package org.eclipse.jetty.server;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.StringTokenizer;
+
+import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * HttpServer Tester.
+ */
+public abstract class ConnectorCloseTestBase extends HttpServerTestFixture
+{
+ private static String __content =
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis felis nunc. "+
+ "Quisque suscipit mauris et ante auctor ornare rhoncus lacus aliquet. Pellentesque "+
+ "habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. "+
+ "Vestibulum sit amet felis augue, vel convallis dolor. Cras accumsan vehicula diam "+
+ "at faucibus. Etiam in urna turpis, sed congue mi. Morbi et lorem eros. Donec vulputate "+
+ "velit in risus suscipit lobortis. Aliquam id urna orci, nec sollicitudin ipsum. "+
+ "Cras a orci turpis. Donec suscipit vulputate cursus. Mauris nunc tellus, fermentum "+
+ "eu auctor ut, mollis at diam. Quisque porttitor ultrices metus, vitae tincidunt massa "+
+ "sollicitudin a. Vivamus porttitor libero eget purus hendrerit cursus. Integer aliquam "+
+ "consequat mauris quis luctus. Cras enim nibh, dignissim eu faucibus ac, mollis nec neque. "+
+ "Aliquam purus mauris, consectetur nec convallis lacinia, porta sed ante. Suspendisse "+
+ "et cursus magna. Donec orci enim, molestie a lobortis eu, imperdiet vitae neque.";
+ private static int __length = __content.length();
+
+ private StringBuffer _response;
+ private boolean _continue;
+
+ /* ------------------------------------------------------------ */
+ @Test
+ public void testCloseBetweenRequests() throws Exception
+ {
+ int total = 0;
+
+ _continue = true;
+ _response = new StringBuffer();
+
+ configureServer(new HelloWorldHandler());
+
+ Socket client = newSocket(HOST,_connector.getLocalPort());
+ try
+ {
+ OutputStream os = client.getOutputStream();
+
+ ResponseReader reader = new ResponseReader(client);
+ Thread runner = new Thread(reader);
+ runner.start();
+
+ for (int pipeline = 1; pipeline < 32; pipeline++)
+ {
+ if (pipeline == 16)
+ _connector.close();
+
+ total += pipeline;
+
+ String request = "";
+ for (int i = 0; i < pipeline; i++)
+ {
+ request +=
+ "GET /data?writes=1&block=16&id="+i+" HTTP/1.1\r\n"+
+ "host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
+ "user-agent: testharness/1.0 (blah foo/bar)\r\n"+
+ "accept-encoding: nothing\r\n"+
+ "cookie: aaa=1234567890\r\n"+
+ "\r\n";
+ }
+ os.write(request.getBytes());
+ os.flush();
+
+ Thread.sleep(50);
+ }
+
+ _continue = false;
+ runner.join();
+ }
+ finally
+ {
+ client.close();
+
+ int count = 0;
+ StringTokenizer lines = new StringTokenizer(_response.toString(),"\r\n");
+ while(lines.hasMoreTokens())
+ {
+ String line = lines.nextToken();
+ if (line.equals("HTTP/1.1 200 OK"))
+ {
+ ++count;
+ }
+ }
+
+ assertEquals(total, count);
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ @Test
+ public void testCloseBetweenChunks() throws Exception
+ {
+ _continue = true;
+ _response = new StringBuffer();
+
+ configureServer(new EchoHandler());
+
+ Socket client = newSocket(HOST,_connector.getLocalPort());
+ try
+ {
+ OutputStream os = client.getOutputStream();
+
+ ResponseReader reader = new ResponseReader(client);
+ Thread runner = new Thread(reader);
+ runner.start();
+
+ String content = "abcdefghij";
+ byte[] bytes = __content.getBytes("utf-8");
+
+ os.write((
+ "POST /echo?charset=utf-8 HTTP/1.1\r\n"+
+ "host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
+ "content-type: text/plain; charset=utf-8\r\n"+
+ "content-length: "+bytes.length+"\r\n"+
+ "\r\n"
+ ).getBytes("iso-8859-1"));
+
+ int len = bytes.length;
+ int offset = 0;
+ int stop = len / 2;
+ while (offset < stop)
+ {
+ os.write(bytes, offset, 64);
+ offset += 64;
+ }
+
+ _connector.close();
+
+ while (offset < len)
+ {
+ os.write(bytes, offset, len-offset <=64 ? len-offset : 64);
+ offset += 64;
+ }
+ os.flush();
+
+ Thread.sleep(50);
+
+ _continue = false;
+ runner.join();
+
+ String in = _response.toString();
+ assertTrue(in.indexOf(__content.substring(__length-64))>0);
+ }
+ finally
+ {
+ client.close();
+ }
+ }
+
+
+ /* ------------------------------------------------------------ */
+ public class ResponseReader implements Runnable
+ {
+ private BufferedReader _reader;
+
+ /* ------------------------------------------------------------ */
+ public ResponseReader(Socket client) throws IOException
+ {
+ _reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see java.lang.Runnable#run()
+ */
+ public void run()
+ {
+ int count = 0;
+ char[] buffer = new char[256];
+
+ try
+ {
+ while (_continue)
+ {
+ if (_reader.ready())
+ {
+ count = _reader.read(buffer);
+ _response.append(buffer, 0, count);
+ }
+ else
+ {
+ count = 0;
+ Thread.sleep(10);
+ }
+
+ }
+ }
+ catch (IOException ex) { }
+ catch (InterruptedException ex) { }
+ finally
+ {
+ try
+ {
+ _reader.close();
+ }
+ catch (IOException e) { }
+ }
+ }
+ }
+}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpURITest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpURITest.java
index 220261803c..44efd5b185 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpURITest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpURITest.java
@@ -67,6 +67,7 @@ public class HttpURITest
/*29*/ {"/?x=y",null, null, null,null,"/", null,"x=y",null},
/*30*/ {"/?abc=test",null, null, null,null,"/", null,"abc=test",null},
/*31*/ {"/#fragment",null, null, null,null,"/", null,null,"fragment"},
+ /*32*/ {"http://localhost:8080", "http", "//localhost:8080", "localhost", "8080", null, null, null, null}
};
@Test
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java
index 97009a6e11..d91b5c4cfc 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java
@@ -348,6 +348,21 @@ public class ResponseTest
assertEquals("http://other:8888/path/info;param?query=0&more=1#target",response.encodeURL("http://other:8888/path/info;param?query=0&more=1#target"));
assertEquals("http://myhost/path/info;param?query=0&more=1#target",response.encodeURL("http://myhost/path/info;param?query=0&more=1#target"));
assertEquals("http://myhost:8888/other/info;param?query=0&more=1#target",response.encodeURL("http://myhost:8888/other/info;param?query=0&more=1#target"));
+
+ request.setContextPath("");
+ assertEquals("http://myhost:8888/;jsessionid=12345",response.encodeURL("http://myhost:8888"));
+ assertEquals("https://myhost:8888/;jsessionid=12345",response.encodeURL("https://myhost:8888"));
+ assertEquals("mailto:/foo", response.encodeURL("mailto:/foo"));
+ assertEquals("http://myhost:8888/;jsessionid=12345",response.encodeURL("http://myhost:8888/"));
+ assertEquals("http://myhost:8888/;jsessionid=12345", response.encodeURL("http://myhost:8888/;jsessionid=7777"));
+ assertEquals("http://myhost:8888/;param;jsessionid=12345?query=0&more=1#target",response.encodeURL("http://myhost:8888/;param?query=0&more=1#target"));
+ assertEquals("http://other:8888/path/info;param?query=0&more=1#target",response.encodeURL("http://other:8888/path/info;param?query=0&more=1#target"));
+ manager.setCheckingRemoteSessionIdEncoding(false);
+ assertEquals("/foo;jsessionid=12345", response.encodeURL("/foo"));
+ assertEquals("/;jsessionid=12345", response.encodeURL("/"));
+ assertEquals("/foo.html;jsessionid=12345#target", response.encodeURL("/foo.html#target"));
+ assertEquals(";jsessionid=12345", response.encodeURL(""));
+
}
@Test
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelConnectorCloseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelConnectorCloseTest.java
new file mode 100644
index 0000000000..920a7094b1
--- /dev/null
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelConnectorCloseTest.java
@@ -0,0 +1,31 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+
+package org.eclipse.jetty.server;
+
+import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.junit.Before;
+
+
+/* ------------------------------------------------------------ */
+public class SelectChannelConnectorCloseTest extends ConnectorCloseTestBase
+{
+
+ /* ------------------------------------------------------------ */
+ @Before
+ public void init() throws Exception
+ {
+ System.setProperty("org.eclipse.jetty.util.log.DEBUG","true");
+ startServer(new SelectChannelConnector());
+ }
+}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/SocketConnectorCloseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/SocketConnectorCloseTest.java
new file mode 100644
index 0000000000..e11c56a666
--- /dev/null
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/SocketConnectorCloseTest.java
@@ -0,0 +1,31 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+
+package org.eclipse.jetty.server;
+
+import org.eclipse.jetty.server.bio.SocketConnector;
+import org.junit.Before;
+
+
+/* ------------------------------------------------------------ */
+public class SocketConnectorCloseTest extends ConnectorCloseTestBase
+{
+
+ /* ------------------------------------------------------------ */
+ @Before
+ public void init() throws Exception
+ {
+ System.setProperty("org.eclipse.jetty.util.log.DEBUG","true");
+ startServer(new SocketConnector());
+ }
+}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/StressTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/StressTest.java
index a2053c8b24..ec10ba221c 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/StressTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/StressTest.java
@@ -117,7 +117,8 @@ public class StressTest
@Test
public void testNonPersistent() throws Throwable
{
- assumeTrue(!OS.IS_OSX || Stress.isEnabled());
+ // TODO needs to be further investigated
+ assumeTrue(!OS.IS_OSX || Stress.isEnabled());
doThreads(10,100,false);
if (Stress.isEnabled())
@@ -132,7 +133,8 @@ public class StressTest
@Test
public void testPersistent() throws Throwable
{
- assumeTrue(!OS.IS_OSX || Stress.isEnabled());
+ // TODO needs to be further investigated
+ assumeTrue(!OS.IS_OSX || Stress.isEnabled());
doThreads(20,100,true);
if (Stress.isEnabled())
diff --git a/jetty-servlets/pom.xml b/jetty-servlets/pom.xml
index 01cd507e57..9b88c2a126 100644
--- a/jetty-servlets/pom.xml
+++ b/jetty-servlets/pom.xml
@@ -54,6 +54,11 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.eclipse.jetty.toolchain</groupId>
+ <artifactId>jetty-test-helper</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-continuation</artifactId>
<version>${project.version}</version>
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java
index 694267d847..3bd5d5ae70 100644
--- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java
+++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java
@@ -127,7 +127,7 @@ public class CrossOriginFilter implements Filter
allowedMethods.addAll(Arrays.asList(allowedMethodsConfig.split(",")));
String allowedHeadersConfig = config.getInitParameter(ALLOWED_HEADERS_PARAM);
- if (allowedHeadersConfig == null) allowedHeadersConfig = "X-Requested-With,Content-Type,Accept";
+ if (allowedHeadersConfig == null) allowedHeadersConfig = "X-Requested-With,Content-Type,Accept,Origin";
allowedHeaders.addAll(Arrays.asList(allowedHeadersConfig.split(",")));
String preflightMaxAgeConfig = config.getInitParameter(PREFLIGHT_MAX_AGE_PARAM);
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java
index b77d783c4c..e48cb70284 100644
--- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java
+++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java
@@ -20,24 +20,20 @@ import java.io.UnsupportedEncodingException;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;
-import java.util.zip.GZIPOutputStream;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
-import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpServletResponseWrapper;
import org.eclipse.jetty.continuation.Continuation;
import org.eclipse.jetty.continuation.ContinuationListener;
import org.eclipse.jetty.continuation.ContinuationSupport;
import org.eclipse.jetty.http.HttpMethods;
-import org.eclipse.jetty.util.ByteArrayOutputStream2;
-import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.http.gzip.GzipResponseWrapper;
import org.eclipse.jetty.util.log.Log;
/* ------------------------------------------------------------ */
@@ -65,11 +61,15 @@ import org.eclipse.jetty.util.log.Log;
*/
public class GzipFilter extends UserAgentFilter
{
- protected Set _mimeTypes;
+ protected Set<String> _mimeTypes;
protected int _bufferSize=8192;
protected int _minGzipSize=256;
- protected Set _excluded;
+ protected Set<String> _excluded;
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.servlets.UserAgentFilter#init(javax.servlet.FilterConfig)
+ */
public void init(FilterConfig filterConfig) throws ServletException
{
super.init(filterConfig);
@@ -85,7 +85,7 @@ public class GzipFilter extends UserAgentFilter
tmp=filterConfig.getInitParameter("mimeTypes");
if (tmp!=null)
{
- _mimeTypes=new HashSet();
+ _mimeTypes=new HashSet<String>();
StringTokenizer tok = new StringTokenizer(tmp,",",false);
while (tok.hasMoreTokens())
_mimeTypes.add(tok.nextToken());
@@ -94,17 +94,25 @@ public class GzipFilter extends UserAgentFilter
tmp=filterConfig.getInitParameter("excludedAgents");
if (tmp!=null)
{
- _excluded=new HashSet();
+ _excluded=new HashSet<String>();
StringTokenizer tok = new StringTokenizer(tmp,",",false);
while (tok.hasMoreTokens())
_excluded.add(tok.nextToken());
}
}
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.servlets.UserAgentFilter#destroy()
+ */
public void destroy()
{
}
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.servlets.UserAgentFilter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
+ */
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException
{
@@ -125,7 +133,7 @@ public class GzipFilter extends UserAgentFilter
}
}
- final GZIPResponseWrapper wrappedResponse=newGZIPResponseWrapper(request,response);
+ final GzipResponseWrapper wrappedResponse=newGzipResponseWrapper(request,response);
boolean exceptional=true;
try
@@ -171,436 +179,41 @@ public class GzipFilter extends UserAgentFilter
}
}
- protected GZIPResponseWrapper newGZIPResponseWrapper(HttpServletRequest request, HttpServletResponse response)
- {
- return new GZIPResponseWrapper(request,response);
- }
-
- /*
- * Allows derived implementations to replace PrintWriter implementation
+ /**
+ * Allows derived implementations to replace ResponseWrapper implementation.
+ *
+ * @param request the request
+ * @param response the response
+ * @return the gzip response wrapper
*/
- protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
- {
- return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
- }
-
- public class GZIPResponseWrapper extends HttpServletResponseWrapper
+ protected GzipResponseWrapper newGzipResponseWrapper(HttpServletRequest request, HttpServletResponse response)
{
- HttpServletRequest _request;
- boolean _noGzip;
- PrintWriter _writer;
- GzipStream _gzStream;
- long _contentLength=-1;
-
- public GZIPResponseWrapper(HttpServletRequest request, HttpServletResponse response)
- {
- super(response);
- _request=request;
- }
-
- public void setContentType(String ct)
- {
- super.setContentType(ct);
-
- if (ct!=null)
- {
- int colon=ct.indexOf(";");
- if (colon>0)
- ct=ct.substring(0,colon);
- }
-
- if ((_gzStream==null || _gzStream._out==null) &&
- (_mimeTypes==null && "application/gzip".equalsIgnoreCase(ct) ||
- _mimeTypes!=null && (ct==null||!_mimeTypes.contains(StringUtil.asciiToLowerCase(ct)))))
- {
- noGzip();
- }
- }
-
- public void setStatus(int sc, String sm)
- {
- super.setStatus(sc,sm);
- if (sc<200||sc>=300)
- noGzip();
- }
-
- public void setStatus(int sc)
- {
- super.setStatus(sc);
- if (sc<200||sc>=300)
- noGzip();
- }
-
- public void setContentLength(int length)
- {
- _contentLength=length;
- if (_gzStream!=null)
- _gzStream.setContentLength(length);
- }
-
- public void addHeader(String name, String value)
- {
- if ("content-length".equalsIgnoreCase(name))
- {
- _contentLength=Long.parseLong(value);
- if (_gzStream!=null)
- _gzStream.setContentLength(_contentLength);
- }
- else if ("content-type".equalsIgnoreCase(name))
- {
- setContentType(value);
- }
- else if ("content-encoding".equalsIgnoreCase(name))
- {
- super.addHeader(name,value);
- if (!isCommitted())
- {
- noGzip();
- }
- }
- else
- super.addHeader(name,value);
- }
-
- public void setHeader(String name, String value)
+ return new GzipResponseWrapper(request, response)
{
- if ("content-length".equalsIgnoreCase(name))
{
- _contentLength=Long.parseLong(value);
- if (_gzStream!=null)
- _gzStream.setContentLength(_contentLength);
+ _mimeTypes = GzipFilter.this._mimeTypes;
+ _bufferSize = GzipFilter.this._bufferSize;
+ _minGzipSize = GzipFilter.this._minGzipSize;
}
- else if ("content-type".equalsIgnoreCase(name))
- {
- setContentType(value);
- }
- else if ("content-encoding".equalsIgnoreCase(name))
- {
- super.setHeader(name,value);
- if (!isCommitted())
- {
- noGzip();
- }
- }
- else
- super.setHeader(name,value);
- }
-
- public void setIntHeader(String name, int value)
- {
- if ("content-length".equalsIgnoreCase(name))
- {
- _contentLength=value;
- if (_gzStream!=null)
- _gzStream.setContentLength(_contentLength);
- }
- else
- super.setIntHeader(name,value);
- }
-
- public void flushBuffer() throws IOException
- {
- if (_writer!=null)
- _writer.flush();
- if (_gzStream!=null)
- _gzStream.finish();
- else
- getResponse().flushBuffer();
- }
-
- public void reset()
- {
- super.reset();
- if (_gzStream!=null)
- _gzStream.resetBuffer();
- _writer=null;
- _gzStream=null;
- _noGzip=false;
- _contentLength=-1;
- }
-
- public void resetBuffer()
- {
- super.resetBuffer();
- if (_gzStream!=null)
- _gzStream.resetBuffer();
- _writer=null;
- _gzStream=null;
- }
-
- public void sendError(int sc, String msg) throws IOException
- {
- resetBuffer();
- super.sendError(sc,msg);
- }
-
- public void sendError(int sc) throws IOException
- {
- resetBuffer();
- super.sendError(sc);
- }
-
- public void sendRedirect(String location) throws IOException
- {
- resetBuffer();
- super.sendRedirect(location);
- }
-
- public ServletOutputStream getOutputStream() throws IOException
- {
- if (_gzStream==null)
- {
- if (getResponse().isCommitted() || _noGzip)
- return getResponse().getOutputStream();
-
- _gzStream=newGzipStream(_request,(HttpServletResponse)getResponse(),_contentLength,_bufferSize,_minGzipSize);
- }
- else if (_writer!=null)
- throw new IllegalStateException("getWriter() called");
- return _gzStream;
- }
-
- public PrintWriter getWriter() throws IOException
- {
- if (_writer==null)
- {
- if (_gzStream!=null)
- throw new IllegalStateException("getOutputStream() called");
-
- if (getResponse().isCommitted() || _noGzip)
- return getResponse().getWriter();
-
- _gzStream=newGzipStream(_request,(HttpServletResponse)getResponse(),_contentLength,_bufferSize,_minGzipSize);
- _writer=newWriter(_gzStream,getCharacterEncoding());
- }
- return _writer;
- }
-
- void noGzip()
- {
- _noGzip=true;
- if (_gzStream!=null)
+ @Override
+ protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
{
- try
- {
- _gzStream.doNotGzip();
- }
- catch (IOException e)
- {
- throw new IllegalStateException(e);
- }
+ return GzipFilter.this.newWriter(out,encoding);
}
- }
-
- void finish() throws IOException
- {
- if (_writer!=null && !_gzStream._closed)
- _writer.flush();
- if (_gzStream!=null)
- _gzStream.finish();
- }
-
- protected GzipStream newGzipStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minGzipSize) throws IOException
- {
- return new GzipStream(request,response,contentLength,bufferSize,minGzipSize);
- }
+ };
}
-
- public static class GzipStream extends ServletOutputStream
+ /**
+ * Allows derived implementations to replace PrintWriter implementation.
+ *
+ * @param out the out
+ * @param encoding the encoding
+ * @return the prints the writer
+ * @throws UnsupportedEncodingException
+ */
+ protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
{
- protected HttpServletRequest _request;
- protected HttpServletResponse _response;
- protected OutputStream _out;
- protected ByteArrayOutputStream2 _bOut;
- protected GZIPOutputStream _gzOut;
- protected boolean _closed;
- protected int _bufferSize;
- protected int _minGzipSize;
- protected long _contentLength;
-
- public GzipStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minGzipSize) throws IOException
- {
- _request=request;
- _response=response;
- _contentLength=contentLength;
- _bufferSize=bufferSize;
- _minGzipSize=minGzipSize;
- if (minGzipSize==0)
- doGzip();
- }
-
- public void resetBuffer()
- {
- if (_response.isCommitted())
- throw new IllegalStateException("Committed");
- _closed=false;
- _out=null;
- _bOut=null;
- if (_gzOut!=null)
- _response.setHeader("Content-Encoding",null);
- _gzOut=null;
- }
-
- public void setContentLength(long length)
- {
- _contentLength=length;
- }
-
- public void flush() throws IOException
- {
- if (_out==null || _bOut!=null)
- {
- if (_contentLength>0 && _contentLength<_minGzipSize)
- doNotGzip();
- else
- doGzip();
- }
-
- _out.flush();
- }
-
- public void close() throws IOException
- {
- if (_closed)
- return;
-
- if (_request.getAttribute("javax.servlet.include.request_uri")!=null)
- flush();
- else
- {
- if (_bOut!=null)
- {
- if (_contentLength<0)
- _contentLength=_bOut.getCount();
- if (_contentLength<_minGzipSize)
- doNotGzip();
- else
- doGzip();
- }
- else if (_out==null)
- {
- doNotGzip();
- }
-
- if (_gzOut!=null)
- _gzOut.close();
- else
- _out.close();
- _closed=true;
- }
- }
-
- public void finish() throws IOException
- {
- if (!_closed)
- {
- if (_out==null || _bOut!=null)
- {
- if (_contentLength>0 && _contentLength<_minGzipSize)
- doNotGzip();
- else
- doGzip();
- }
-
- if (_gzOut!=null && !_closed)
- {
- _closed=true;
- _gzOut.close();
- }
- }
- }
-
- public void write(int b) throws IOException
- {
- checkOut(1);
- _out.write(b);
- }
-
- public void write(byte b[]) throws IOException
- {
- checkOut(b.length);
- _out.write(b);
- }
-
- public void write(byte b[], int off, int len) throws IOException
- {
- checkOut(len);
- _out.write(b,off,len);
- }
-
- protected boolean setContentEncodingGzip()
- {
- _response.setHeader("Content-Encoding", "gzip");
- return _response.containsHeader("Content-Encoding");
- }
-
- public void doGzip() throws IOException
- {
- if (_gzOut==null)
- {
- if (_response.isCommitted())
- throw new IllegalStateException();
-
- if (setContentEncodingGzip())
- {
- _out=_gzOut=new GZIPOutputStream(_response.getOutputStream(),_bufferSize);
-
- if (_bOut!=null)
- {
- _out.write(_bOut.getBuf(),0,_bOut.getCount());
- _bOut=null;
- }
- }
- else
- doNotGzip();
- }
- }
-
- public void doNotGzip() throws IOException
- {
- if (_gzOut!=null)
- throw new IllegalStateException();
- if (_out==null || _bOut!=null )
- {
- _out=_response.getOutputStream();
- if (_contentLength>=0)
- {
- if(_contentLength<Integer.MAX_VALUE)
- _response.setContentLength((int)_contentLength);
- else
- _response.setHeader("Content-Length",Long.toString(_contentLength));
- }
-
- if (_bOut!=null)
- _out.write(_bOut.getBuf(),0,_bOut.getCount());
- _bOut=null;
- }
- }
-
- private void checkOut(int length) throws IOException
- {
- if (_closed)
- throw new IOException("CLOSED");
-
- if (_out==null)
- {
- if (_response.isCommitted() || (_contentLength>=0 && _contentLength<_minGzipSize))
- doNotGzip();
- else if (length>_minGzipSize)
- doGzip();
- else
- _out=_bOut=new ByteArrayOutputStream2(_bufferSize);
- }
- else if (_bOut!=null)
- {
- if (_response.isCommitted() || (_contentLength>=0 && _contentLength<_minGzipSize))
- doNotGzip();
- else if (length>=(_bOut.getBuf().length -_bOut.getCount()))
- doGzip();
- }
- }
+ return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
}
-
}
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java
index 97fdee7f90..0084ddaf86 100644
--- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java
+++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java
@@ -24,6 +24,8 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.http.gzip.GzipResponseWrapper;
+import org.eclipse.jetty.http.gzip.GzipStream;
import org.eclipse.jetty.io.UncheckedPrintWriter;
@@ -55,16 +57,20 @@ public class IncludableGzipFilter extends GzipFilter
}
@Override
- protected GZIPResponseWrapper newGZIPResponseWrapper(HttpServletRequest request, HttpServletResponse response)
+ protected GzipResponseWrapper newGzipResponseWrapper(HttpServletRequest request, HttpServletResponse response)
{
return new IncludableResponseWrapper(request,response);
}
- public class IncludableResponseWrapper extends GzipFilter.GZIPResponseWrapper
+ public class IncludableResponseWrapper extends GzipResponseWrapper
{
public IncludableResponseWrapper(HttpServletRequest request, HttpServletResponse response)
{
super(request,response);
+
+ _mimeTypes = IncludableGzipFilter.this._mimeTypes;
+ _bufferSize = IncludableGzipFilter.this._bufferSize;
+ _minGzipSize = IncludableGzipFilter.this._minGzipSize;
}
@Override
@@ -72,9 +78,15 @@ public class IncludableGzipFilter extends GzipFilter
{
return new IncludableGzipStream(request,response,contentLength,bufferSize,minGzipSize);
}
+
+ @Override
+ protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
+ {
+ return IncludableGzipFilter.this.newWriter(out,encoding);
+ }
}
- public class IncludableGzipStream extends GzipFilter.GzipStream
+ public class IncludableGzipStream extends GzipStream
{
public IncludableGzipStream(HttpServletRequest request, HttpServletResponse response, long contentLength, int bufferSize, int minGzipSize)
throws IOException
@@ -93,7 +105,7 @@ public class IncludableGzipFilter extends GzipFilter
return _response.containsHeader("Content-Encoding");
}
}
-
+
@Override
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
{
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java
index cb5e043a47..c891c940a7 100644
--- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java
+++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java
@@ -38,6 +38,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.HttpConnection;
import org.eclipse.jetty.client.HttpExchange;
import org.eclipse.jetty.continuation.Continuation;
import org.eclipse.jetty.continuation.ContinuationSupport;
@@ -48,34 +49,40 @@ import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.PathMap;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.EofException;
+import org.eclipse.jetty.servlet.Holder;
import org.eclipse.jetty.util.HostMap;
import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
-
+import org.omg.CORBA._PolicyStub;
/**
* Asynchronous Proxy Servlet.
- *
- * Forward requests to another server either as a standard web proxy (as defined by
- * RFC2616) or as a transparent proxy.
+ *
+ * Forward requests to another server either as a standard web proxy (as defined by RFC2616) or as a transparent proxy.
* <p>
- * This servlet needs the jetty-util and jetty-client classes to be available to
- * the web application.
+ * This servlet needs the jetty-util and jetty-client classes to be available to the web application.
* <p>
- * To facilitate JMX monitoring, the "HttpClient", it's "ThreadPool" and the "Logger"
- * are set as context attributes prefixed with the servlet name.
+ * To facilitate JMX monitoring, the "HttpClient", it's "ThreadPool" and the "Logger" are set as context attributes prefixed with the servlet name.
* <p>
- * The following init parameters may be used to configure the servlet: <ul>
+ * The following init parameters may be used to configure the servlet:
+ * <ul>
* <li>name - Name of Proxy servlet (default: "ProxyServlet"
* <li>maxThreads - maximum threads
* <li>maxConnections - maximum connections per destination
- * <li>HostHeader - Force the host header to a particular value
+ * <li>timeout - the period in ms the client will wait for a response from the proxied server
+ * <li>idleTimeout - the period in ms a connection to proxied server can be idle for before it is closed
+ * <li>requestHeaderSize - the size of the request header buffer (d. 6,144)
+ * <li>requestBufferSize - the size of the request buffer (d. 12,288)
+ * <li>responseHeaderSize - the size of the response header buffer (d. 6,144)
+ * <li>responseBufferSize - the size of the response buffer (d. 32,768)
+ * <li>HostHeader - Force the host header to a particular value
* <li>whiteList - comma-separated list of allowed proxy destinations
* <li>blackList - comma-separated list of forbidden proxy destinations
* </ul>
- *
+ *
* @see org.eclipse.jetty.server.handler.ConnectHandler
*/
public class ProxyServlet implements Servlet
@@ -103,53 +110,40 @@ public class ProxyServlet implements Servlet
protected HostMap<PathMap> _black = new HostMap<PathMap>();
/* ------------------------------------------------------------ */
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see javax.servlet.Servlet#init(javax.servlet.ServletConfig)
*/
public void init(ServletConfig config) throws ServletException
{
- _config=config;
- _context=config.getServletContext();
-
- _client=new HttpClient();
- _client.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
-
- _hostHeader=config.getInitParameter("HostHeader");
-
+ _config = config;
+ _context = config.getServletContext();
+
+ _hostHeader = config.getInitParameter("HostHeader");
try
{
- _log= Log.getLogger("org.eclipse.jetty.servlets."+config.getServletName());
-
- String t = config.getInitParameter("maxThreads");
- if (t!=null)
- _client.setThreadPool(new QueuedThreadPool(Integer.parseInt(t)));
- else
- _client.setThreadPool(new QueuedThreadPool());
- ((QueuedThreadPool)_client.getThreadPool()).setName(config.getServletName());
+ _log = createLogger(config);
- t = config.getInitParameter("maxConnections");
- if (t!=null)
- _client.setMaxConnectionsPerAddress(Integer.parseInt(t));
-
- _client.start();
-
- if (_context!=null)
+ _client = createHttpClient(config);
+
+ if (_context != null)
{
- _context.setAttribute(config.getServletName()+".Logger",_log);
- _context.setAttribute(config.getServletName()+".ThreadPool",_client.getThreadPool());
- _context.setAttribute(config.getServletName()+".HttpClient",_client);
+ _context.setAttribute(config.getServletName() + ".Logger",_log);
+ _context.setAttribute(config.getServletName() + ".ThreadPool",_client.getThreadPool());
+ _context.setAttribute(config.getServletName() + ".HttpClient",_client);
}
String white = config.getInitParameter("whiteList");
if (white != null)
{
- parseList(white, _white);
+ parseList(white,_white);
}
String black = config.getInitParameter("blackList");
if (black != null)
{
- parseList(black, _black);
+ parseList(black,_black);
}
}
catch (Exception e)
@@ -169,14 +163,110 @@ public class ProxyServlet implements Servlet
_log.debug(x);
}
}
+
+
+ /**
+ * Create and return a logger based on the ServletConfig for use in the
+ * proxy servlet
+ *
+ * @param config
+ * @return Logger
+ */
+ protected Logger createLogger(ServletConfig config)
+ {
+ return Log.getLogger("org.eclipse.jetty.servlets." + config.getServletName());
+ }
+
+ /**
+ * Create and return an HttpClient based on ServletConfig
+ *
+ * By default this implementation will create an instance of the
+ * HttpClient for use by this proxy servlet.
+ *
+ * @param config
+ * @return HttpClient
+ * @throws Exception
+ */
+ protected HttpClient createHttpClient(ServletConfig config) throws Exception
+ {
+ HttpClient client = new HttpClient();
+ client.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
+
+ String t = config.getInitParameter("maxThreads");
+
+ if (t != null)
+ {
+ client.setThreadPool(new QueuedThreadPool(Integer.parseInt(t)));
+ }
+ else
+ {
+ client.setThreadPool(new QueuedThreadPool());
+ }
+
+ ((QueuedThreadPool)client.getThreadPool()).setName(config.getServletName());
+ t = config.getInitParameter("maxConnections");
+
+ if (t != null)
+ {
+ client.setMaxConnectionsPerAddress(Integer.parseInt(t));
+ }
+
+ t = config.getInitParameter("timeout");
+
+ if ( t != null )
+ {
+ client.setTimeout(Long.parseLong(t));
+ }
+
+ t = config.getInitParameter("idleTimeout");
+
+ if ( t != null )
+ {
+ client.setIdleTimeout(Long.parseLong(t));
+ }
+
+ t = config.getInitParameter("requestHeaderSize");
+
+ if ( t != null )
+ {
+ client.setRequestHeaderSize(Integer.parseInt(t));
+ }
+
+ t = config.getInitParameter("requestBufferSize");
+
+ if ( t != null )
+ {
+ client.setRequestBufferSize(Integer.parseInt(t));
+ }
+
+ t = config.getInitParameter("responseHeaderSize");
+
+ if ( t != null )
+ {
+ client.setResponseHeaderSize(Integer.parseInt(t));
+ }
+
+ t = config.getInitParameter("responseBufferSize");
+
+ if ( t != null )
+ {
+ client.setResponseBufferSize(Integer.parseInt(t));
+ }
+
+ client.start();
+
+ return client;
+ }
+
/* ------------------------------------------------------------ */
/**
- * Helper function to process a parameter value containing a list
- * of new entries and initialize the specified host map.
- *
- * @param list comma-separated list of new entries
- * @param hostMap target host map
+ * Helper function to process a parameter value containing a list of new entries and initialize the specified host map.
+ *
+ * @param list
+ * comma-separated list of new entries
+ * @param hostMap
+ * target host map
*/
private void parseList(String list, HostMap<PathMap> hostMap)
{
@@ -185,14 +275,14 @@ public class ProxyServlet implements Servlet
int idx;
String entry;
- StringTokenizer entries = new StringTokenizer(list, ",");
- while(entries.hasMoreTokens())
+ StringTokenizer entries = new StringTokenizer(list,",");
+ while (entries.hasMoreTokens())
{
entry = entries.nextToken();
idx = entry.indexOf('/');
- String host = idx > 0 ? entry.substring(0,idx) : entry;
- String path = idx > 0 ? entry.substring(idx) : "/*";
+ String host = idx > 0?entry.substring(0,idx):entry;
+ String path = idx > 0?entry.substring(idx):"/*";
host = host.trim();
PathMap pathMap = hostMap.get(host);
@@ -212,26 +302,28 @@ public class ProxyServlet implements Servlet
/* ------------------------------------------------------------ */
/**
* Check the request hostname and path against white- and blacklist.
- *
- * @param host hostname to check
- * @param path path to check
+ *
+ * @param host
+ * hostname to check
+ * @param path
+ * path to check
* @return true if request is allowed to be proxied
*/
public boolean validateDestination(String host, String path)
{
- if (_white.size()>0)
+ if (_white.size() > 0)
{
boolean match = false;
Object whiteObj = _white.getLazyMatches(host);
if (whiteObj != null)
{
- List whiteList = (whiteObj instanceof List) ? (List)whiteObj : Collections.singletonList(whiteObj);
+ List whiteList = (whiteObj instanceof List)?(List)whiteObj:Collections.singletonList(whiteObj);
- for (Object entry: whiteList)
+ for (Object entry : whiteList)
{
PathMap pathMap = ((Map.Entry<String, PathMap>)entry).getValue();
- if (match = (pathMap!=null && (pathMap.size()==0 || pathMap.match(path)!=null)))
+ if (match = (pathMap != null && (pathMap.size() == 0 || pathMap.match(path) != null)))
break;
}
}
@@ -245,12 +337,12 @@ public class ProxyServlet implements Servlet
Object blackObj = _black.getLazyMatches(host);
if (blackObj != null)
{
- List blackList = (blackObj instanceof List) ? (List)blackObj : Collections.singletonList(blackObj);
+ List blackList = (blackObj instanceof List)?(List)blackObj:Collections.singletonList(blackObj);
- for (Object entry: blackList)
+ for (Object entry : blackList)
{
PathMap pathMap = ((Map.Entry<String, PathMap>)entry).getValue();
- if (pathMap!=null && (pathMap.size()==0 || pathMap.match(path)!=null))
+ if (pathMap != null && (pathMap.size() == 0 || pathMap.match(path) != null))
return false;
}
}
@@ -260,7 +352,9 @@ public class ProxyServlet implements Servlet
}
/* ------------------------------------------------------------ */
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see javax.servlet.Servlet#getServletConfig()
*/
public ServletConfig getServletConfig()
@@ -268,9 +362,10 @@ public class ProxyServlet implements Servlet
return _config;
}
-
/* ------------------------------------------------------------ */
- /** Get the hostHeader.
+ /**
+ * Get the hostHeader.
+ *
* @return the hostHeader
*/
public String getHostHeader()
@@ -279,8 +374,11 @@ public class ProxyServlet implements Servlet
}
/* ------------------------------------------------------------ */
- /** Set the hostHeader.
- * @param hostHeader the hostHeader to set
+ /**
+ * Set the hostHeader.
+ *
+ * @param hostHeader
+ * the hostHeader to set
*/
public void setHostHeader(String hostHeader)
{
@@ -288,24 +386,26 @@ public class ProxyServlet implements Servlet
}
/* ------------------------------------------------------------ */
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see javax.servlet.Servlet#service(javax.servlet.ServletRequest, javax.servlet.ServletResponse)
*/
- public void service(ServletRequest req, ServletResponse res) throws ServletException,
- IOException
+ public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
{
- final int debug=_log.isDebugEnabled()?req.hashCode():0;
+ final int debug = _log.isDebugEnabled()?req.hashCode():0;
final HttpServletRequest request = (HttpServletRequest)req;
final HttpServletResponse response = (HttpServletResponse)res;
+
if ("CONNECT".equalsIgnoreCase(request.getMethod()))
{
handleConnect(request,response);
}
else
{
- final InputStream in=request.getInputStream();
- final OutputStream out=response.getOutputStream();
+ final InputStream in = request.getInputStream();
+ final OutputStream out = response.getOutputStream();
final Continuation continuation = ContinuationSupport.getContinuation(request);
@@ -313,19 +413,17 @@ public class ProxyServlet implements Servlet
response.sendError(HttpServletResponse.SC_GATEWAY_TIMEOUT); // Need better test that isInitial
else
{
- String uri=request.getRequestURI();
- if (request.getQueryString()!=null)
- uri+="?"+request.getQueryString();
+
+ String uri = request.getRequestURI();
+ if (request.getQueryString() != null)
+ uri += "?" + request.getQueryString();
- HttpURI url=proxyHttpURI(request.getScheme(),
- request.getServerName(),
- request.getServerPort(),
- uri);
+ HttpURI url = proxyHttpURI(request.getScheme(),request.getServerName(),request.getServerPort(),uri);
- if (debug!=0)
- _log.debug(debug+" proxy "+uri+"-->"+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:
* <ul>
* <li>ProxyTo - a URI like http://host:80/context to which the request is proxied.
* <li>Prefix - a URI prefix that is striped from the start of the forwarded URI.
* </ul>
- * For example, if a request was received at /foo/bar and the ProxyTo was http://host:80/context
- * and the Prefix was /foo, then the request would be proxied to http://host:80/context/bar
+ * 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 0000000000..b1e41f6a4c
--- /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 0000000000..3ad66eab23
--- /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 f4d0a94db7..4e2d6115f9 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 ba0fd87a93..2491493570 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 4622c6662a..0cec73d246 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<Object> _parent;
+ private final WeakReference<Object> _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<Object>(parent);
+ _child=new WeakReference<Object>(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 14004a62b1..ae3945f737 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("&nbsp;");
- buf.append("</TD><TD ALIGN=right>");
+ buf.append("</A></TD><TD ALIGN=right>");
buf.append(item.length());
buf.append(" bytes&nbsp;</TD><TD>");
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 c43167f127..8a85c29562 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 ac8866b62b..30f7062140 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<charsets.length;i++)
{
ByteArrayInputStream in = new ByteArrayInputStream("name\n=value+%30&name1=&name2&n\u00e3me3=value+3".getBytes(charsets[i][0]));
@@ -180,7 +199,28 @@ public class URLEncodedTest
}
else
assertTrue("Charset Shift_JIS not supported by jvm", true);
+
}
+
+
+ /* -------------------------------------------------------------- */
+ @Test
+ public void testCharsetViaSystemProperty ()
+ throws Exception
+ {
+ /*
+ * Uncomment to test setting a non-UTF-8 default character encoding using the SystemProperty org.eclipse.jetty.util.UrlEncoding.charset.
+ * You will also need to uncomment the static initializer that sets this SystemProperty near the top of this file.
+
+
+ ByteArrayInputStream in3 = new ByteArrayInputStream("name=libell%E9".getBytes(StringUtil.__ISO_8859_1));
+ MultiMap m3 = new MultiMap();
+ UrlEncoded.decodeTo(in3, m3, null, -1);
+ assertEquals("stream name", "libell\u00E9", m3.getString("name"));
+
+ */
+ }
+
/* -------------------------------------------------------------- */
@Test
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceTest.java
index fa37b30db3..49e0e467d7 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceTest.java
@@ -461,6 +461,7 @@ public class ResourceTest
@Test
public void testUncPathResourceFile() throws Exception
{
+ // This test is intended to run only on Windows platform
assumeTrue(OS.IS_WINDOWS);
String uncPath = "\\\\127.0.0.1"+__userURL.toURI().getPath().replace('/','\\').replace(':','$')+"ResourceTest.java";
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppClassLoader.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppClassLoader.java
index 6ecd7b1394..4e9a1c844f 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppClassLoader.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppClassLoader.java
@@ -316,10 +316,9 @@ public class WebAppClassLoader extends URLClassLoader
/* ------------------------------------------------------------ */
private List<URL> toList(Enumeration<URL> e)
{
- List<URL> list = new ArrayList<URL>();
- while (e!=null && e.hasMoreElements())
- list.add(e.nextElement());
- return list;
+ if (e==null)
+ return new ArrayList<URL>();
+ 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 a81223729f..ba6e4d7b89 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<String,String> _parameters=new HashMap<String, String>();
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)
- {
- 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;
- }
- public byte setFlag(byte flags,int flag)
+ public byte setFlag(byte flags,int rsv)
{
- return (byte)(flags | _bitMasks[flag]);
+ if (rsv<1||rsv>3)
+ throw new IllegalArgumentException("rsv"+rsv);
+ byte b=(byte)(flags | __mask[rsv]);
+ return b;
}
- public byte clearFlag(byte flags,int flag)
+ public byte clearFlag(byte flags,int rsv)
{
- return (byte)(flags & ~_bitMasks[flag]);
+ if (rsv<1||rsv>3)
+ throw new IllegalArgumentException("rsv"+rsv);
+ return (byte)(flags & ~__mask[rsv]);
}
- public 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 c8b5dd100c..68bf4f222d 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 2d725f5236..b3c93ec460 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<String,String> parameters);
- public void bind(WebSocket.FrameConnection connection, WebSocketParser.FrameHandler inbound, WebSocketGenerator outbound,byte[] dataOpCodes, byte[] controlOpcodes, byte[] bitMasks);
+ public void bind(WebSocket.FrameConnection connection, WebSocketParser.FrameHandler inbound, WebSocketGenerator outbound);
}
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 2321124908..106f718be5 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 4f2aeb9cf6..c8036c69d9 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 fc41fc0488..f865a93bd1 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
index da85e08593..12c3d91a85 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<Extension> _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<Extension> extensions)
+ public WebSocketConnectionD7_9(WebSocket websocket, EndPoint endpoint, WebSocketBuffers buffers, long timestamp, int maxIdleTime, String protocol, List<Extension> 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<data_ops.length;i++)
- data_ops[i]=data_op++;
- byte[] ctrl_ops=new byte[extension.getControlOpcodes()];
- for (int i=0;i<ctrl_ops.length;i++)
- ctrl_ops[i]=ctrl_op++;
- byte[] flag_masks=new byte[extension.getReservedBits()];
- for (int i=0;i<flag_masks.length;i++)
- {
- flag_masks[i]=flag_mask;
- flag_mask= (byte)(flag_mask>>1);
- }
-
extension.bind(
_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 ba37fc0294..d1cceda264 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
index 4cc6d3dd60..f6a12c90b6 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
index 896370592e..8b4f889aa1 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
index 1560bb44f2..0fe9eedd9a 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<b.length;i++)
@@ -118,7 +118,7 @@ public class WebSocketGeneratorD07Test
@Test
public void testOneStringMasked() throws Exception
{
- _generator = new WebSocketGeneratorD07(_buffers, _endPoint,_maskGen);
+ _generator = new WebSocketGeneratorD7_9(_buffers, _endPoint,_maskGen);
byte[] data = "Hell\uFF4F W\uFF4Frld".getBytes(StringUtil.__UTF8);
_generator.addFrame((byte)0x8,(byte)0x04,data,0,data.length);
@@ -147,7 +147,7 @@ public class WebSocketGeneratorD07Test
@Test
public void testOneBufferMasked() throws Exception
{
- _generator = new WebSocketGeneratorD07(_buffers, _endPoint,_maskGen);
+ _generator = new WebSocketGeneratorD7_9(_buffers, _endPoint,_maskGen);
String string = "Hell\uFF4F W\uFF4Frld";
byte[] bytes=string.getBytes(StringUtil.__UTF8);
@@ -177,7 +177,7 @@ public class WebSocketGeneratorD07Test
@Test
public void testOneLongBufferMasked() throws Exception
{
- _generator = new WebSocketGeneratorD07(_buffers, _endPoint,_maskGen);
+ _generator = new WebSocketGeneratorD7_9(_buffers, _endPoint,_maskGen);
byte[] b=new byte[150];
for (int i=0;i<b.length;i++)
diff --git a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketLoadD07Test.java b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketLoadD7_9Test.java
index c703f44ca8..7ad300e3d6 100644
--- a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketLoadD07Test.java
+++ b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketLoadD7_9Test.java
@@ -33,7 +33,7 @@ import org.junit.Test;
/**
* @version $Revision$ $Date$
*/
-public class WebSocketLoadD07Test
+public class WebSocketLoadD7_9Test
{
private static Server _server;
private static Connector _connector;
@@ -142,8 +142,8 @@ public class WebSocketLoadD07Test
private final int iterations;
private final CountDownLatch latch;
private final SocketEndPoint _endp;
- private final WebSocketGeneratorD07 _generator;
- private final WebSocketParserD07 _parser;
+ private final WebSocketGeneratorD7_9 _generator;
+ private final WebSocketParserD7_9 _parser;
private final WebSocketParser.FrameHandler _handler = new WebSocketParser.FrameHandler()
{
public void onFrame(byte flags, byte opcode, Buffer buffer)
@@ -167,8 +167,8 @@ public class WebSocketLoadD07Test
this.iterations = iterations;
_endp=new SocketEndPoint(socket);
- _generator = new WebSocketGeneratorD07(new WebSocketBuffers(32*1024),_endp,new WebSocketGeneratorD07.FixedMaskGen());
- _parser = new WebSocketParserD07(new WebSocketBuffers(32*1024),_endp,_handler,false);
+ _generator = new WebSocketGeneratorD7_9(new WebSocketBuffers(32*1024),_endp,new WebSocketGeneratorD7_9.FixedMaskGen());
+ _parser = new WebSocketParserD7_9(new WebSocketBuffers(32*1024),_endp,_handler,false);
}
@@ -202,7 +202,7 @@ public class WebSocketLoadD07Test
for (int i = 0; i < iterations; ++i)
{
byte[] data = message.getBytes(StringUtil.__UTF8);
- _generator.addFrame((byte)0x8,WebSocketConnectionD07.OP_TEXT,data,0,data.length);
+ _generator.addFrame((byte)0x8,WebSocketConnectionD7_9.OP_TEXT,data,0,data.length);
_generator.flush();
//System.err.println("-> "+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
index a38973bcbc..1c097edb92 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<String> received = new AtomicReference<String>();
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<String> received = new AtomicReference<String>();
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
index d3ce5fe003..2611715c24 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 799af9442a..fe5f18b492 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-parent</artifactId>
- <version>17</version>
+ <version>18</version>
</parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
@@ -23,13 +23,13 @@
<servlet.spec.artifactId>servlet-api</servlet.spec.artifactId>
<servlet.spec.version>3.0.20100224</servlet.spec.version>
<build-support-version>1.0</build-support-version>
- <jetty.test.helper>1.5</jetty.test.helper>
+ <jetty.test.helper>1.6</jetty.test.helper>
<jetty.test.policy>1.2</jetty.test.policy>
</properties>
<scm>
- <connection>scm:svn:http://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/branches/jetty-8</connection>
- <developerConnection>scm:svn:svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/branches/jetty-8</developerConnection>
- <url>http://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/branches/jetty-8</url>
+ <connection>scm:git:http://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.project.git</connection>
+ <developerConnection>scm:git:ssh://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.project.git</developerConnection>
+ <url>http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree</url>
</scm>
<build>
<defaultGoal>install</defaultGoal>
@@ -45,7 +45,6 @@
<plugin>
<artifactId>maven-release-plugin</artifactId>
<configuration>
- <tagBase>svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/tags</tagBase>
<autoVersionSubmodules>true</autoVersionSubmodules>
</configuration>
</plugin>
@@ -420,14 +419,10 @@
-->
<id>osgi</id>
<activation>
-
- <activeByDefault>false</activeByDefault>
- <!--
- <activeByDefault>true</activeByDefault>
+ <activeByDefault>true</activeByDefault>
<file>
<exists>${basedir}/pom.xml</exists>
</file>
- -->
</activation>
<modules>
<module>jetty-osgi</module>
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 edbcd5a4bd..c7b63308be 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
@@ -141,6 +141,23 @@ public class HttpTester
}
/* ------------------------------------------------------------ */
+ /**
+ * 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
{
_charset = _defaultCharset;
@@ -439,6 +456,16 @@ public class HttpTester
}
/* ------------------------------------------------------------ */
+ public byte[] getContentBytes()
+ {
+ if (_parsedContent!=null)
+ return _parsedContent.toByteArray();
+ if (_genContent!=null)
+ return _genContent;
+ return null;
+ }
+
+ /* ------------------------------------------------------------ */
public void setContent(String content)
{
_parsedContent=null;
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 e59c794887..fba961cda7 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("</tr><tr>\n");
pout.write("<th align=\"right\">Thread.currentThread().getContextClassLoader().getResource(...):&nbsp;</th>");
pout.write("<td>"+Thread.currentThread().getContextClassLoader().getResource(res)+"</td>");
+ pout.write("</tr><tr>\n");
+ pout.write("<th align=\"right\">Thread.currentThread().getContextClassLoader().getResources(...):&nbsp;</th>");
+ Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(res);
+ if (urls==null)
+ pout.write("<td>null</td>");
+ else
+ pout.write("<td>"+Collections.list(urls)+"</td>");
}
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 b7f219dd5b..d0efe95613 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 7f19c2f1b1..fd9e22ffc3 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 @@
<body>
<h1>Rewrite not enabled</h1>
<p>The rewrite handler is currently not enabled. To enable this demo, start up Jetty with:</p>
-<code>java -jar start.jar OPTIONS=default,rewrite etc/jetty.xml etc/jetty-rewrite.xml</code>
+<code>java -jar start.jar OPTIONS=rewrite etc/jetty-rewrite.xml</code>
</body>
</html>
diff --git a/test-jetty-webapp/src/main/webapp/rewrite/info.html b/test-jetty-webapp/src/main/webapp/rewrite/info.html
index 88e87b1406..f273b66586 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 @@
<h2>Internal URI rewrite</h2>
<dl>
-<dt><a href="/some/old/context">Rewrite "/some/old/context" to "/rewritten/newcontext"</a></dt>
+<dt><a href="../some/old/context">Rewrite "../some/old/context" to "../rewritten/newcontext"</a></dt>
<dd>This demo shows how the entire request URI can be internally rewritten to point to another context, using simple text matching</dd>
-<dt><a href="/rewrite/for/beginning">Rewrite "/rewrite/for/beginning" to "/rewritten/beginning"</a></dt>
+<dt><a href="../rewrite/for/beginning">Rewrite "../rewrite/for/beginning" to "../rewritten/beginning"</a></dt>
<dd>This demo shows how the beginning of the request URI can be rewritten, while keeping the ending section</dd>
-<dt><a href="/rewritten/reverse/bar/foo">Rewrite "bar/foo" to "foo/bar" using regex</a></dt>
+<dt><a href="../rewritten/reverse/bar/foo">Rewrite "bar/foo" to "foo/bar" using regex</a></dt>
<dd>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</dd>
-<dt><a href="/rewrite/for/reverse/bar/foo">Rewrite the beginning, and reverse the path sections</a></dt>
+<dt><a href="../rewrite/for/reverse/bar/foo">Rewrite the beginning, and reverse the path sections</a></dt>
<dd>This demo shows how rewrite patterns can be chained.</dd>
-<dt><a href="/dump/reverse/bar/foo">Rewrite "bar/foo" to "foo/bar", full dump view</a></dt>
+<dt><a href="../dump/reverse/bar/foo">Rewrite "bar/foo" to "foo/bar", full dump view</a></dt>
<dd>This demo rewrites "bar/foo" to "foo/bar" the same as earlier, but shows a full dump of the request</dd>
<h2>Redirect</h2>
-<dt><a href="/redirect/this">Redirect "/redirect/this" to "/redirected/this"</a></dt>
+<dt><a href="../redirect/this">Redirect "../redirect/this" to "../redirected/this"</a></dt>
<dd>This demo redirects the request in a manner visible to the user agent, instead of doing an internal rewrite.</dd>
<h2>Cookie</h2>
@@ -35,7 +35,7 @@
<dd>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".</dd>
<h2>Response Code</h2>
-<dt><a href="/400Error">Return a 400 error status</a></dt>
+<dt><a href="../400Error">Return a 400 error status</a></dt>
<dd>This demo shows how to modify the response code of a page to an error, based on its URL</dd>
</dl>
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 0000000000..3dcfdb05c1
--- /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";
+ }
+ }
+
+}

Back to the top