Merge of jetty-7 into jetty-8

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

View File

@ -1,3 +1,6 @@
jetty-8.0.0.RC0
+ Merge from jetty-7.4.3
jetty-8.0.0.M3
+ 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

View File

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

View File

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

View File

@ -0,0 +1,126 @@
// ========================================================================
// Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.embedded;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.zip.GZIPInputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.GzipHandler;
import org.eclipse.jetty.testing.HttpTester;
import org.eclipse.jetty.util.IO;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class GzipHandlerTest
{
private static String __content =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis felis nunc. "+
"Quisque suscipit mauris et ante auctor ornare rhoncus lacus aliquet. Pellentesque "+
"habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. "+
"Vestibulum sit amet felis augue, vel convallis dolor. Cras accumsan vehicula diam "+
"at faucibus. Etiam in urna turpis, sed congue mi. Morbi et lorem eros. Donec vulputate "+
"velit in risus suscipit lobortis. Aliquam id urna orci, nec sollicitudin ipsum. "+
"Cras a orci turpis. Donec suscipit vulputate cursus. Mauris nunc tellus, fermentum "+
"eu auctor ut, mollis at diam. Quisque porttitor ultrices metus, vitae tincidunt massa "+
"sollicitudin a. Vivamus porttitor libero eget purus hendrerit cursus. Integer aliquam "+
"consequat mauris quis luctus. Cras enim nibh, dignissim eu faucibus ac, mollis nec neque. "+
"Aliquam purus mauris, consectetur nec convallis lacinia, porta sed ante. Suspendisse "+
"et cursus magna. Donec orci enim, molestie a lobortis eu, imperdiet vitae neque.";
private Server _server;
private LocalConnector _connector;
@Before
public void init() throws Exception
{
_server = new Server();
_connector = new LocalConnector();
_server.addConnector(_connector);
Handler testHandler = new AbstractHandler()
{
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException,
ServletException
{
PrintWriter writer = response.getWriter();
writer.write(__content);
writer.close();
baseRequest.setHandled(true);
}
};
GzipHandler gzipHandler = new GzipHandler();
gzipHandler.setHandler(testHandler);
_server.setHandler(gzipHandler);
_server.start();
}
@After
public void destroy() throws Exception
{
_server.stop();
_server.join();
}
@Test
public void testGzipHandler() throws Exception
{
// generated and parsed test
HttpTester request = new HttpTester();
HttpTester response = new HttpTester();
request.setMethod("GET");
request.setVersion("HTTP/1.0");
request.setHeader("Host","tester");
request.setHeader("accept-encoding","gzip");
request.setURI("/");
ByteArrayBuffer reqsBuff = new ByteArrayBuffer(request.generate().getBytes());
ByteArrayBuffer respBuff = _connector.getResponses(reqsBuff, false);
response.parse(respBuff.asArray());
assertTrue(response.getMethod()==null);
assertTrue(response.getHeader("Content-Encoding").equalsIgnoreCase("gzip"));
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes()));
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
IO.copy(testIn,testOut);
assertEquals(__content, testOut.toString("UTF8"));
}
}

BIN
icon.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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,18 +217,19 @@ public class WebSocketUpgradeTest extends TestCase
_port=_connector.getLocalPort();
}
/* ------------------------------------------------------------ */
private void stopServer() throws Exception
{
_server.stop();
_server.join();
}
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
class TestWebSocket implements WebSocket.OnTextMessage
{
Connection _connection;
/* ------------------------------------------------------------ */
public void onOpen(Connection connection)
{
_connection=connection;
@ -223,18 +238,21 @@ public class WebSocketUpgradeTest extends TestCase
_results.add(this);
}
/* ------------------------------------------------------------ */
public void onMessage(final String data)
{
_results.add("serverWS.onMessage");
_results.add(data);
}
/* ------------------------------------------------------------ */
public void onClose(int code, String message)
{
_results.add("onDisconnect");
_webSockets.remove(this);
}
/* ------------------------------------------------------------ */
public void sendMessage(String msg) throws IOException
{
_connection.sendMessage(msg);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -17,6 +17,12 @@
<artifactId>jetty-io</artifactId>
<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>

View File

@ -0,0 +1,394 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.http.gzip;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.Set;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.eclipse.jetty.util.StringUtil;
/* ------------------------------------------------------------ */
/**
*/
public class GzipResponseWrapper extends HttpServletResponseWrapper
{
private HttpServletRequest _request;
private Set<String> _mimeTypes;
private int _bufferSize=8192;
private int _minGzipSize=256;
private PrintWriter _writer;
private GzipStream _gzStream;
private long _contentLength=-1;
private boolean _noGzip;
/**
* Instantiates a new gzip response wrapper.
*
* @param request the request
* @param response the response
*/
public GzipResponseWrapper(HttpServletRequest request, HttpServletResponse response)
{
super(response);
_request=request;
}
/* ------------------------------------------------------------ */
/**
* Sets the mime types.
*
* @param mimeTypes the new mime types
*/
public void setMimeTypes(Set<String> mimeTypes)
{
_mimeTypes = mimeTypes;
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.ServletResponseWrapper#setBufferSize(int)
*/
public void setBufferSize(int bufferSize)
{
_bufferSize = bufferSize;
}
/* ------------------------------------------------------------ */
/**
* Sets the min gzip size.
*
* @param minGzipSize the new min gzip size
*/
public void setMinGzipSize(int minGzipSize)
{
_minGzipSize = minGzipSize;
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.ServletResponseWrapper#setContentType(java.lang.String)
*/
public void setContentType(String ct)
{
super.setContentType(ct);
if (ct!=null)
{
int colon=ct.indexOf(";");
if (colon>0)
ct=ct.substring(0,colon);
}
if ((_gzStream==null || _gzStream._out==null) &&
(_mimeTypes==null && "application/gzip".equalsIgnoreCase(ct) ||
_mimeTypes!=null && (ct==null||!_mimeTypes.contains(StringUtil.asciiToLowerCase(ct)))))
{
noGzip();
}
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.http.HttpServletResponseWrapper#setStatus(int, java.lang.String)
*/
public void setStatus(int sc, String sm)
{
super.setStatus(sc,sm);
if (sc<200||sc>=300)
noGzip();
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.http.HttpServletResponseWrapper#setStatus(int)
*/
public void setStatus(int sc)
{
super.setStatus(sc);
if (sc<200||sc>=300)
noGzip();
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.ServletResponseWrapper#setContentLength(int)
*/
public void setContentLength(int length)
{
_contentLength=length;
if (_gzStream!=null)
_gzStream.setContentLength(length);
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.http.HttpServletResponseWrapper#addHeader(java.lang.String, java.lang.String)
*/
public void addHeader(String name, String value)
{
if ("content-length".equalsIgnoreCase(name))
{
_contentLength=Long.parseLong(value);
if (_gzStream!=null)
_gzStream.setContentLength(_contentLength);
}
else if ("content-type".equalsIgnoreCase(name))
{
setContentType(value);
}
else if ("content-encoding".equalsIgnoreCase(name))
{
super.addHeader(name,value);
if (!isCommitted())
{
noGzip();
}
}
else
super.addHeader(name,value);
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.http.HttpServletResponseWrapper#setHeader(java.lang.String, java.lang.String)
*/
public void setHeader(String name, String value)
{
if ("content-length".equalsIgnoreCase(name))
{
_contentLength=Long.parseLong(value);
if (_gzStream!=null)
_gzStream.setContentLength(_contentLength);
}
else if ("content-type".equalsIgnoreCase(name))
{
setContentType(value);
}
else if ("content-encoding".equalsIgnoreCase(name))
{
super.setHeader(name,value);
if (!isCommitted())
{
noGzip();
}
}
else
super.setHeader(name,value);
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.http.HttpServletResponseWrapper#setIntHeader(java.lang.String, int)
*/
public void setIntHeader(String name, int value)
{
if ("content-length".equalsIgnoreCase(name))
{
_contentLength=value;
if (_gzStream!=null)
_gzStream.setContentLength(_contentLength);
}
else
super.setIntHeader(name,value);
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.ServletResponseWrapper#flushBuffer()
*/
public void flushBuffer() throws IOException
{
if (_writer!=null)
_writer.flush();
if (_gzStream!=null)
_gzStream.finish();
else
getResponse().flushBuffer();
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.ServletResponseWrapper#reset()
*/
public void reset()
{
super.reset();
if (_gzStream!=null)
_gzStream.resetBuffer();
_writer=null;
_gzStream=null;
_noGzip=false;
_contentLength=-1;
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.ServletResponseWrapper#resetBuffer()
*/
public void resetBuffer()
{
super.resetBuffer();
if (_gzStream!=null)
_gzStream.resetBuffer();
_writer=null;
_gzStream=null;
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.http.HttpServletResponseWrapper#sendError(int, java.lang.String)
*/
public void sendError(int sc, String msg) throws IOException
{
resetBuffer();
super.sendError(sc,msg);
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.http.HttpServletResponseWrapper#sendError(int)
*/
public void sendError(int sc) throws IOException
{
resetBuffer();
super.sendError(sc);
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.http.HttpServletResponseWrapper#sendRedirect(java.lang.String)
*/
public void sendRedirect(String location) throws IOException
{
resetBuffer();
super.sendRedirect(location);
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.ServletResponseWrapper#getOutputStream()
*/
public ServletOutputStream getOutputStream() throws IOException
{
if (_gzStream==null)
{
if (getResponse().isCommitted() || _noGzip)
return getResponse().getOutputStream();
_gzStream=newGzipStream(_request,(HttpServletResponse)getResponse(),_contentLength,_bufferSize,_minGzipSize);
}
else if (_writer!=null)
throw new IllegalStateException("getWriter() called");
return _gzStream;
}
/* ------------------------------------------------------------ */
/**
* @see javax.servlet.ServletResponseWrapper#getWriter()
*/
public PrintWriter getWriter() throws IOException
{
if (_writer==null)
{
if (_gzStream!=null)
throw new IllegalStateException("getOutputStream() called");
if (getResponse().isCommitted() || _noGzip)
return getResponse().getWriter();
_gzStream=newGzipStream(_request,(HttpServletResponse)getResponse(),_contentLength,_bufferSize,_minGzipSize);
_writer=newWriter(_gzStream,getCharacterEncoding());
}
return _writer;
}
/* ------------------------------------------------------------ */
/**
* No gzip.
*/
public void noGzip()
{
_noGzip=true;
if (_gzStream!=null)
{
try
{
_gzStream.doNotGzip();
}
catch (IOException e)
{
throw new IllegalStateException(e);
}
}
}
/* ------------------------------------------------------------ */
/**
* Finish.
*
* @throws IOException Signals that an I/O exception has occurred.
*/
public void finish() throws IOException
{
if (_writer!=null && !_gzStream._closed)
_writer.flush();
if (_gzStream!=null)
_gzStream.finish();
}
/* ------------------------------------------------------------ */
/**
* Allows derived implementations to replace GzipStream implementation.
*
* @param request the request
* @param response the response
* @param contentLength the content length
* @param bufferSize the buffer size
* @param minGzipSize the min gzip size
* @return the gzip stream
* @throws IOException Signals that an I/O exception has occurred.
*/
protected GzipStream newGzipStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minGzipSize) throws IOException
{
return new GzipStream(request,response,contentLength,bufferSize,minGzipSize);
}
/* ------------------------------------------------------------ */
/**
* Allows derived implementations to replace PrintWriter implementation.
*
* @param out the out
* @param encoding the encoding
* @return the prints the writer
* @throws UnsupportedEncodingException the unsupported encoding exception
*/
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
{
return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
}
}

View File

@ -0,0 +1,300 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.http.gzip;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.util.ByteArrayOutputStream2;
/* ------------------------------------------------------------ */
/**
*/
public class GzipStream extends ServletOutputStream
{
protected HttpServletRequest _request;
protected HttpServletResponse _response;
protected OutputStream _out;
protected ByteArrayOutputStream2 _bOut;
protected GZIPOutputStream _gzOut;
protected boolean _closed;
protected int _bufferSize;
protected int _minGzipSize;
protected long _contentLength;
/**
* Instantiates a new gzip stream.
*
* @param request the request
* @param response the response
* @param contentLength the content length
* @param bufferSize the buffer size
* @param minGzipSize the min gzip size
* @throws IOException Signals that an I/O exception has occurred.
*/
public GzipStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minGzipSize) throws IOException
{
_request=request;
_response=response;
_contentLength=contentLength;
_bufferSize=bufferSize;
_minGzipSize=minGzipSize;
if (minGzipSize==0)
doGzip();
}
/**
* Reset buffer.
*/
public void resetBuffer()
{
if (_response.isCommitted())
throw new IllegalStateException("Committed");
_closed=false;
_out=null;
_bOut=null;
if (_gzOut!=null)
_response.setHeader("Content-Encoding",null);
_gzOut=null;
}
/**
* Sets the content length.
*
* @param length the new content length
*/
public void setContentLength(long length)
{
_contentLength=length;
}
/* ------------------------------------------------------------ */
/**
* @see java.io.OutputStream#flush()
*/
public void flush() throws IOException
{
if (_out==null || _bOut!=null)
{
if (_contentLength>0 && _contentLength<_minGzipSize)
doNotGzip();
else
doGzip();
}
_out.flush();
}
/* ------------------------------------------------------------ */
/**
* @see java.io.OutputStream#close()
*/
public void close() throws IOException
{
if (_closed)
return;
if (_request.getAttribute("javax.servlet.include.request_uri")!=null)
flush();
else
{
if (_bOut!=null)
{
if (_contentLength<0)
_contentLength=_bOut.getCount();
if (_contentLength<_minGzipSize)
doNotGzip();
else
doGzip();
}
else if (_out==null)
{
doNotGzip();
}
if (_gzOut!=null)
_gzOut.close();
else
_out.close();
_closed=true;
}
}
/**
* Finish.
*
* @throws IOException Signals that an I/O exception has occurred.
*/
public void finish() throws IOException
{
if (!_closed)
{
if (_out==null || _bOut!=null)
{
if (_contentLength>0 && _contentLength<_minGzipSize)
doNotGzip();
else
doGzip();
}
if (_gzOut!=null && !_closed)
{
_closed=true;
_gzOut.close();
}
}
}
/* ------------------------------------------------------------ */
/**
* @see java.io.OutputStream#write(int)
*/
public void write(int b) throws IOException
{
checkOut(1);
_out.write(b);
}
/* ------------------------------------------------------------ */
/**
* @see java.io.OutputStream#write(byte[])
*/
public void write(byte b[]) throws IOException
{
checkOut(b.length);
_out.write(b);
}
/* ------------------------------------------------------------ */
/**
* @see java.io.OutputStream#write(byte[], int, int)
*/
public void write(byte b[], int off, int len) throws IOException
{
checkOut(len);
_out.write(b,off,len);
}
/**
* Sets the content encoding gzip.
*
* @return true, if successful
*/
protected boolean setContentEncodingGzip()
{
_response.setHeader("Content-Encoding", "gzip");
return _response.containsHeader("Content-Encoding");
}
/**
* Do gzip.
*
* @throws IOException Signals that an I/O exception has occurred.
*/
public void doGzip() throws IOException
{
if (_gzOut==null)
{
if (_response.isCommitted())
throw new IllegalStateException();
if (setContentEncodingGzip())
{
_out=_gzOut=new GZIPOutputStream(_response.getOutputStream(),_bufferSize);
if (_bOut!=null)
{
_out.write(_bOut.getBuf(),0,_bOut.getCount());
_bOut=null;
}
}
else
doNotGzip();
}
}
/**
* Do not gzip.
*
* @throws IOException Signals that an I/O exception has occurred.
*/
public void doNotGzip() throws IOException
{
if (_gzOut!=null)
throw new IllegalStateException();
if (_out==null || _bOut!=null )
{
_out=_response.getOutputStream();
if (_contentLength>=0)
{
if(_contentLength<Integer.MAX_VALUE)
_response.setContentLength((int)_contentLength);
else
_response.setHeader("Content-Length",Long.toString(_contentLength));
}
if (_bOut!=null)
_out.write(_bOut.getBuf(),0,_bOut.getCount());
_bOut=null;
}
}
/**
* Check out.
*
* @param length the length
* @throws IOException Signals that an I/O exception has occurred.
*/
private void checkOut(int length) throws IOException
{
if (_closed)
throw new IOException("CLOSED");
if (_out==null)
{
if (_response.isCommitted() || (_contentLength>=0 && _contentLength<_minGzipSize))
doNotGzip();
else if (length>_minGzipSize)
doGzip();
else
_out=_bOut=new ByteArrayOutputStream2(_bufferSize);
}
else if (_bOut!=null)
{
if (_response.isCommitted() || (_contentLength>=0 && _contentLength<_minGzipSize))
doNotGzip();
else if (length>=(_bOut.getBuf().length -_bOut.getCount()))
doGzip();
}
}
/**
* Allows derived implementations to replace PrintWriter implementation.
*/
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
{
return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
}
}

View File

@ -169,13 +169,13 @@ public interface EndPoint
* the {@link java.net.Socket#getSoTimeout()} for blocking connections,
* 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;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -16,6 +16,19 @@ Import-Package: javax.mail;version="1.4.0";resolution:=optional,
javax.transaction.xa;version="1.1.0";resolution:=optional,
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)"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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;
@ -56,6 +57,13 @@ public class RewritePatternRule extends PatternRule
return target;
}
/* ------------------------------------------------------------ */
public void applyURI(Request request, String oldTarget, String newTarget) throws IOException
{
String uri = URIUtil.addPaths(_replacement, PathMap.pathInfo(_pattern,request.getRequestURI()));
request.setRequestURI(uri);
}
/* ------------------------------------------------------------ */
/**
* Returns the replacement string.

View File

@ -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;
@ -61,6 +63,25 @@ public class RewriteRegexRule extends RegexRule
return target;
}
/* ------------------------------------------------------------ */
public void applyURI(Request request, String oldTarget, String newTarget) throws IOException
{
Matcher matcher=_regex.matcher(request.getRequestURI());
boolean matches = matcher.matches();
if (matches)
{
String uri=_replacement;
for (int g=1;g<=matcher.groupCount();g++)
{
String group = matcher.group(g);
uri=uri.replaceAll("\\$"+g,group);
}
request.setRequestURI(uri);
}
else
request.setRequestURI(newTarget);
}
/* ------------------------------------------------------------ */
/**
* Returns the replacement string.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -102,17 +102,6 @@ public class SelectChannelConnector extends AbstractNIOConnector
{
synchronized(this)
{
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();
}

View File

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

View File

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

View File

@ -0,0 +1,29 @@
// ========================================================================
// Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server;
import org.eclipse.jetty.server.nio.BlockingChannelConnector;
import org.junit.BeforeClass;
/**
* HttpServer Tester.
*/
public class BlockingChannelCloseTest extends HttpServerTestBase
{
@BeforeClass
public static void init() throws Exception
{
startServer(new BlockingChannelConnector());
}
}

View File

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

View File

@ -67,6 +67,7 @@ public class HttpURITest
/*29*/ {"/?x=y",null, null, null,null,"/", null,"x=y",null},
/*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

View File

@ -348,6 +348,21 @@ public class ResponseTest
assertEquals("http://other:8888/path/info;param?query=0&more=1#target",response.encodeURL("http://other:8888/path/info;param?query=0&more=1#target"));
assertEquals("http://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

View File

@ -0,0 +1,31 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.junit.Before;
/* ------------------------------------------------------------ */
public class SelectChannelConnectorCloseTest extends ConnectorCloseTestBase
{
/* ------------------------------------------------------------ */
@Before
public void init() throws Exception
{
System.setProperty("org.eclipse.jetty.util.log.DEBUG","true");
startServer(new SelectChannelConnector());
}
}

View File

@ -0,0 +1,31 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server;
import org.eclipse.jetty.server.bio.SocketConnector;
import org.junit.Before;
/* ------------------------------------------------------------ */
public class SocketConnectorCloseTest extends ConnectorCloseTestBase
{
/* ------------------------------------------------------------ */
@Before
public void init() throws Exception
{
System.setProperty("org.eclipse.jetty.util.log.DEBUG","true");
startServer(new SocketConnector());
}
}

View File

@ -117,7 +117,8 @@ public class StressTest
@Test
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())

View File

@ -53,6 +53,11 @@
<artifactId>junit</artifactId>
<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>

View File

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

View File

@ -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)
/**
* Allows derived implementations to replace ResponseWrapper implementation.
*
* @param request the request
* @param response the response
* @return the gzip response wrapper
*/
protected GzipResponseWrapper newGzipResponseWrapper(HttpServletRequest request, HttpServletResponse response)
{
return new GZIPResponseWrapper(request,response);
return new GzipResponseWrapper(request, response)
{
{
_mimeTypes = GzipFilter.this._mimeTypes;
_bufferSize = GzipFilter.this._bufferSize;
_minGzipSize = GzipFilter.this._minGzipSize;
}
@Override
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
{
return GzipFilter.this.newWriter(out,encoding);
}
};
}
/*
* Allows derived implementations to replace PrintWriter implementation
/**
* Allows derived implementations to replace PrintWriter implementation.
*
* @param out the out
* @param encoding the encoding
* @return the prints the writer
* @throws UnsupportedEncodingException
*/
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
{
return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
}
public class GZIPResponseWrapper extends HttpServletResponseWrapper
{
HttpServletRequest _request;
boolean _noGzip;
PrintWriter _writer;
GzipStream _gzStream;
long _contentLength=-1;
public GZIPResponseWrapper(HttpServletRequest request, HttpServletResponse response)
{
super(response);
_request=request;
}
public void setContentType(String ct)
{
super.setContentType(ct);
if (ct!=null)
{
int colon=ct.indexOf(";");
if (colon>0)
ct=ct.substring(0,colon);
}
if ((_gzStream==null || _gzStream._out==null) &&
(_mimeTypes==null && "application/gzip".equalsIgnoreCase(ct) ||
_mimeTypes!=null && (ct==null||!_mimeTypes.contains(StringUtil.asciiToLowerCase(ct)))))
{
noGzip();
}
}
public void setStatus(int sc, String sm)
{
super.setStatus(sc,sm);
if (sc<200||sc>=300)
noGzip();
}
public void setStatus(int sc)
{
super.setStatus(sc);
if (sc<200||sc>=300)
noGzip();
}
public void setContentLength(int length)
{
_contentLength=length;
if (_gzStream!=null)
_gzStream.setContentLength(length);
}
public void addHeader(String name, String value)
{
if ("content-length".equalsIgnoreCase(name))
{
_contentLength=Long.parseLong(value);
if (_gzStream!=null)
_gzStream.setContentLength(_contentLength);
}
else if ("content-type".equalsIgnoreCase(name))
{
setContentType(value);
}
else if ("content-encoding".equalsIgnoreCase(name))
{
super.addHeader(name,value);
if (!isCommitted())
{
noGzip();
}
}
else
super.addHeader(name,value);
}
public void setHeader(String name, String value)
{
if ("content-length".equalsIgnoreCase(name))
{
_contentLength=Long.parseLong(value);
if (_gzStream!=null)
_gzStream.setContentLength(_contentLength);
}
else if ("content-type".equalsIgnoreCase(name))
{
setContentType(value);
}
else if ("content-encoding".equalsIgnoreCase(name))
{
super.setHeader(name,value);
if (!isCommitted())
{
noGzip();
}
}
else
super.setHeader(name,value);
}
public void setIntHeader(String name, int value)
{
if ("content-length".equalsIgnoreCase(name))
{
_contentLength=value;
if (_gzStream!=null)
_gzStream.setContentLength(_contentLength);
}
else
super.setIntHeader(name,value);
}
public void flushBuffer() throws IOException
{
if (_writer!=null)
_writer.flush();
if (_gzStream!=null)
_gzStream.finish();
else
getResponse().flushBuffer();
}
public void reset()
{
super.reset();
if (_gzStream!=null)
_gzStream.resetBuffer();
_writer=null;
_gzStream=null;
_noGzip=false;
_contentLength=-1;
}
public void resetBuffer()
{
super.resetBuffer();
if (_gzStream!=null)
_gzStream.resetBuffer();
_writer=null;
_gzStream=null;
}
public void sendError(int sc, String msg) throws IOException
{
resetBuffer();
super.sendError(sc,msg);
}
public void sendError(int sc) throws IOException
{
resetBuffer();
super.sendError(sc);
}
public void sendRedirect(String location) throws IOException
{
resetBuffer();
super.sendRedirect(location);
}
public ServletOutputStream getOutputStream() throws IOException
{
if (_gzStream==null)
{
if (getResponse().isCommitted() || _noGzip)
return getResponse().getOutputStream();
_gzStream=newGzipStream(_request,(HttpServletResponse)getResponse(),_contentLength,_bufferSize,_minGzipSize);
}
else if (_writer!=null)
throw new IllegalStateException("getWriter() called");
return _gzStream;
}
public PrintWriter getWriter() throws IOException
{
if (_writer==null)
{
if (_gzStream!=null)
throw new IllegalStateException("getOutputStream() called");
if (getResponse().isCommitted() || _noGzip)
return getResponse().getWriter();
_gzStream=newGzipStream(_request,(HttpServletResponse)getResponse(),_contentLength,_bufferSize,_minGzipSize);
_writer=newWriter(_gzStream,getCharacterEncoding());
}
return _writer;
}
void noGzip()
{
_noGzip=true;
if (_gzStream!=null)
{
try
{
_gzStream.doNotGzip();
}
catch (IOException e)
{
throw new IllegalStateException(e);
}
}
}
void finish() throws IOException
{
if (_writer!=null && !_gzStream._closed)
_writer.flush();
if (_gzStream!=null)
_gzStream.finish();
}
protected GzipStream newGzipStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minGzipSize) throws IOException
{
return new GzipStream(request,response,contentLength,bufferSize,minGzipSize);
}
}
public static class GzipStream extends ServletOutputStream
{
protected HttpServletRequest _request;
protected HttpServletResponse _response;
protected OutputStream _out;
protected ByteArrayOutputStream2 _bOut;
protected GZIPOutputStream _gzOut;
protected boolean _closed;
protected int _bufferSize;
protected int _minGzipSize;
protected long _contentLength;
public GzipStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minGzipSize) throws IOException
{
_request=request;
_response=response;
_contentLength=contentLength;
_bufferSize=bufferSize;
_minGzipSize=minGzipSize;
if (minGzipSize==0)
doGzip();
}
public void resetBuffer()
{
if (_response.isCommitted())
throw new IllegalStateException("Committed");
_closed=false;
_out=null;
_bOut=null;
if (_gzOut!=null)
_response.setHeader("Content-Encoding",null);
_gzOut=null;
}
public void setContentLength(long length)
{
_contentLength=length;
}
public void flush() throws IOException
{
if (_out==null || _bOut!=null)
{
if (_contentLength>0 && _contentLength<_minGzipSize)
doNotGzip();
else
doGzip();
}
_out.flush();
}
public void close() throws IOException
{
if (_closed)
return;
if (_request.getAttribute("javax.servlet.include.request_uri")!=null)
flush();
else
{
if (_bOut!=null)
{
if (_contentLength<0)
_contentLength=_bOut.getCount();
if (_contentLength<_minGzipSize)
doNotGzip();
else
doGzip();
}
else if (_out==null)
{
doNotGzip();
}
if (_gzOut!=null)
_gzOut.close();
else
_out.close();
_closed=true;
}
}
public void finish() throws IOException
{
if (!_closed)
{
if (_out==null || _bOut!=null)
{
if (_contentLength>0 && _contentLength<_minGzipSize)
doNotGzip();
else
doGzip();
}
if (_gzOut!=null && !_closed)
{
_closed=true;
_gzOut.close();
}
}
}
public void write(int b) throws IOException
{
checkOut(1);
_out.write(b);
}
public void write(byte b[]) throws IOException
{
checkOut(b.length);
_out.write(b);
}
public void write(byte b[], int off, int len) throws IOException
{
checkOut(len);
_out.write(b,off,len);
}
protected boolean setContentEncodingGzip()
{
_response.setHeader("Content-Encoding", "gzip");
return _response.containsHeader("Content-Encoding");
}
public void doGzip() throws IOException
{
if (_gzOut==null)
{
if (_response.isCommitted())
throw new IllegalStateException();
if (setContentEncodingGzip())
{
_out=_gzOut=new GZIPOutputStream(_response.getOutputStream(),_bufferSize);
if (_bOut!=null)
{
_out.write(_bOut.getBuf(),0,_bOut.getCount());
_bOut=null;
}
}
else
doNotGzip();
}
}
public void doNotGzip() throws IOException
{
if (_gzOut!=null)
throw new IllegalStateException();
if (_out==null || _bOut!=null )
{
_out=_response.getOutputStream();
if (_contentLength>=0)
{
if(_contentLength<Integer.MAX_VALUE)
_response.setContentLength((int)_contentLength);
else
_response.setHeader("Content-Length",Long.toString(_contentLength));
}
if (_bOut!=null)
_out.write(_bOut.getBuf(),0,_bOut.getCount());
_bOut=null;
}
}
private void checkOut(int length) throws IOException
{
if (_closed)
throw new IOException("CLOSED");
if (_out==null)
{
if (_response.isCommitted() || (_contentLength>=0 && _contentLength<_minGzipSize))
doNotGzip();
else if (length>_minGzipSize)
doGzip();
else
_out=_bOut=new ByteArrayOutputStream2(_bufferSize);
}
else if (_bOut!=null)
{
if (_response.isCommitted() || (_contentLength>=0 && _contentLength<_minGzipSize))
doNotGzip();
else if (length>=(_bOut.getBuf().length -_bOut.getCount()))
doGzip();
}
}
}
}

View File

@ -24,6 +24,8 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.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
{

View File

@ -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());
_log = createLogger(config);
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));
_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

View File

@ -0,0 +1,115 @@
// ========================================================================
// Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.servlets;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.testing.HttpTester;
import org.eclipse.jetty.testing.ServletTester;
import org.eclipse.jetty.toolchain.test.TestingDir;
import org.eclipse.jetty.util.IO;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
public class GzipFilterTest
{
private static String __content =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis felis nunc. "+
"Quisque suscipit mauris et ante auctor ornare rhoncus lacus aliquet. Pellentesque "+
"habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. "+
"Vestibulum sit amet felis augue, vel convallis dolor. Cras accumsan vehicula diam "+
"at faucibus. Etiam in urna turpis, sed congue mi. Morbi et lorem eros. Donec vulputate "+
"velit in risus suscipit lobortis. Aliquam id urna orci, nec sollicitudin ipsum. "+
"Cras a orci turpis. Donec suscipit vulputate cursus. Mauris nunc tellus, fermentum "+
"eu auctor ut, mollis at diam. Quisque porttitor ultrices metus, vitae tincidunt massa "+
"sollicitudin a. Vivamus porttitor libero eget purus hendrerit cursus. Integer aliquam "+
"consequat mauris quis luctus. Cras enim nibh, dignissim eu faucibus ac, mollis nec neque. "+
"Aliquam purus mauris, consectetur nec convallis lacinia, porta sed ante. Suspendisse "+
"et cursus magna. Donec orci enim, molestie a lobortis eu, imperdiet vitae neque.";
@Rule
public TestingDir testdir = new TestingDir();
private ServletTester tester;
@Before
public void setUp() throws Exception
{
testdir.ensureEmpty();
File testFile = testdir.getFile("file.txt");
BufferedOutputStream testOut = new BufferedOutputStream(new FileOutputStream(testFile));
ByteArrayInputStream testIn = new ByteArrayInputStream(__content.getBytes("ISO8859_1"));
IO.copy(testIn,testOut);
testOut.close();
tester=new ServletTester();
tester.setContextPath("/context");
tester.setResourceBase(testdir.getDir().getCanonicalPath());
tester.addServlet(org.eclipse.jetty.servlet.DefaultServlet.class, "/");
FilterHolder holder = tester.addFilter(GzipFilter.class,"/*",null);
holder.setInitParameter("mimeTypes","text/plain");
tester.start();
}
@After
public void tearDown() throws Exception
{
tester.stop();
IO.delete(testdir.getDir());
}
@Test
public void testGzipFilter() throws Exception
{
// generated and parsed test
HttpTester request = new HttpTester();
HttpTester response = new HttpTester();
request.setMethod("GET");
request.setVersion("HTTP/1.0");
request.setHeader("Host","tester");
request.setHeader("accept-encoding","gzip");
request.setURI("/context/file.txt");
ByteArrayBuffer reqsBuff = new ByteArrayBuffer(request.generate().getBytes());
ByteArrayBuffer respBuff = tester.getResponses(reqsBuff);
response.parse(respBuff.asArray());
assertTrue(response.getMethod()==null);
assertTrue(response.getHeader("Content-Encoding").equalsIgnoreCase("gzip"));
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes()));
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
IO.copy(testIn,testOut);
assertEquals(__content, testOut.toString("ISO8859_1"));
}
}

View File

@ -0,0 +1,115 @@
// ========================================================================
// Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.servlets;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.testing.HttpTester;
import org.eclipse.jetty.testing.ServletTester;
import org.eclipse.jetty.toolchain.test.TestingDir;
import org.eclipse.jetty.util.IO;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
public class IncludableGzipFilterTest
{
private static String __content =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis felis nunc. "+
"Quisque suscipit mauris et ante auctor ornare rhoncus lacus aliquet. Pellentesque "+
"habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. "+
"Vestibulum sit amet felis augue, vel convallis dolor. Cras accumsan vehicula diam "+
"at faucibus. Etiam in urna turpis, sed congue mi. Morbi et lorem eros. Donec vulputate "+
"velit in risus suscipit lobortis. Aliquam id urna orci, nec sollicitudin ipsum. "+
"Cras a orci turpis. Donec suscipit vulputate cursus. Mauris nunc tellus, fermentum "+
"eu auctor ut, mollis at diam. Quisque porttitor ultrices metus, vitae tincidunt massa "+
"sollicitudin a. Vivamus porttitor libero eget purus hendrerit cursus. Integer aliquam "+
"consequat mauris quis luctus. Cras enim nibh, dignissim eu faucibus ac, mollis nec neque. "+
"Aliquam purus mauris, consectetur nec convallis lacinia, porta sed ante. Suspendisse "+
"et cursus magna. Donec orci enim, molestie a lobortis eu, imperdiet vitae neque.";
@Rule
public TestingDir testdir = new TestingDir();
private ServletTester tester;
@Before
public void setUp() throws Exception
{
testdir.ensureEmpty();
File testFile = testdir.getFile("file.txt");
BufferedOutputStream testOut = new BufferedOutputStream(new FileOutputStream(testFile));
ByteArrayInputStream testIn = new ByteArrayInputStream(__content.getBytes("ISO8859_1"));
IO.copy(testIn,testOut);
testOut.close();
tester=new ServletTester();
tester.setContextPath("/context");
tester.setResourceBase(testdir.getDir().getCanonicalPath());
tester.addServlet(org.eclipse.jetty.servlet.DefaultServlet.class, "/");
FilterHolder holder = tester.addFilter(IncludableGzipFilter.class,"/*",null);
holder.setInitParameter("mimeTypes","text/plain");
tester.start();
}
@After
public void tearDown() throws Exception
{
tester.stop();
IO.delete(testdir.getDir());
}
@Test
public void testGzipFilter() throws Exception
{
// generated and parsed test
HttpTester request = new HttpTester();
HttpTester response = new HttpTester();
request.setMethod("GET");
request.setVersion("HTTP/1.0");
request.setHeader("Host","tester");
request.setHeader("accept-encoding","gzip");
request.setURI("/context/file.txt");
ByteArrayBuffer reqsBuff = new ByteArrayBuffer(request.generate().getBytes());
ByteArrayBuffer respBuff = tester.getResponses(reqsBuff);
response.parse(respBuff.asArray());
assertTrue(response.getMethod()==null);
assertTrue(response.getHeader("Content-Encoding").equalsIgnoreCase("gzip"));
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes()));
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
IO.copy(testIn,testOut);
assertEquals(__content, testOut.toString("ISO8859_1"));
}
}

View File

@ -562,7 +562,15 @@ public class Main
if (_exec)
{
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());

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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)
public byte setFlag(byte flags,int rsv)
{
return _dataOpcodes[i];
}
public int dataIndex(byte op)
{
for (int i=0;i<_dataOpcodes.length;i++)
if (_dataOpcodes[i]==op)
return i;
return -1;
}
public byte controlOpcode(int i)
{
return _dataOpcodes[i];
}
public int controlIndex(byte op)
{
for (int i=0;i<_controlOpcodes.length;i++)
if (_controlOpcodes[i]==op)
return i;
return -1;
if (rsv<1||rsv>3)
throw new IllegalArgumentException("rsv"+rsv);
byte b=(byte)(flags | __mask[rsv]);
return b;
}
public byte setFlag(byte flags,int flag)
public byte clearFlag(byte flags,int rsv)
{
return (byte)(flags | _bitMasks[flag]);
}
public byte clearFlag(byte flags,int flag)
{
return (byte)(flags & ~_bitMasks[flag]);
if (rsv<1||rsv>3)
throw new IllegalArgumentException("rsv"+rsv);
return (byte)(flags & ~__mask[rsv]);
}
public boolean isFlag(byte flags,int flag)
public boolean isFlag(byte flags,int rsv)
{
return (flags & _bitMasks[flag])!=0;
if (rsv<1||rsv>3)
throw new IllegalArgumentException("rsv"+rsv);
return (flags & __mask[rsv])!=0;
}
public String toString()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -38,7 +38,7 @@ import org.eclipse.jetty.websocket.WebSocket.OnTextMessage;
import org.eclipse.jetty.websocket.WebSocket.OnBinaryMessage;
import org.eclipse.jetty.websocket.WebSocket.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;
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

17
pom.xml
View File

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

View File

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

View File

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

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