Merge branch 'master' into release
This commit is contained in:
commit
ec7fc0313c
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>example-jetty-embedded</artifactId>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-all-server</artifactId>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-all</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-client</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-plus</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-servlet</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-webapp</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-websocket</artifactId>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-ajp</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-annotations</artifactId>
|
||||
|
|
|
@ -1,22 +1,19 @@
|
|||
package org.eclipse.jetty.annotations.resources;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
|
||||
import org.eclipse.jetty.annotations.AnnotationIntrospector;
|
||||
import org.eclipse.jetty.annotations.AnnotationParser;
|
||||
import org.eclipse.jetty.annotations.ClassNameResolver;
|
||||
import org.eclipse.jetty.annotations.ResourceAnnotationHandler;
|
||||
import org.eclipse.jetty.annotations.ResourcesAnnotationHandler;
|
||||
import org.eclipse.jetty.plus.annotation.Injection;
|
||||
import org.eclipse.jetty.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.webapp.MetaData;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
@ -24,24 +21,39 @@ import static org.junit.Assert.assertNotNull;
|
|||
|
||||
public class TestResourceAnnotations
|
||||
{
|
||||
Object objA=new Integer(1000);
|
||||
Object objB=new Integer(2000);
|
||||
|
||||
private Server server;
|
||||
private WebAppContext wac;
|
||||
private InjectionCollection injections;
|
||||
private Context comp;
|
||||
private Context env;
|
||||
private Object objA = 1000;
|
||||
private Object objB = 2000;
|
||||
|
||||
@Before
|
||||
public void init() throws Exception
|
||||
{
|
||||
server = new Server();
|
||||
wac = new WebAppContext();
|
||||
wac.setServer(server);
|
||||
injections = new InjectionCollection();
|
||||
wac.setAttribute(InjectionCollection.INJECTION_COLLECTION, injections);
|
||||
InitialContext ic = new InitialContext();
|
||||
comp = (Context)ic.lookup("java:comp");
|
||||
env = comp.createSubcontext("env");
|
||||
}
|
||||
|
||||
@After
|
||||
public void destroy() throws Exception
|
||||
{
|
||||
comp.destroySubcontext("env");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResourceAnnotations ()
|
||||
throws Exception
|
||||
{
|
||||
Server server = new Server();
|
||||
WebAppContext wac = new WebAppContext();
|
||||
wac.setServer(server);
|
||||
InjectionCollection injections = new InjectionCollection();
|
||||
wac.setAttribute(InjectionCollection.INJECTION_COLLECTION, injections);
|
||||
InitialContext ic = new InitialContext();
|
||||
Context comp = (Context)ic.lookup("java:comp");
|
||||
Context env = comp.createSubcontext("env");
|
||||
|
||||
org.eclipse.jetty.plus.jndi.EnvEntry resourceA = new org.eclipse.jetty.plus.jndi.EnvEntry(server, "resA", objA, false);
|
||||
org.eclipse.jetty.plus.jndi.EnvEntry resourceB = new org.eclipse.jetty.plus.jndi.EnvEntry(server, "resB", objB, false);
|
||||
new org.eclipse.jetty.plus.jndi.EnvEntry(server, "resA", objA, false);
|
||||
new org.eclipse.jetty.plus.jndi.EnvEntry(server, "resB", objB, false);
|
||||
|
||||
AnnotationIntrospector parser = new AnnotationIntrospector();
|
||||
ResourceAnnotationHandler handler = new ResourceAnnotationHandler(wac);
|
||||
|
@ -116,32 +128,21 @@ public class TestResourceAnnotations
|
|||
f = ResourceA.class.getDeclaredField("n");
|
||||
f.setAccessible(true);
|
||||
assertEquals(objB, f.get(binst));
|
||||
|
||||
comp.destroySubcontext("env");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testResourcesAnnotation ()
|
||||
throws Exception
|
||||
{
|
||||
Server server = new Server();
|
||||
WebAppContext wac = new WebAppContext();
|
||||
wac.setServer(server);
|
||||
InjectionCollection injections = new InjectionCollection();
|
||||
wac.setAttribute(InjectionCollection.INJECTION_COLLECTION, injections);
|
||||
InitialContext ic = new InitialContext();
|
||||
Context comp = (Context)ic.lookup("java:comp");
|
||||
Context env = comp.createSubcontext("env");
|
||||
org.eclipse.jetty.plus.jndi.EnvEntry resourceA = new org.eclipse.jetty.plus.jndi.EnvEntry(server, "resA", objA, false);
|
||||
org.eclipse.jetty.plus.jndi.EnvEntry resourceB = new org.eclipse.jetty.plus.jndi.EnvEntry(server, "resB", objB, false);
|
||||
|
||||
new org.eclipse.jetty.plus.jndi.EnvEntry(server, "resA", objA, false);
|
||||
new org.eclipse.jetty.plus.jndi.EnvEntry(server, "resB", objB, false);
|
||||
|
||||
AnnotationIntrospector introspector = new AnnotationIntrospector();
|
||||
ResourcesAnnotationHandler handler = new ResourcesAnnotationHandler(wac);
|
||||
introspector.registerHandler(handler);
|
||||
introspector.introspect(ResourceA.class);
|
||||
introspector.introspect(ResourceB.class);
|
||||
|
||||
|
||||
assertEquals(objA, env.lookup("peach"));
|
||||
assertEquals(objB, env.lookup("pear"));
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -39,7 +39,7 @@ import org.eclipse.jetty.util.security.Constraint;
|
|||
import org.eclipse.jetty.util.security.Credential;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
|
||||
public class SslCertSecuredExchangeTest extends ContentExchangeTest
|
||||
public class SslCertSecuredExchangeTest// extends ContentExchangeTest
|
||||
{
|
||||
// certificate is valid until Jan 1, 2050
|
||||
private String _keypath = MavenTestingUtils.getTargetFile("test-policy/validation/jetty-valid.keystore").getAbsolutePath();
|
||||
|
@ -51,7 +51,7 @@ public class SslCertSecuredExchangeTest extends ContentExchangeTest
|
|||
protected void configureServer(Server server)
|
||||
throws Exception
|
||||
{
|
||||
setProtocol("https");
|
||||
//setProtocol("https");
|
||||
|
||||
SslSelectChannelConnector connector = new SslSelectChannelConnector();
|
||||
SslContextFactory cf = connector.getSslContextFactory();
|
||||
|
@ -139,31 +139,31 @@ public class SslCertSecuredExchangeTest extends ContentExchangeTest
|
|||
|
||||
ServletContextHandler root = new ServletContextHandler();
|
||||
root.setContextPath("/");
|
||||
root.setResourceBase(getBasePath());
|
||||
// root.setResourceBase(getBasePath());
|
||||
ServletHolder servletHolder = new ServletHolder( new DefaultServlet() );
|
||||
servletHolder.setInitParameter( "gzip", "true" );
|
||||
root.addServlet( servletHolder, "/*" );
|
||||
|
||||
Handler handler = new TestHandler(getBasePath());
|
||||
// Handler handler = new TestHandler(getBasePath());
|
||||
|
||||
HandlerCollection handlers = new HandlerCollection();
|
||||
handlers.setHandlers(new Handler[]{handler, root});
|
||||
// handlers.setHandlers(new Handler[]{handler, root});
|
||||
security.setHandler(handlers);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureClient(HttpClient client) throws Exception
|
||||
{
|
||||
SslContextFactory cf = client.getSslContextFactory();
|
||||
cf.setValidateCerts(true);
|
||||
cf.setCrlPath(_crlpath);
|
||||
|
||||
cf.setCertAlias("client");
|
||||
cf.setKeyStorePath(_clientpath);
|
||||
cf.setKeyStorePassword(_password);
|
||||
cf.setKeyManagerPassword(_password);
|
||||
|
||||
cf.setTrustStore(_trustpath);
|
||||
cf.setTrustStorePassword(_password);
|
||||
}
|
||||
// @Override
|
||||
// protected void configureClient(HttpClient client) throws Exception
|
||||
// {
|
||||
// SslContextFactory cf = client.getSslContextFactory();
|
||||
// cf.setValidateCerts(true);
|
||||
// cf.setCrlPath(_crlpath);
|
||||
//
|
||||
// cf.setCertAlias("client");
|
||||
// cf.setKeyStorePath(_clientpath);
|
||||
// cf.setKeyStorePassword(_password);
|
||||
// cf.setKeyManagerPassword(_password);
|
||||
//
|
||||
// cf.setTrustStore(_trustpath);
|
||||
// cf.setTrustStorePassword(_password);
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
|||
import org.eclipse.jetty.util.security.CertificateUtils;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
|
||||
public abstract class SslValidationTestBase extends ContentExchangeTest
|
||||
public abstract class SslValidationTestBase //extends ContentExchangeTest
|
||||
{
|
||||
protected static Class<? extends SslConnector> __klass;
|
||||
protected static int __konnector;
|
||||
|
@ -29,70 +29,70 @@ public abstract class SslValidationTestBase extends ContentExchangeTest
|
|||
private String _crlpath = MavenTestingUtils.getTargetFile("test-policy/validation/crlfile.pem").getAbsolutePath();
|
||||
private String _password = "OBF:1wnl1sw01ta01z0f1tae1svy1wml";
|
||||
|
||||
@Override
|
||||
|
||||
protected void configureServer(Server server)
|
||||
throws Exception
|
||||
{
|
||||
setProtocol("https");
|
||||
|
||||
SslContextFactory srvFactory = new SslContextFactory() {
|
||||
@Override
|
||||
protected KeyStore getKeyStore(InputStream storeStream, String storePath, String storeType, String storeProvider, String storePassword) throws Exception
|
||||
{
|
||||
return CertificateUtils.getKeyStore(storeStream, storePath, storeType, storeProvider, storePassword);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<? extends CRL> loadCRL(String crlPath) throws Exception
|
||||
{
|
||||
return CertificateUtils.loadCRL(crlPath);
|
||||
}
|
||||
};
|
||||
srvFactory.setValidateCerts(true);
|
||||
srvFactory.setCrlPath(_crlpath);
|
||||
srvFactory.setNeedClientAuth(true);
|
||||
|
||||
srvFactory.setKeyStorePath(_keypath);
|
||||
srvFactory.setKeyStorePassword(_password);
|
||||
srvFactory.setKeyManagerPassword(_password);
|
||||
|
||||
srvFactory.setTrustStore(_trustpath);
|
||||
srvFactory.setTrustStorePassword(_password);
|
||||
|
||||
Constructor<? extends SslConnector> constructor = __klass.getConstructor(SslContextFactory.class);
|
||||
SslConnector connector = constructor.newInstance(srvFactory);
|
||||
connector.setMaxIdleTime(5000);
|
||||
server.addConnector(connector);
|
||||
|
||||
Handler handler = new TestHandler(getBasePath());
|
||||
|
||||
ServletContextHandler root = new ServletContextHandler();
|
||||
root.setContextPath("/");
|
||||
root.setResourceBase(getBasePath());
|
||||
ServletHolder servletHolder = new ServletHolder( new DefaultServlet() );
|
||||
servletHolder.setInitParameter( "gzip", "true" );
|
||||
root.addServlet( servletHolder, "/*" );
|
||||
|
||||
HandlerCollection handlers = new HandlerCollection();
|
||||
handlers.setHandlers(new Handler[]{handler, root});
|
||||
server.setHandler( handlers );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureClient(HttpClient client)
|
||||
throws Exception
|
||||
{
|
||||
client.setConnectorType(__konnector);
|
||||
|
||||
SslContextFactory cf = client.getSslContextFactory();
|
||||
cf.setValidateCerts(true);
|
||||
cf.setCrlPath(_crlpath);
|
||||
|
||||
cf.setKeyStorePath(_clientpath);
|
||||
cf.setKeyStorePassword(_password);
|
||||
cf.setKeyManagerPassword(_password);
|
||||
|
||||
cf.setTrustStore(_trustpath);
|
||||
cf.setTrustStorePassword(_password);
|
||||
// setProtocol("https");
|
||||
//
|
||||
// SslContextFactory srvFactory = new SslContextFactory() {
|
||||
// @Override
|
||||
// protected KeyStore getKeyStore(InputStream storeStream, String storePath, String storeType, String storeProvider, String storePassword) throws Exception
|
||||
// {
|
||||
// return CertificateUtils.getKeyStore(storeStream, storePath, storeType, storeProvider, storePassword);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected Collection<? extends CRL> loadCRL(String crlPath) throws Exception
|
||||
// {
|
||||
// return CertificateUtils.loadCRL(crlPath);
|
||||
// }
|
||||
// };
|
||||
// srvFactory.setValidateCerts(true);
|
||||
// srvFactory.setCrlPath(_crlpath);
|
||||
// srvFactory.setNeedClientAuth(true);
|
||||
//
|
||||
// srvFactory.setKeyStorePath(_keypath);
|
||||
// srvFactory.setKeyStorePassword(_password);
|
||||
// srvFactory.setKeyManagerPassword(_password);
|
||||
//
|
||||
// srvFactory.setTrustStore(_trustpath);
|
||||
// srvFactory.setTrustStorePassword(_password);
|
||||
//
|
||||
// Constructor<? extends SslConnector> constructor = __klass.getConstructor(SslContextFactory.class);
|
||||
// SslConnector connector = constructor.newInstance(srvFactory);
|
||||
// connector.setMaxIdleTime(5000);
|
||||
// server.addConnector(connector);
|
||||
//
|
||||
// Handler handler = new TestHandler(getBasePath());
|
||||
//
|
||||
// ServletContextHandler root = new ServletContextHandler();
|
||||
// root.setContextPath("/");
|
||||
// root.setResourceBase(getBasePath());
|
||||
// ServletHolder servletHolder = new ServletHolder( new DefaultServlet() );
|
||||
// servletHolder.setInitParameter( "gzip", "true" );
|
||||
// root.addServlet( servletHolder, "/*" );
|
||||
//
|
||||
// HandlerCollection handlers = new HandlerCollection();
|
||||
// handlers.setHandlers(new Handler[]{handler, root});
|
||||
// server.setHandler( handlers );
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected void configureClient(HttpClient client)
|
||||
// throws Exception
|
||||
// {
|
||||
// client.setConnectorType(__konnector);
|
||||
//
|
||||
// SslContextFactory cf = client.getSslContextFactory();
|
||||
// cf.setValidateCerts(true);
|
||||
// cf.setCrlPath(_crlpath);
|
||||
//
|
||||
// cf.setKeyStorePath(_clientpath);
|
||||
// cf.setKeyStorePassword(_password);
|
||||
// cf.setKeyManagerPassword(_password);
|
||||
//
|
||||
// cf.setTrustStore(_trustpath);
|
||||
// cf.setTrustStorePassword(_password);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-continuation</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-deploy</artifactId>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>jetty-distribution</artifactId>
|
||||
<name>Jetty :: Distribution Assemblies</name>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-http-spi</artifactId>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-http</artifactId>
|
||||
|
|
|
@ -106,7 +106,7 @@ public class GzipResponseWrapper extends HttpServletResponseWrapper
|
|||
}
|
||||
|
||||
if ((_gzStream==null || _gzStream._out==null) &&
|
||||
(_mimeTypes==null && "application/gzip".equalsIgnoreCase(ct) ||
|
||||
(_mimeTypes==null && ct!=null && ct.contains("gzip") ||
|
||||
_mimeTypes!=null && (ct==null||!_mimeTypes.contains(StringUtil.asciiToLowerCase(ct)))))
|
||||
{
|
||||
noGzip();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-io</artifactId>
|
||||
|
|
|
@ -385,7 +385,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
|
|||
try
|
||||
{
|
||||
updateKey();
|
||||
this.wait(timeoutMs>=0?(end-now):10000);
|
||||
this.wait(timeoutMs>0?(end-now):10000);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
|
@ -433,7 +433,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
|
|||
try
|
||||
{
|
||||
updateKey();
|
||||
this.wait(timeoutMs>=0?(end-now):10000);
|
||||
this.wait(timeoutMs>0?(end-now):10000);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
|
@ -455,14 +455,14 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.io.AsyncEndPoint#scheduleWrite()
|
||||
*/
|
||||
public void scheduleWrite()
|
||||
{
|
||||
if (_writable==true)
|
||||
if (_writable)
|
||||
LOG.debug("Required scheduleWrite {}",this);
|
||||
|
||||
_writable=false;
|
||||
|
@ -687,14 +687,15 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
|
|||
{
|
||||
try
|
||||
{
|
||||
if (_key!=null)
|
||||
_key.cancel();
|
||||
SelectionKey key = _key;
|
||||
if (key!=null)
|
||||
key.cancel();
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
LOG.ignore(e);
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
super.close();
|
||||
|
|
|
@ -285,7 +285,7 @@ public class IOTest
|
|||
Socket client;
|
||||
Socket server;
|
||||
|
||||
connector = new ServerSocket(9123);
|
||||
connector = new ServerSocket(0);
|
||||
client = new Socket("127.0.0.1",connector.getLocalPort());
|
||||
server = connector.accept();
|
||||
client.setTcpNoDelay(true);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-jaspi</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-jmx</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-jndi</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-jsp</artifactId>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-monitor</artifactId>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>jetty-nested</artifactId>
|
||||
<name>Jetty :: Nested</name>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-nosql</artifactId>
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.eclipse.jetty.npn</groupId>
|
||||
<artifactId>npn-api</artifactId>
|
||||
<name>Jetty :: Next Protocol Negotiation :: API</name>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
* Copyright (c) 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.eclipse.jetty.npn;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import javax.net.ssl.SSLEngine;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
|
||||
/**
|
||||
* <p>{@link NextProtoNego} provides an API to applications that want to make use of the
|
||||
* <a href="http://technotes.googlecode.com/git/nextprotoneg.html">Next Protocol Negotiation</a>.</p>
|
||||
* <p>The NPN extension is only available when using the TLS protocol, therefore applications must
|
||||
* ensure that the TLS protocol is used:</p>
|
||||
* <pre>
|
||||
* SSLContext context = SSLContext.getInstance("TLSv1");
|
||||
* </pre>
|
||||
* <p>Refer to the
|
||||
* <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#SSLContext">list
|
||||
* of standard SSLContext protocol names</a> for further information on TLS protocol versions supported.</p>
|
||||
* <p>Applications must register instances of either {@link SSLSocket} or {@link SSLEngine} with a
|
||||
* {@link ClientProvider} or with a {@link ServerProvider}, depending whether they are on client or
|
||||
* server side.</p>
|
||||
* <p>The NPN implementation will invoke the provider callbacks to allow applications to interact
|
||||
* with the negotiation of the next protocol.</p>
|
||||
* <p>Client side typical usage:</p>
|
||||
* <pre>
|
||||
* SSLSocket sslSocket = ...;
|
||||
* NextProtoNego.put(sslSocket, new NextProtoNego.ClientProvider()
|
||||
* {
|
||||
* @Override
|
||||
* public boolean supports()
|
||||
* {
|
||||
* return true;
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* public void unsupported()
|
||||
* {
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* public String selectProtocol(List<String> protocols)
|
||||
* {
|
||||
* return protocols.get(0);
|
||||
* }
|
||||
* });
|
||||
* </pre>
|
||||
* <p>Server side typical usage:</p>
|
||||
* <pre>
|
||||
* SSLSocket sslSocket = ...;
|
||||
* NextProtoNego.put(sslSocket, new NextProtoNego.ServerProvider()
|
||||
* {
|
||||
* @Override
|
||||
* public void unsupported()
|
||||
* {
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* public List<String> protocols()
|
||||
* {
|
||||
* return Arrays.asList("http/1.1");
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* public void protocolSelected(String protocol)
|
||||
* {
|
||||
* System.out.println("Protocol Selected is: " + protocol);
|
||||
* }
|
||||
* });
|
||||
* </pre>
|
||||
* <p>There is no need to unregister {@link SSLSocket} or {@link SSLEngine} instances, as they
|
||||
* are kept in a {@link WeakHashMap} and will be garbage collected when the application does not
|
||||
* hard reference them anymore.</p>
|
||||
* <p>In order to help application development, you can set the {@link NextProtoNego#debug} field
|
||||
* to {@code true} to have debug code printed to {@link System#err}.</p>
|
||||
*/
|
||||
public class NextProtoNego
|
||||
{
|
||||
/**
|
||||
* <p>Enables debug logging on {@link System#err}.</p>
|
||||
*/
|
||||
public static boolean debug = false;
|
||||
|
||||
private static Map<Object, Provider> objects = Collections.synchronizedMap(new WeakHashMap<Object, Provider>());
|
||||
|
||||
private NextProtoNego()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Registers a SSLSocket with a provider.</p>
|
||||
*
|
||||
* @param socket the socket to register with the provider
|
||||
* @param provider the provider to register with the socket
|
||||
*/
|
||||
public static void put(SSLSocket socket, Provider provider)
|
||||
{
|
||||
objects.put(socket, provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param socket a socket registered with {@link #put(SSLSocket, Provider)}
|
||||
* @return the provider registered with the given socket
|
||||
*/
|
||||
public static Provider get(SSLSocket socket)
|
||||
{
|
||||
return objects.get(socket);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Registers a SSLEngine with a provider.</p>
|
||||
*
|
||||
* @param engine the engine to register with the provider
|
||||
* @param provider the provider to register with the engine
|
||||
*/
|
||||
public static void put(SSLEngine engine, Provider provider)
|
||||
{
|
||||
objects.put(engine, provider);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param engine an engine registered with {@link #put(SSLEngine, Provider)}
|
||||
* @return the provider registered with the given engine
|
||||
*/
|
||||
public static Provider get(SSLEngine engine)
|
||||
{
|
||||
return objects.get(engine);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Base, empty, interface for providers.</p>
|
||||
*/
|
||||
public interface Provider
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>The client-side provider interface that applications must implement to interact
|
||||
* with the negotiation of the next protocol.</p>
|
||||
*/
|
||||
public interface ClientProvider extends Provider
|
||||
{
|
||||
/**
|
||||
* <p>Callback invoked to let the implementation know whether an
|
||||
* empty NPN extension should be added to a ClientHello SSL message.</p>
|
||||
*
|
||||
* @return true to add the NPN extension, false otherwise
|
||||
*/
|
||||
public boolean supports();
|
||||
|
||||
/**
|
||||
* <p>Callback invoked to let the application know that the server does
|
||||
* not support NPN.</p>
|
||||
*/
|
||||
public void unsupported();
|
||||
|
||||
/**
|
||||
* <p>Callback invoked to let the application select a protocol
|
||||
* among the ones sent by the server.</p>
|
||||
*
|
||||
* @param protocols the protocols sent by the server
|
||||
* @return the protocol selected by the application, or null if the
|
||||
* NextProtocol SSL message should not be sent to the server
|
||||
*/
|
||||
public String selectProtocol(List<String> protocols);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>The server-side provider interface that applications must implement to interact
|
||||
* with the negotiation of the next protocol.</p>
|
||||
*/
|
||||
public interface ServerProvider extends Provider
|
||||
{
|
||||
/**
|
||||
* <p>Callback invoked to let the application know that the client does not
|
||||
* support NPN.</p>
|
||||
*/
|
||||
public void unsupported();
|
||||
|
||||
/**
|
||||
* <p>Callback invoked to let the implementation know the list
|
||||
* of protocols that should be added to an NPN extension in a
|
||||
* ServerHello SSL message.</p>
|
||||
* <p>This callback is invoked only if the client sent a NPN extension.</p>
|
||||
*
|
||||
* @return the list of protocols, or null if no NPN extension
|
||||
* should be sent to the client
|
||||
*/
|
||||
public List<String> protocols();
|
||||
|
||||
/**
|
||||
* <p>Callback invoked to let the application know the protocol selected
|
||||
* by the client.</p>
|
||||
* <p>This callback is invoked only if the client sent a NextProtocol SSL message.</p>
|
||||
*
|
||||
* @param protocol the selected protocol
|
||||
*/
|
||||
public void protocolSelected(String protocol);
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2
|
|||
Bundle-Name: Jetty-OSGi-Jasper integration
|
||||
Fragment-Host: org.eclipse.jetty.osgi.boot
|
||||
Bundle-SymbolicName: org.eclipse.jetty.osgi.boot.jsp
|
||||
Bundle-Version: 7.4.1.qualifier
|
||||
Bundle-Version: 7.6.2.qualifier
|
||||
Bundle-Vendor: Mort Bay Consulting
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
Import-Package: com.sun.el;resolution:=optional,
|
||||
|
@ -22,15 +22,16 @@ Import-Package: com.sun.el;resolution:=optional,
|
|||
javax.servlet.jsp.resources;version="2.1.0",
|
||||
javax.servlet.jsp.tagext;version="2.1.0",
|
||||
javax.servlet.resources;version="2.5.0",
|
||||
org.apache.jasper;version="2.0.0";resolution:=optional,
|
||||
org.apache.jasper.compiler;version="2.0.0";resolution:=optional,
|
||||
org.apache.jasper.compiler.tagplugin;version="2.0.0";resolution:=optional,
|
||||
org.apache.jasper.runtime;version="2.0.0";resolution:=optional,
|
||||
org.apache.jasper.security;version="2.0.0";resolution:=optional,
|
||||
org.apache.jasper.servlet;version="2.0.0";resolution:=optional,
|
||||
org.apache.jasper.tagplugins.jstl;version="2.0.0";resolution:=optional,
|
||||
org.apache.jasper.util;version="2.0.0";resolution:=optional,
|
||||
org.apache.jasper.xmlparser;version="2.0.0";resolution:=optional,
|
||||
org.apache.jasper;version="6.0.0";resolution:=optional,
|
||||
org.apache.jasper.compiler;version="6.0.0";resolution:=optional,
|
||||
org.apache.jasper.compiler.tagplugin;version="6.0.0";resolution:=optional,
|
||||
org.apache.jasper.runtime;version="6.0.0";resolution:=optional,
|
||||
org.apache.jasper.security;version="6.0.0";resolution:=optional,
|
||||
org.apache.jasper.servlet;version="6.0.0";resolution:=optional,
|
||||
org.apache.jasper.tagplugins.jstl;version="6.0.0";resolution:=optional,
|
||||
org.apache.jasper.util;version="6.0.0";resolution:=optional,
|
||||
org.apache.jasper.xmlparser;version="6.0.0";resolution:=optional,
|
||||
org.glassfish.jasper.api;version="2.1.3";resolution:=optional,
|
||||
org.apache.taglibs.standard;version="1.2.0";resolution:=optional,
|
||||
org.apache.taglibs.standard.extra.spath;version="1.2.0";resolution:=optional,
|
||||
org.apache.taglibs.standard.functions;version="1.2.0";resolution:=optional,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -167,6 +167,8 @@ public class WebappRegistrationCustomizerImpl implements WebappRegistrationCusto
|
|||
}
|
||||
return urls.toArray(new URL[urls.size()]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Jasper resolves the dtd when it parses a taglib descriptor.
|
||||
|
@ -182,7 +184,7 @@ public class WebappRegistrationCustomizerImpl implements WebappRegistrationCusto
|
|||
* on a static friendly field :(
|
||||
* </p>
|
||||
*/
|
||||
void fixupDtdResolution()
|
||||
void fixupDtdResolution()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -214,12 +216,12 @@ public class WebappRegistrationCustomizerImpl implements WebappRegistrationCusto
|
|||
Constants.WEBAPP_DTD_RESOURCE_PATH_22,
|
||||
Constants.WEBAPP_DTD_RESOURCE_PATH_23, };
|
||||
|
||||
// static final String[] CACHED_SCHEMA_RESOURCE_PATHS = {
|
||||
// Constants.TAGLIB_SCHEMA_RESOURCE_PATH_20,
|
||||
// Constants.TAGLIB_SCHEMA_RESOURCE_PATH_21,
|
||||
// Constants.WEBAPP_SCHEMA_RESOURCE_PATH_24,
|
||||
// Constants.WEBAPP_SCHEMA_RESOURCE_PATH_25,
|
||||
// };
|
||||
static final String[] CACHED_SCHEMA_RESOURCE_PATHS = {
|
||||
Constants.TAGLIB_SCHEMA_RESOURCE_PATH_20,
|
||||
Constants.TAGLIB_SCHEMA_RESOURCE_PATH_21,
|
||||
Constants.WEBAPP_SCHEMA_RESOURCE_PATH_24,
|
||||
Constants.WEBAPP_SCHEMA_RESOURCE_PATH_25,
|
||||
};
|
||||
public InputSource resolveEntity(String publicId, String systemId) throws SAXException
|
||||
{
|
||||
for (int i = 0; i < CACHED_DTD_PUBLIC_IDS.length; i++)
|
||||
|
|
|
@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2
|
|||
Bundle-Name: Jetty-OSGi-Logback integration
|
||||
Fragment-Host: org.eclipse.jetty.osgi.boot
|
||||
Bundle-SymbolicName: org.eclipse.jetty.osgi.boot.logback;singleton:=true
|
||||
Bundle-Version: 7.3.0.qualifier
|
||||
Bundle-Version: 7.6.2.qualifier
|
||||
Bundle-Vendor: Mort Bay Consulting
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
Import-Package: ch.qos.logback.classic,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
|||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Support for rfc66 war url scheme
|
||||
Bundle-SymbolicName: org.eclipse.jetty.osgi.boot.warurl;singleton:=true
|
||||
Bundle-Version: 7.3.0.qualifier
|
||||
Bundle-Version: 7.6.2.qualifier
|
||||
Bundle-Activator: org.eclipse.jetty.osgi.boot.warurl.WarUrlActivator
|
||||
Bundle-Vendor: Mort Bay Consulting
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2
|
|||
Bundle-Name: Jetty OSGi bootstrap
|
||||
Bundle-SymbolicName: org.eclipse.jetty.osgi.boot;singleton:=true
|
||||
Bundle-Vendor: Mort Bay Consulting
|
||||
Bundle-Version: 7.4.3.qualifier
|
||||
Bundle-Version: 7.6.2.qualifier
|
||||
Bundle-Activator: org.eclipse.jetty.osgi.boot.JettyBootstrapActivator
|
||||
Import-Package: javax.mail;version="1.4.0";resolution:=optional,
|
||||
javax.mail.event;version="1.4.0";resolution:=optional,
|
||||
|
@ -14,19 +14,19 @@ Import-Package: javax.mail;version="1.4.0";resolution:=optional,
|
|||
javax.servlet.http;version="2.5.0",
|
||||
javax.transaction;version="1.1.0";resolution:=optional,
|
||||
javax.transaction.xa;version="1.1.0";resolution:=optional,
|
||||
org.eclipse.jetty.deploy;version="7.4.0",
|
||||
org.eclipse.jetty.deploy.providers;version="7.4.0",
|
||||
org.eclipse.jetty.http;version="7.4.0",
|
||||
org.eclipse.jetty.nested;version="7.4.0";resolution:=optional,
|
||||
org.eclipse.jetty.server;version="7.4.0",
|
||||
org.eclipse.jetty.server.handler;version="7.4.0",
|
||||
org.eclipse.jetty.servlet;version="7.4.0",
|
||||
org.eclipse.jetty.util;version="7.4.0",
|
||||
org.eclipse.jetty.util.component;version="7.4.0",
|
||||
org.eclipse.jetty.util.log;version="7.4.0",
|
||||
org.eclipse.jetty.util.resource;version="7.4.0",
|
||||
org.eclipse.jetty.webapp;version="7.4.1.v20110513",
|
||||
org.eclipse.jetty.xml;version="7.4.0",
|
||||
org.eclipse.jetty.deploy;version="7.6.2",
|
||||
org.eclipse.jetty.deploy.providers;version="7.6.2",
|
||||
org.eclipse.jetty.http;version="7.6.2",
|
||||
org.eclipse.jetty.nested;version="7.6.2";resolution:=optional,
|
||||
org.eclipse.jetty.server;version="7.6.2",
|
||||
org.eclipse.jetty.server.handler;version="7.6.2",
|
||||
org.eclipse.jetty.servlet;version="7.6.2",
|
||||
org.eclipse.jetty.util;version="7.6.2",
|
||||
org.eclipse.jetty.util.component;version="7.6.2",
|
||||
org.eclipse.jetty.util.log;version="7.6.2",
|
||||
org.eclipse.jetty.util.resource;version="7.6.2",
|
||||
org.eclipse.jetty.webapp;version="7.6.2",
|
||||
org.eclipse.jetty.xml;version="7.6.2",
|
||||
org.osgi.framework,
|
||||
org.osgi.service.cm;version="1.2.0",
|
||||
org.osgi.service.packageadmin,
|
||||
|
@ -40,7 +40,7 @@ Import-Package: javax.mail;version="1.4.0";resolution:=optional,
|
|||
org.xml.sax.helpers
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
Bundle-Classpath: .
|
||||
Export-Package: org.eclipse.jetty.osgi.boot;version="7.4.0",
|
||||
org.eclipse.jetty.osgi.nested;version="7.4.0",
|
||||
org.eclipse.jetty.osgi.boot.utils;version="7.4.0"
|
||||
Export-Package: org.eclipse.jetty.osgi.boot;version="7.6.2",
|
||||
org.eclipse.jetty.osgi.nested;version="7.6.2",
|
||||
org.eclipse.jetty.osgi.boot.utils;version="7.6.2"
|
||||
DynamicImport-Package: org.eclipse.jetty.*;version="[7.3,8)"
|
||||
|
|
|
@ -22,14 +22,6 @@
|
|||
<Set name="minThreads">10</Set>
|
||||
<Set name="maxThreads">200</Set>
|
||||
</New>
|
||||
|
||||
<!-- Optional Java 5 bounded threadpool with job queue
|
||||
<New class="org.eclipse.jetty.util.thread.ExecutorThreadPool">
|
||||
<Arg name="coreSize" type="int">25</Arg>
|
||||
<Arg name="maxSize" type="int">50</Arg>
|
||||
<Arg name="maxIdleMs" type="long">30000</Arg>
|
||||
</New>
|
||||
-->
|
||||
</Set>
|
||||
|
||||
|
||||
|
@ -118,7 +110,7 @@
|
|||
contain custom tag libraries (*.tld files)
|
||||
if those bundles don't exist or can't be loaded no errors or warning will be issued!
|
||||
this default value is to plug the tld files of the reference implementation of JSF -->
|
||||
<Set name="tldBundles"><Property name="org.eclipse.jetty.osgi.tldsbundles"
|
||||
<Set name="tldBundles"><Property name="org.eclipse.jetty.osgi.tldbundles"
|
||||
default="javax.faces.jsf-impl" /></Set>
|
||||
</New>
|
||||
</Arg>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -187,6 +187,9 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
|
|||
{
|
||||
((WebAppContext)wah).setConfigurationClasses(_configurationClasses);
|
||||
}
|
||||
|
||||
if (_defaultsDescriptor != null)
|
||||
((WebAppContext)wah).setDefaultsDescriptor(_defaultsDescriptor);
|
||||
return app.getContextHandler();
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Map;
|
|||
import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator;
|
||||
import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
|
||||
import org.eclipse.jetty.osgi.boot.OSGiWebappConstants;
|
||||
import org.eclipse.jetty.osgi.boot.internal.serverfactory.DefaultJettyAtJettyHomeHelper;
|
||||
import org.eclipse.jetty.osgi.boot.internal.serverfactory.IManagedJettyServerRegistry;
|
||||
import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
|
@ -195,7 +196,21 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
|
|||
String defaultWebXmlPath = (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_DEFAULT_WEB_XML_PATH);
|
||||
if (defaultWebXmlPath == null)
|
||||
{
|
||||
defaultWebXmlPath = webapp.getDefaultsDescriptor();
|
||||
String jettyHome = System.getProperty(DefaultJettyAtJettyHomeHelper.SYS_PROP_JETTY_HOME);
|
||||
if (jettyHome != null)
|
||||
{
|
||||
File etc = new File(jettyHome, "etc");
|
||||
if (etc.exists() && etc.isDirectory())
|
||||
{
|
||||
File webDefault = new File (etc, "webdefault.xml");
|
||||
if (webDefault.exists())
|
||||
defaultWebXmlPath = webDefault.getAbsolutePath();
|
||||
else
|
||||
defaultWebXmlPath = webapp.getDefaultsDescriptor();
|
||||
}
|
||||
else
|
||||
defaultWebXmlPath = webapp.getDefaultsDescriptor();
|
||||
}
|
||||
}
|
||||
String war = (String)sr.getProperty("war");
|
||||
try
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.ArrayList;
|
|||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.TreeMap;
|
||||
|
@ -50,6 +51,9 @@ import org.eclipse.jetty.webapp.WebInfConfiguration;
|
|||
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.BundleReference;
|
||||
import org.osgi.service.packageadmin.PackageAdmin;
|
||||
import org.osgi.util.tracker.ServiceTracker;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
|
@ -173,6 +177,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
overrideBundleInstallLocation);
|
||||
File webapp = null;
|
||||
URL baseWebappInstallURL = null;
|
||||
|
||||
if (webappFolderPath != null && webappFolderPath.length() != 0 && !webappFolderPath.equals("."))
|
||||
{
|
||||
if (webappFolderPath.startsWith("/") || webappFolderPath.startsWith("file:"))
|
||||
|
@ -261,7 +266,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
File defaultWebXml = null;
|
||||
if (defaultWebXmlPath.startsWith("/") || defaultWebXmlPath.startsWith("file:/"))
|
||||
{
|
||||
defaultWebXml = new File(webXmlPath);
|
||||
defaultWebXml = new File(defaultWebXmlPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -276,8 +281,9 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
//other parameters that might be defines on the OSGiAppProvider:
|
||||
context.setParentLoaderPriority(_wrapper.getOSGiAppProvider().isParentLoaderPriority());
|
||||
|
||||
configureWebappClassLoader(contributor,context,composite, requireTldBundle);
|
||||
configureWebAppContext(context,contributor,requireTldBundle);
|
||||
configureWebappClassLoader(contributor,context,composite);
|
||||
|
||||
|
||||
// @see
|
||||
// org.eclipse.jetty.webapp.JettyWebXmlConfiguration#configure(WebAppContext)
|
||||
|
@ -450,7 +456,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
//the actual registration must happen via the new Deployment API.
|
||||
// _ctxtHandler.addHandler(context);
|
||||
|
||||
configureWebappClassLoader(contributor,context,composite);
|
||||
configureWebappClassLoader(contributor,context,composite, requireTldBundle);
|
||||
if (context instanceof WebAppContext)
|
||||
{
|
||||
webAppContext = (WebAppContext)context;
|
||||
|
@ -615,8 +621,9 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
}
|
||||
while (tldEnum.hasMoreElements())
|
||||
{
|
||||
URL tldUrl = tldEnum.nextElement();
|
||||
tldfrags.add(Resource.newResource(
|
||||
DefaultFileLocatorHelper.getLocalURL(tldEnum.nextElement())));
|
||||
DefaultFileLocatorHelper.getLocalURL(tldUrl)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -764,13 +771,17 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
* @param classInBundle
|
||||
* @throws Exception
|
||||
*/
|
||||
protected void configureWebappClassLoader(Bundle contributor, ContextHandler context, OSGiWebappClassLoader webappClassLoader) throws Exception
|
||||
protected void configureWebappClassLoader(Bundle contributor, ContextHandler context, OSGiWebappClassLoader webappClassLoader, String requireTldBundle) throws Exception
|
||||
{
|
||||
if (context instanceof WebAppContext)
|
||||
{
|
||||
WebAppContext webappCtxt = (WebAppContext)context;
|
||||
context.setClassLoader(webappClassLoader);
|
||||
webappClassLoader.setWebappContext(webappCtxt);
|
||||
|
||||
String pathsToRequiredBundles = getPathsToRequiredBundles(context, requireTldBundle);
|
||||
if (pathsToRequiredBundles != null)
|
||||
webappClassLoader.addClassPath(pathsToRequiredBundles);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -788,6 +799,18 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
// know.
|
||||
OSGiWebappClassLoader webappClassLoader = new OSGiWebappClassLoader(
|
||||
_wrapper.getParentClassLoaderForWebapps(),new WebAppContext(),contributor,BUNDLE_CLASS_LOADER_HELPER);
|
||||
/* DEBUG
|
||||
try {
|
||||
Class c = webappClassLoader.loadClass("org.glassfish.jsp.api.ResourceInjector");
|
||||
System.err.println("LOADED org.glassfish.jsp.api.ResourceInjector from "+c.getClassLoader());
|
||||
}
|
||||
catch (Exception e) {e.printStackTrace();}
|
||||
try {
|
||||
Class c = webappClassLoader.loadClass("org.apache.jasper.xmlparser.ParserUtils");
|
||||
System.err.println("LOADED org.apache.jasper.xmlparser.ParserUtils from "+c.getClassLoader());
|
||||
}
|
||||
catch (Exception e) {e.printStackTrace();}
|
||||
*/
|
||||
return webappClassLoader;
|
||||
}
|
||||
|
||||
|
@ -811,5 +834,50 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private String getPathsToRequiredBundles (ContextHandler context, String requireTldBundle) throws Exception
|
||||
{
|
||||
if (requireTldBundle == null)
|
||||
return null;
|
||||
|
||||
StringBuilder paths = new StringBuilder();
|
||||
Bundle bundle = (Bundle)context.getAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE);
|
||||
PackageAdmin packAdmin = getBundleAdmin();
|
||||
DefaultFileLocatorHelper fileLocatorHelper = new DefaultFileLocatorHelper();
|
||||
|
||||
String[] symbNames = requireTldBundle.split(", ");
|
||||
|
||||
for (String symbName : symbNames)
|
||||
{
|
||||
Bundle[] bs = packAdmin.getBundles(symbName, null);
|
||||
if (bs == null || bs.length == 0)
|
||||
{
|
||||
throw new IllegalArgumentException("Unable to locate the bundle '"
|
||||
+ symbName + "' specified in the "
|
||||
+ OSGiWebappConstants.REQUIRE_TLD_BUNDLE
|
||||
+ " of the manifest of "
|
||||
+ bundle.getSymbolicName());
|
||||
}
|
||||
|
||||
|
||||
File f = fileLocatorHelper.getBundleInstallLocation(bs[0]);
|
||||
if (paths.length() > 0)
|
||||
paths.append(", ");
|
||||
System.err.println("getPathsToRequiredBundles: bundle path="+bs[0].getLocation()+" uri="+f.toURI());
|
||||
paths.append(f.toURI().toURL().toString());
|
||||
}
|
||||
|
||||
return paths.toString();
|
||||
}
|
||||
|
||||
private PackageAdmin getBundleAdmin()
|
||||
{
|
||||
Bundle bootBundle = ((BundleReference)OSGiWebappConstants.class.getClassLoader()).getBundle();
|
||||
ServiceTracker serviceTracker = new ServiceTracker(bootBundle.getBundleContext(), PackageAdmin.class.getName(), null);
|
||||
serviceTracker.open();
|
||||
|
||||
return (PackageAdmin) serviceTracker.getService();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -3,20 +3,20 @@ Bundle-ManifestVersion: 2
|
|||
Bundle-Name: Console
|
||||
Bundle-SymbolicName: org.eclipse.jetty.osgi.equinoxtools
|
||||
Bundle-Description: Example application: equinox console accesssible on the web
|
||||
Bundle-Version: 7.4.2.qualifier
|
||||
Bundle-Version: 7.6.2.qualifier
|
||||
Bundle-Activator: org.eclipse.jetty.osgi.equinoxtools.WebEquinoxToolsActivator
|
||||
Import-Package: javax.servlet;version="2.5.0",
|
||||
javax.servlet.http;version="2.5.0",
|
||||
org.eclipse.jetty.continuation;version="7.4.0",
|
||||
org.eclipse.jetty.io;version="7.4.0",
|
||||
org.eclipse.jetty.util;version="7.4.0",
|
||||
org.eclipse.jetty.util.log;version="7.4.0",
|
||||
org.eclipse.jetty.websocket;version="7.4.0",
|
||||
org.eclipse.jetty.continuation;version="7.6.2",
|
||||
org.eclipse.jetty.io;version="7.6.2",
|
||||
org.eclipse.jetty.util;version="7.6.2",
|
||||
org.eclipse.jetty.util.log;version="7.6.2",
|
||||
org.eclipse.jetty.websocket;version="7.6.2",
|
||||
org.eclipse.osgi.framework.console;version="1.1.0",
|
||||
org.osgi.framework;version="1.3.0",
|
||||
org.osgi.service.http;version="1.2.0",
|
||||
org.osgi.util.tracker;version="1.3.0"
|
||||
Export-Package: org.eclipse.jetty.osgi.equinoxtools;x-internal:=true;version="7.4.2",
|
||||
org.eclipse.jetty.osgi.equinoxtools.console;x-internal:=true;version="7.4.2"
|
||||
Export-Package: org.eclipse.jetty.osgi.equinoxtools;x-internal:=true;version="7.6.2",
|
||||
org.eclipse.jetty.osgi.equinoxtools.console;x-internal:=true;version="7.6.2"
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
Bundle-ManifestVersion: 2
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
Bundle-SymbolicName: org.eclipse.jetty.osgi.httpservice
|
||||
Bundle-Version: 7.4.2.qualifier
|
||||
Bundle-Version: 7.6.2.qualifier
|
||||
Bundle-Vendor: Mort Bay Consulting
|
||||
Bundle-Name: OSGi HttpService provided by equinox HttpServiceServlet deployed on jetty
|
||||
Jetty-ContextFilePath: contexts/httpservice.xml
|
||||
Import-Package: javax.servlet;version="2.5.0",
|
||||
javax.servlet.http;version="2.5.0",
|
||||
org.eclipse.equinox.http.servlet,
|
||||
org.eclipse.jetty.server;version="7.0.0",
|
||||
org.eclipse.jetty.server.handler;version="7.0.0",
|
||||
org.eclipse.jetty.servlet;version="7.4.0",
|
||||
org.eclipse.jetty.util.component;version="7.0.0"
|
||||
Export-Package: org.eclipse.jetty.osgi.httpservice;version="7.4.2"
|
||||
org.eclipse.jetty.server;version="7.6.2",
|
||||
org.eclipse.jetty.server.handler;version="7.6.2",
|
||||
org.eclipse.jetty.servlet;version="7.6.2",
|
||||
org.eclipse.jetty.util.component;version="7.6.2"
|
||||
Export-Package: org.eclipse.jetty.osgi.httpservice;version="7.6.2"
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
|
@ -15,7 +15,6 @@
|
|||
<osgi-services-version>3.2.100.v20100503</osgi-services-version>
|
||||
<equinox-http-servlet-version>1.0.0-v20070606</equinox-http-servlet-version>
|
||||
<!--equinox-servletbridge-version>1.0.0-v20070523</equinox-servletbridge-version-->
|
||||
<jsp-2.1-glassfish-version>2.1.v20100127</jsp-2.1-glassfish-version>
|
||||
<logback-version>0.9.18</logback-version>
|
||||
<slf4j-version>1.5.11</slf4j-version>
|
||||
</properties>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -102,6 +102,12 @@
|
|||
<artifactId>jetty-websocket</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-plus</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Eclipse OSGi Deps -->
|
||||
<dependency>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-overlay-deployer</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-plus</artifactId>
|
||||
|
|
|
@ -13,11 +13,15 @@
|
|||
|
||||
package org.eclipse.jetty.plus.jndi;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
|
||||
import javax.naming.Binding;
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
import javax.naming.Name;
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.RefAddr;
|
||||
import javax.naming.Reference;
|
||||
|
@ -25,6 +29,7 @@ import javax.naming.Referenceable;
|
|||
import javax.naming.StringRefAddr;
|
||||
import javax.naming.spi.ObjectFactory;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -125,6 +130,35 @@ public class TestNamingEntries
|
|||
public void init()
|
||||
{
|
||||
this.someObject = new SomeObject(4);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* after each test we should scrape out any lingering bindings to prevent cross test pollution
|
||||
* as observed when running java 7
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@After
|
||||
public void after() throws Exception
|
||||
{
|
||||
InitialContext icontext = new InitialContext();
|
||||
|
||||
NamingEnumeration<Binding> bindings = icontext.listBindings("");
|
||||
List<String> names = new ArrayList<String>();
|
||||
while (bindings.hasMore())
|
||||
{
|
||||
Binding bd = (Binding)bindings.next();
|
||||
names.add(bd.getName());
|
||||
}
|
||||
|
||||
for (String name : names)
|
||||
{
|
||||
icontext.unbind(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -199,6 +233,7 @@ public class TestNamingEntries
|
|||
|
||||
ne = NamingEntryUtil.lookupNamingEntry(new ScopeB(), "resourceB");
|
||||
assertNull(ne);
|
||||
testLink();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>jetty-policy</artifactId>
|
||||
<name>Jetty :: Policy Tool</name>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-rewrite</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-security</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
|
|
|
@ -24,7 +24,6 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import org.eclipse.jetty.continuation.Continuation;
|
||||
import org.eclipse.jetty.continuation.ContinuationListener;
|
||||
import org.eclipse.jetty.continuation.ContinuationThrowable;
|
||||
import org.eclipse.jetty.http.PathMap;
|
||||
import org.eclipse.jetty.io.AsyncEndPoint;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
|
@ -821,8 +820,10 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
synchronized (this)
|
||||
{
|
||||
doSuspend(context,request,response);
|
||||
if ( request instanceof HttpServletRequest)
|
||||
_event._pathInContext=URIUtil.addPaths(((HttpServletRequest)request).getServletPath(),((HttpServletRequest)request).getPathInfo());
|
||||
if (request instanceof HttpServletRequest)
|
||||
{
|
||||
_event._pathInContext = URIUtil.addPaths(((HttpServletRequest)request).getServletPath(),((HttpServletRequest)request).getPathInfo());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -783,7 +783,7 @@ public class Response implements HttpServletResponse
|
|||
if (isCommitted() || _connection.isIncluding())
|
||||
return;
|
||||
_connection._generator.setContentLength(len);
|
||||
if (len>=0)
|
||||
if (len>0)
|
||||
{
|
||||
_connection.getResponseFields().putLongField(HttpHeaders.CONTENT_LENGTH, len);
|
||||
if (_connection._generator.isAllContentWritten())
|
||||
|
|
|
@ -24,8 +24,8 @@ import org.eclipse.jetty.server.Request;
|
|||
import org.eclipse.jetty.server.Server;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** A <code>HandlerContainer</code> that allows a hot swap
|
||||
* of a wrapped handler.
|
||||
/**
|
||||
* A <code>HandlerContainer</code> that allows a hot swap of a wrapped handler.
|
||||
*
|
||||
*/
|
||||
public class HotSwapHandler extends AbstractHandlerContainer
|
||||
|
@ -48,113 +48,106 @@ public class HotSwapHandler extends AbstractHandlerContainer
|
|||
{
|
||||
return _handler;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return Returns the handlers.
|
||||
*/
|
||||
public Handler[] getHandlers()
|
||||
{
|
||||
return new Handler[] {_handler};
|
||||
return new Handler[]
|
||||
{ _handler };
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param handler Set the {@link Handler} which should be wrapped.
|
||||
* @param handler
|
||||
* Set the {@link Handler} which should be wrapped.
|
||||
*/
|
||||
public void setHandler(Handler handler)
|
||||
{
|
||||
if (handler == null)
|
||||
throw new IllegalArgumentException("Parameter handler is null.");
|
||||
try
|
||||
{
|
||||
Handler old_handler = _handler;
|
||||
_handler = handler;
|
||||
if (handler!=null)
|
||||
{
|
||||
handler.setServer(getServer());
|
||||
if (isStarted())
|
||||
handler.start();
|
||||
}
|
||||
Server server = getServer();
|
||||
handler.setServer(server);
|
||||
addBean(handler);
|
||||
|
||||
if (getServer()!=null)
|
||||
getServer().getContainer().update(this, old_handler, handler, "handler");
|
||||
if (server != null)
|
||||
server.getContainer().update(this,old_handler,handler,"handler");
|
||||
|
||||
|
||||
// if there is an old handler and it was started, stop it
|
||||
if (old_handler != null && isStarted())
|
||||
if (old_handler != null)
|
||||
{
|
||||
old_handler.stop();
|
||||
removeBean(old_handler);
|
||||
}
|
||||
|
||||
}
|
||||
catch(RuntimeException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch(Exception e)
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
/*
|
||||
* @see org.eclipse.thread.AbstractLifeCycle#doStart()
|
||||
*/
|
||||
@Override
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
if (_handler!=null)
|
||||
_handler.start();
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
/*
|
||||
* @see org.eclipse.thread.AbstractLifeCycle#doStop()
|
||||
*/
|
||||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
super.doStop();
|
||||
if (_handler!=null)
|
||||
_handler.stop();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
/*
|
||||
* @see org.eclipse.jetty.server.server.EventHandler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
||||
*/
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
if (_handler!=null && isStarted())
|
||||
if (_handler != null && isStarted())
|
||||
{
|
||||
_handler.handle(target,baseRequest, request, response);
|
||||
_handler.handle(target,baseRequest,request,response);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public void setServer(Server server)
|
||||
{
|
||||
Server old_server=getServer();
|
||||
if (server==old_server)
|
||||
Server old_server = getServer();
|
||||
if (server == old_server)
|
||||
return;
|
||||
|
||||
|
||||
if (isRunning())
|
||||
throw new IllegalStateException(RUNNING);
|
||||
|
||||
|
||||
super.setServer(server);
|
||||
|
||||
Handler h=getHandler();
|
||||
if (h!=null)
|
||||
|
||||
Handler h = getHandler();
|
||||
if (h != null)
|
||||
h.setServer(server);
|
||||
|
||||
if (server!=null && server!=old_server)
|
||||
server.getContainer().update(this, null,_handler, "handler");
|
||||
|
||||
if (server != null && server != old_server)
|
||||
server.getContainer().update(this,null,_handler,"handler");
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@SuppressWarnings(
|
||||
{ "rawtypes", "unchecked" })
|
||||
@Override
|
||||
protected Object expandChildren(Object list, Class byClass)
|
||||
{
|
||||
|
@ -167,8 +160,8 @@ public class HotSwapHandler extends AbstractHandlerContainer
|
|||
{
|
||||
if (!isStopped())
|
||||
throw new IllegalStateException("!STOPPED");
|
||||
Handler child=getHandler();
|
||||
if (child!=null)
|
||||
Handler child = getHandler();
|
||||
if (child != null)
|
||||
{
|
||||
setHandler(null);
|
||||
child.destroy();
|
||||
|
|
|
@ -79,7 +79,16 @@ public class SelectChannelConnector extends AbstractNIOConnector
|
|||
addBean(_manager,true);
|
||||
setAcceptors(Math.max(1,(Runtime.getRuntime().availableProcessors()+3)/4));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setThreadPool(ThreadPool pool)
|
||||
{
|
||||
super.setThreadPool(pool);
|
||||
// preserve start order
|
||||
removeBean(_manager);
|
||||
addBean(_manager,true);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public void accept(int acceptorID) throws IOException
|
||||
|
|
|
@ -39,7 +39,9 @@ import org.eclipse.jetty.util.IO;
|
|||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.StdErrLog;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Test;
|
||||
import org.junit.matchers.JUnitMatchers;
|
||||
|
||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
@ -1048,10 +1050,13 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
else
|
||||
out.println(avail);
|
||||
|
||||
for (int i=0;i<avail;i++)
|
||||
while (avail>0)
|
||||
{
|
||||
buf+=(char)in.read();
|
||||
|
||||
avail=in.available();
|
||||
avail=in.available();
|
||||
}
|
||||
|
||||
|
||||
out.println(avail);
|
||||
out.println(buf);
|
||||
out.close();
|
||||
|
@ -1098,9 +1103,9 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
||||
// skip header
|
||||
while(reader.readLine().length()>0);
|
||||
assertEquals(10,Integer.parseInt(reader.readLine()));
|
||||
assertThat(Integer.parseInt(reader.readLine()),Matchers.greaterThan(0));
|
||||
assertEquals(0,Integer.parseInt(reader.readLine()));
|
||||
assertEquals(20,Integer.parseInt(reader.readLine()));
|
||||
assertThat(Integer.parseInt(reader.readLine()),Matchers.greaterThan(0));
|
||||
assertEquals(0,Integer.parseInt(reader.readLine()));
|
||||
assertEquals("1234567890abcdefghijklmnopqrst",reader.readLine());
|
||||
|
||||
|
|
|
@ -439,6 +439,20 @@ public class ResponseTest
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZeroContent () throws Exception
|
||||
{
|
||||
Response response = new Response (new TestHttpConnection(connector, new ByteArrayEndPoint(), connector.getServer()));
|
||||
PrintWriter writer = response.getWriter();
|
||||
response.setContentLength(0);
|
||||
assertTrue(!response.isCommitted());
|
||||
assertTrue(!writer.checkError());
|
||||
writer.print("");
|
||||
assertTrue(!writer.checkError());
|
||||
assertTrue(response.isCommitted());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testHead() throws Exception
|
||||
{
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
package org.eclipse.jetty.server.handler;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -13,7 +10,6 @@ import java.net.Socket;
|
|||
import java.security.SecureRandom;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
|
@ -31,6 +27,9 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
|
|||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
/**
|
||||
* @version $Revision$ $Date$
|
||||
*/
|
||||
|
@ -85,7 +84,7 @@ public class ConnectHandlerSSLTest extends AbstractConnectHandlerTest
|
|||
output = sslSocket.getOutputStream();
|
||||
input = new BufferedReader(new InputStreamReader(sslSocket.getInputStream()));
|
||||
|
||||
request =
|
||||
request =
|
||||
"GET /echo HTTP/1.1\r\n" +
|
||||
"Host: " + hostPort + "\r\n" +
|
||||
"\r\n";
|
||||
|
@ -188,7 +187,7 @@ public class ConnectHandlerSSLTest extends AbstractConnectHandlerTest
|
|||
|
||||
public X509Certificate[] getAcceptedIssuers()
|
||||
{
|
||||
return null;
|
||||
return new X509Certificate[]{};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
//------------------------------------------------------------------------
|
||||
//Licensed under the Apache License, Version 2.0 (the "License");
|
||||
//you may not use this file except in compliance with the License.
|
||||
//You may obtain a copy of the License at
|
||||
//You may obtain a copy of the License at
|
||||
//http://www.apache.org/licenses/LICENSE-2.0
|
||||
//Unless required by applicable law or agreed to in writing, software
|
||||
//distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
@ -27,7 +27,6 @@ import java.io.OutputStream;
|
|||
import java.net.Socket;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
@ -36,7 +35,6 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.eclipse.jetty.io.AsyncEndPoint;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
|
@ -53,20 +51,18 @@ public class SSLCloseTest extends TestCase
|
|||
{
|
||||
public X509Certificate[] getAcceptedIssuers()
|
||||
{
|
||||
return null;
|
||||
return new X509Certificate[]{};
|
||||
}
|
||||
|
||||
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static final TrustManager[] s_dummyTrustManagers=new TrustManager[] { new CredulousTM() };
|
||||
|
||||
// ~ Methods
|
||||
|
@ -74,7 +70,7 @@ public class SSLCloseTest extends TestCase
|
|||
|
||||
/**
|
||||
* Feed the server the entire request at once.
|
||||
*
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testClose() throws Exception
|
||||
|
@ -83,7 +79,7 @@ public class SSLCloseTest extends TestCase
|
|||
SslSelectChannelConnector connector=new SslSelectChannelConnector();
|
||||
|
||||
String keystore = System.getProperty("user.dir")+File.separator+"src"+File.separator+"test"+File.separator+"resources"+File.separator+"keystore";
|
||||
|
||||
|
||||
connector.setPort(0);
|
||||
connector.getSslContextFactory().setKeyStorePath(keystore);
|
||||
connector.getSslContextFactory().setKeyStorePassword("storepwd");
|
||||
|
@ -92,7 +88,7 @@ public class SSLCloseTest extends TestCase
|
|||
server.setConnectors(new Connector[]
|
||||
{ connector });
|
||||
server.setHandler(new WriteHandler());
|
||||
|
||||
|
||||
server.start();
|
||||
|
||||
|
||||
|
@ -107,7 +103,7 @@ public class SSLCloseTest extends TestCase
|
|||
|
||||
os.write("GET /test HTTP/1.1\r\nHost:test\r\nConnection:close\r\n\r\n".getBytes());
|
||||
os.flush();
|
||||
|
||||
|
||||
BufferedReader in =new BufferedReader(new InputStreamReader(socket.getInputStream()));
|
||||
|
||||
String line;
|
||||
|
@ -123,7 +119,7 @@ public class SSLCloseTest extends TestCase
|
|||
|
||||
while ((line=in.readLine())!=null)
|
||||
System.err.println(line);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -137,7 +133,7 @@ public class SSLCloseTest extends TestCase
|
|||
response.setStatus(200);
|
||||
response.setHeader("test","value");
|
||||
__endp=(AsyncEndPoint)baseRequest.getConnection().getEndPoint();
|
||||
|
||||
|
||||
OutputStream out=response.getOutputStream();
|
||||
|
||||
String data = "Now is the time for all good men to come to the aid of the party.\n";
|
||||
|
|
|
@ -27,6 +27,7 @@ import javax.net.ssl.TrustManagerFactory;
|
|||
import org.eclipse.jetty.server.HttpServerTestBase;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
|
@ -135,4 +136,13 @@ public class SelectChannelServerSslTest extends HttpServerTestBase
|
|||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Ignore
|
||||
public void testAvailable() throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import javax.net.ssl.TrustManagerFactory;
|
|||
import org.eclipse.jetty.server.HttpServerTestBase;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
|
@ -75,4 +76,10 @@ public class SslSocketServerTest extends HttpServerTestBase
|
|||
// TODO this test uses URL, so noop for now
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Ignore
|
||||
public void testAvailable() throws Exception
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-servlet</artifactId>
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
package org.eclipse.jetty.servlet;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
|
@ -8,8 +12,7 @@ import javax.servlet.ServletException;
|
|||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eclipse.jetty.continuation.ContinuationSupport;
|
||||
|
@ -42,12 +45,13 @@ public class AsyncContextTest
|
|||
@Before
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
_connector.setMaxIdleTime(3000000);
|
||||
_connector.setMaxIdleTime(30000);
|
||||
_server.setConnectors(new Connector[]
|
||||
{ _connector });
|
||||
|
||||
_contextHandler.setContextPath("/");
|
||||
_contextHandler.addServlet(new ServletHolder(new TestServlet()),"/servletPath");
|
||||
_contextHandler.addServlet(new ServletHolder(new TestServlet()),"/path with spaces/servletPath");
|
||||
_contextHandler.addServlet(new ServletHolder(new TestServlet2()),"/servletPath2");
|
||||
_contextHandler.addServlet(new ServletHolder(new ForwardingServlet()),"/forward");
|
||||
_contextHandler.addServlet(new ServletHolder(new AsyncDispatchingServlet()),"/dispatchingServlet");
|
||||
|
@ -62,111 +66,102 @@ public class AsyncContextTest
|
|||
|
||||
@Test
|
||||
public void testSimpleAsyncContext() throws Exception
|
||||
{
|
||||
{
|
||||
String request = "GET /servletPath HTTP/1.1\r\n" + "Host: localhost\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n"
|
||||
+ "Connection: close\r\n" + "\r\n";
|
||||
|
||||
String responseString = _connector.getResponses(request);
|
||||
|
||||
BufferedReader br = new BufferedReader(new StringReader(responseString));
|
||||
|
||||
Assert.assertEquals("HTTP/1.1 200 OK",br.readLine());
|
||||
|
||||
br.readLine();// connection close
|
||||
br.readLine();// server
|
||||
br.readLine();// empty
|
||||
|
||||
Assert.assertEquals("servlet gets right path","doGet:getServletPath:/servletPath", br.readLine());
|
||||
Assert.assertEquals("async context gets right path in get","doGet:async:getServletPath:/servletPath", br.readLine());
|
||||
Assert.assertEquals("async context gets right path in async","async:run:attr:servletPath:/servletPath", br.readLine());
|
||||
BufferedReader br = parseHeader(responseString);
|
||||
|
||||
Assert.assertEquals("servlet gets right path","doGet:getServletPath:/servletPath",br.readLine());
|
||||
Assert.assertEquals("async context gets right path in get","doGet:async:getServletPath:/servletPath",br.readLine());
|
||||
Assert.assertEquals("async context gets right path in async","async:run:attr:servletPath:/servletPath",br.readLine());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testDispatchAsyncContext() throws Exception
|
||||
{
|
||||
{
|
||||
String request = "GET /servletPath?dispatch=true HTTP/1.1\r\n" + "Host: localhost\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n"
|
||||
+ "Connection: close\r\n" + "\r\n";
|
||||
String responseString = _connector.getResponses(request);
|
||||
|
||||
BufferedReader br = new BufferedReader(new StringReader(responseString));
|
||||
|
||||
Assert.assertEquals("HTTP/1.1 200 OK",br.readLine());
|
||||
|
||||
br.readLine();// connection close
|
||||
br.readLine();// server
|
||||
br.readLine();// empty
|
||||
|
||||
Assert.assertEquals("servlet gets right path","doGet:getServletPath:/servletPath2", br.readLine());
|
||||
Assert.assertEquals("async context gets right path in get","doGet:async:getServletPath:/servletPath2", br.readLine());
|
||||
Assert.assertEquals("servlet path attr is original","async:run:attr:servletPath:/servletPath", br.readLine());
|
||||
Assert.assertEquals("path info attr is correct","async:run:attr:pathInfo:null", br.readLine());
|
||||
Assert.assertEquals("query string attr is correct","async:run:attr:queryString:dispatch=true", br.readLine());
|
||||
Assert.assertEquals("context path attr is correct","async:run:attr:contextPath:", br.readLine());
|
||||
Assert.assertEquals("request uri attr is correct","async:run:attr:requestURI:/servletPath", br.readLine());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleWithContextAsyncContext() throws Exception
|
||||
{
|
||||
_contextHandler.setContextPath("/foo");
|
||||
|
||||
String request = "GET /foo/servletPath HTTP/1.1\r\n" + "Host: localhost\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n"
|
||||
+ "Connection: close\r\n" + "\r\n";
|
||||
String responseString = _connector.getResponses(request);
|
||||
|
||||
BufferedReader br = new BufferedReader(new StringReader(responseString));
|
||||
|
||||
Assert.assertEquals("HTTP/1.1 200 OK",br.readLine());
|
||||
|
||||
br.readLine();// connection close
|
||||
br.readLine();// server
|
||||
br.readLine();// empty
|
||||
|
||||
Assert.assertEquals("servlet gets right path","doGet:getServletPath:/servletPath", br.readLine());
|
||||
Assert.assertEquals("async context gets right path in get","doGet:async:getServletPath:/servletPath", br.readLine());
|
||||
Assert.assertEquals("async context gets right path in async","async:run:attr:servletPath:/servletPath", br.readLine());
|
||||
BufferedReader br = parseHeader(responseString);
|
||||
|
||||
Assert.assertEquals("servlet gets right path","doGet:getServletPath:/servletPath2",br.readLine());
|
||||
Assert.assertEquals("async context gets right path in get","doGet:async:getServletPath:/servletPath2",br.readLine());
|
||||
Assert.assertEquals("servlet path attr is original","async:run:attr:servletPath:/servletPath",br.readLine());
|
||||
Assert.assertEquals("path info attr is correct","async:run:attr:pathInfo:null",br.readLine());
|
||||
Assert.assertEquals("query string attr is correct","async:run:attr:queryString:dispatch=true",br.readLine());
|
||||
Assert.assertEquals("context path attr is correct","async:run:attr:contextPath:",br.readLine());
|
||||
Assert.assertEquals("request uri attr is correct","async:run:attr:requestURI:/servletPath",br.readLine());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDispatchWithContextAsyncContext() throws Exception
|
||||
{
|
||||
_contextHandler.setContextPath("/foo");
|
||||
|
||||
String request = "GET /foo/servletPath?dispatch=true HTTP/1.1\r\n" + "Host: localhost\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n"
|
||||
public void testDispatchAsyncContextEncodedPathAndQueryString() throws Exception
|
||||
{
|
||||
String request = "GET /path%20with%20spaces/servletPath?dispatch=true&queryStringWithEncoding=space%20space HTTP/1.1\r\n" + "Host: localhost\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n"
|
||||
+ "Connection: close\r\n" + "\r\n";
|
||||
String responseString = _connector.getResponses(request);
|
||||
|
||||
System.out.println(responseString);
|
||||
BufferedReader br = parseHeader(responseString);
|
||||
|
||||
BufferedReader br = new BufferedReader(new StringReader(responseString));
|
||||
|
||||
Assert.assertEquals("HTTP/1.1 200 OK",br.readLine());
|
||||
|
||||
br.readLine();// connection close
|
||||
br.readLine();// server
|
||||
br.readLine();// empty
|
||||
|
||||
Assert.assertEquals("servlet gets right path","doGet:getServletPath:/servletPath2", br.readLine());
|
||||
Assert.assertEquals("async context gets right path in get","doGet:async:getServletPath:/servletPath2", br.readLine());
|
||||
Assert.assertEquals("servlet path attr is original","async:run:attr:servletPath:/servletPath", br.readLine());
|
||||
Assert.assertEquals("path info attr is correct","async:run:attr:pathInfo:null", br.readLine());
|
||||
Assert.assertEquals("query string attr is correct","async:run:attr:queryString:dispatch=true", br.readLine());
|
||||
Assert.assertEquals("context path attr is correct","async:run:attr:contextPath:/foo", br.readLine());
|
||||
Assert.assertEquals("request uri attr is correct","async:run:attr:requestURI:/foo/servletPath", br.readLine());
|
||||
}
|
||||
assertThat("servlet gets right path",br.readLine(),equalTo("doGet:getServletPath:/servletPath2"));
|
||||
assertThat("async context gets right path in get",br.readLine(), equalTo("doGet:async:getServletPath:/servletPath2"));
|
||||
assertThat("servlet path attr is original",br.readLine(),equalTo("async:run:attr:servletPath:/path with spaces/servletPath"));
|
||||
assertThat("path info attr is correct",br.readLine(),equalTo("async:run:attr:pathInfo:null"));
|
||||
assertThat("query string attr is correct",br.readLine(),equalTo("async:run:attr:queryString:dispatch=true&queryStringWithEncoding=space%20space"));
|
||||
assertThat("context path attr is correct",br.readLine(),equalTo("async:run:attr:contextPath:"));
|
||||
assertThat("request uri attr is correct",br.readLine(),equalTo("async:run:attr:requestURI:/path%20with%20spaces/servletPath"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleWithContextAsyncContext() throws Exception
|
||||
{
|
||||
_contextHandler.setContextPath("/foo");
|
||||
|
||||
String request = "GET /foo/servletPath HTTP/1.1\r\n" + "Host: localhost\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n"
|
||||
+ "Connection: close\r\n" + "\r\n";
|
||||
|
||||
String responseString = _connector.getResponses(request);
|
||||
|
||||
BufferedReader br = parseHeader(responseString);
|
||||
|
||||
Assert.assertEquals("servlet gets right path","doGet:getServletPath:/servletPath",br.readLine());
|
||||
Assert.assertEquals("async context gets right path in get","doGet:async:getServletPath:/servletPath",br.readLine());
|
||||
Assert.assertEquals("async context gets right path in async","async:run:attr:servletPath:/servletPath",br.readLine());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDispatchWithContextAsyncContext() throws Exception
|
||||
{
|
||||
_contextHandler.setContextPath("/foo");
|
||||
|
||||
String request = "GET /foo/servletPath?dispatch=true HTTP/1.1\r\n" + "Host: localhost\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n"
|
||||
+ "Connection: close\r\n" + "\r\n";
|
||||
|
||||
String responseString = _connector.getResponses(request);
|
||||
|
||||
BufferedReader br = parseHeader(responseString);
|
||||
|
||||
Assert.assertEquals("servlet gets right path","doGet:getServletPath:/servletPath2",br.readLine());
|
||||
Assert.assertEquals("async context gets right path in get","doGet:async:getServletPath:/servletPath2",br.readLine());
|
||||
Assert.assertEquals("servlet path attr is original","async:run:attr:servletPath:/servletPath",br.readLine());
|
||||
Assert.assertEquals("path info attr is correct","async:run:attr:pathInfo:null",br.readLine());
|
||||
Assert.assertEquals("query string attr is correct","async:run:attr:queryString:dispatch=true",br.readLine());
|
||||
Assert.assertEquals("context path attr is correct","async:run:attr:contextPath:/foo",br.readLine());
|
||||
Assert.assertEquals("request uri attr is correct","async:run:attr:requestURI:/foo/servletPath",br.readLine());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDispatch() throws Exception
|
||||
{
|
||||
String request = "GET /forward HTTP/1.1\r\n" + "Host: localhost\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n" + "Connection: close\r\n"
|
||||
+ "\r\n";
|
||||
|
||||
String responseString = _connector.getResponses(request);
|
||||
|
||||
BufferedReader br = new BufferedReader(new StringReader(responseString));
|
||||
assertEquals("HTTP/1.1 200 OK",br.readLine());
|
||||
|
||||
br.readLine();// connection close
|
||||
br.readLine();// server
|
||||
br.readLine();// empty
|
||||
BufferedReader br = parseHeader(responseString);
|
||||
|
||||
assertThat("!ForwardingServlet",br.readLine(),equalTo("Dispatched back to ForwardingServlet"));
|
||||
}
|
||||
|
@ -176,16 +171,24 @@ public class AsyncContextTest
|
|||
{
|
||||
String request = "GET /forward?dispatchRequestResponse=true HTTP/1.1\r\n" + "Host: localhost\r\n"
|
||||
+ "Content-Type: application/x-www-form-urlencoded\r\n" + "Connection: close\r\n" + "\r\n";
|
||||
|
||||
String responseString = _connector.getResponses(request);
|
||||
|
||||
BufferedReader br = parseHeader(responseString);
|
||||
|
||||
assertThat("!AsyncDispatchingServlet",br.readLine(),equalTo("Dispatched back to AsyncDispatchingServlet"));
|
||||
}
|
||||
|
||||
private BufferedReader parseHeader(String responseString) throws IOException
|
||||
{
|
||||
BufferedReader br = new BufferedReader(new StringReader(responseString));
|
||||
|
||||
assertEquals("HTTP/1.1 200 OK",br.readLine());
|
||||
|
||||
br.readLine();// connection close
|
||||
br.readLine();// server
|
||||
br.readLine();// empty
|
||||
|
||||
assertThat("!AsyncDispatchingServlet",br.readLine(),equalTo("Dispatched back to AsyncDispatchingServlet"));
|
||||
return br;
|
||||
}
|
||||
|
||||
private class ForwardingServlet extends HttpServlet
|
||||
|
@ -206,28 +209,32 @@ public class AsyncContextTest
|
|||
}
|
||||
}
|
||||
|
||||
private class AsyncDispatchingServlet extends HttpServlet
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private class AsyncDispatchingServlet extends HttpServlet
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, final HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
Request request = (Request)req;
|
||||
if (request.getDispatcherType() == DispatcherType.ASYNC)
|
||||
{
|
||||
response.getOutputStream().print("Dispatched back to AsyncDispatchingServlet");
|
||||
}
|
||||
else
|
||||
{
|
||||
final AsyncContext asyncContext;
|
||||
if (request.getParameter("dispatchRequestResponse") != null)
|
||||
asyncContext = request.startAsync(request,response);
|
||||
else
|
||||
asyncContext = request.startAsync();
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, final HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
Request request = (Request)req;
|
||||
if (request.getDispatcherType() == DispatcherType.ASYNC)
|
||||
{
|
||||
response.getOutputStream().print("Dispatched back to AsyncDispatchingServlet");
|
||||
}
|
||||
else
|
||||
{
|
||||
final AsyncContext asyncContext;
|
||||
if (request.getParameter("dispatchRequestResponse") != null)
|
||||
{
|
||||
asyncContext = request.startAsync(request,response);
|
||||
}
|
||||
else
|
||||
{
|
||||
asyncContext = request.startAsync();
|
||||
}
|
||||
|
||||
new Thread(new DispatchingRunnable(asyncContext)).start();
|
||||
}
|
||||
new Thread(new DispatchingRunnable(asyncContext)).start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-servlets</artifactId>
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.io.UnsupportedEncodingException;
|
|||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
|
@ -67,12 +68,17 @@ public class GzipFilter extends UserAgentFilter
|
|||
protected Set<String> _mimeTypes;
|
||||
protected int _bufferSize=8192;
|
||||
protected int _minGzipSize=256;
|
||||
protected Set<String> _excluded;
|
||||
protected Set<String> _excludedAgents;
|
||||
protected Set<Pattern> _excludedAgentPatterns;
|
||||
protected Set<String> _excludedPaths;
|
||||
protected Set<Pattern> _excludedPathPatterns;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.servlets.UserAgentFilter#init(javax.servlet.FilterConfig)
|
||||
*/
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException
|
||||
{
|
||||
super.init(filterConfig);
|
||||
|
@ -93,21 +99,48 @@ public class GzipFilter extends UserAgentFilter
|
|||
while (tok.hasMoreTokens())
|
||||
_mimeTypes.add(tok.nextToken());
|
||||
}
|
||||
|
||||
tmp=filterConfig.getInitParameter("excludedAgents");
|
||||
if (tmp!=null)
|
||||
{
|
||||
_excluded=new HashSet<String>();
|
||||
_excludedAgents=new HashSet<String>();
|
||||
StringTokenizer tok = new StringTokenizer(tmp,",",false);
|
||||
while (tok.hasMoreTokens())
|
||||
_excluded.add(tok.nextToken());
|
||||
_excludedAgents.add(tok.nextToken());
|
||||
}
|
||||
|
||||
tmp=filterConfig.getInitParameter("excludeAgentPatterns");
|
||||
if (tmp!=null)
|
||||
{
|
||||
_excludedAgentPatterns=new HashSet<Pattern>();
|
||||
StringTokenizer tok = new StringTokenizer(tmp,",",false);
|
||||
while (tok.hasMoreTokens())
|
||||
_excludedAgentPatterns.add(Pattern.compile(tok.nextToken()));
|
||||
}
|
||||
|
||||
tmp=filterConfig.getInitParameter("excludePaths");
|
||||
if (tmp!=null)
|
||||
{
|
||||
_excludedPaths=new HashSet<String>();
|
||||
StringTokenizer tok = new StringTokenizer(tmp,",",false);
|
||||
while (tok.hasMoreTokens())
|
||||
_excludedPaths.add(tok.nextToken());
|
||||
}
|
||||
|
||||
tmp=filterConfig.getInitParameter("excludePathPatterns");
|
||||
if (tmp!=null)
|
||||
{
|
||||
_excludedPathPatterns=new HashSet<Pattern>();
|
||||
StringTokenizer tok = new StringTokenizer(tmp,",",false);
|
||||
while (tok.hasMoreTokens())
|
||||
_excludedPathPatterns.add(Pattern.compile(tok.nextToken()));
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.servlets.UserAgentFilter#destroy()
|
||||
*/
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
}
|
||||
|
@ -116,6 +149,7 @@ public class GzipFilter extends UserAgentFilter
|
|||
/**
|
||||
* @see org.eclipse.jetty.servlets.UserAgentFilter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
|
||||
*/
|
||||
@Override
|
||||
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
|
@ -126,14 +160,17 @@ public class GzipFilter extends UserAgentFilter
|
|||
if (ae != null && ae.indexOf("gzip")>=0 && !response.containsHeader("Content-Encoding")
|
||||
&& !HttpMethods.HEAD.equalsIgnoreCase(request.getMethod()))
|
||||
{
|
||||
if (_excluded!=null)
|
||||
String ua = getUserAgent(request);
|
||||
if (isExcludedAgent(ua))
|
||||
{
|
||||
String ua=getUserAgent(request);
|
||||
if (_excluded.contains(ua))
|
||||
{
|
||||
super.doFilter(request,response,chain);
|
||||
return;
|
||||
}
|
||||
super.doFilter(request,response,chain);
|
||||
return;
|
||||
}
|
||||
String requestURI = request.getRequestURI();
|
||||
if (isExcludedPath(requestURI))
|
||||
{
|
||||
super.doFilter(request,response,chain);
|
||||
return;
|
||||
}
|
||||
|
||||
final GzipResponseWrapper wrappedResponse=newGzipResponseWrapper(request,response);
|
||||
|
@ -181,7 +218,64 @@ public class GzipFilter extends UserAgentFilter
|
|||
super.doFilter(request,response,chain);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks to see if the UserAgent is excluded
|
||||
*
|
||||
* @param ua
|
||||
* the user agent
|
||||
* @return boolean true if excluded
|
||||
*/
|
||||
private boolean isExcludedAgent(String ua)
|
||||
{
|
||||
if (ua == null)
|
||||
return false;
|
||||
|
||||
if (_excludedAgents != null)
|
||||
{
|
||||
if (_excludedAgents.contains(ua))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (_excludedAgentPatterns != null)
|
||||
{
|
||||
for (Pattern pattern : _excludedAgentPatterns)
|
||||
{
|
||||
if (pattern.matcher(ua).matches())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the Path is excluded
|
||||
*
|
||||
* @param ua
|
||||
* the request uri
|
||||
* @return boolean true if excluded
|
||||
*/
|
||||
private boolean isExcludedPath(String requestURI)
|
||||
{
|
||||
if (requestURI == null)
|
||||
return false;
|
||||
if (_excludedPathPatterns != null)
|
||||
{
|
||||
for (Pattern pattern : _excludedPathPatterns)
|
||||
{
|
||||
if (pattern.matcher(requestURI).matches())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows derived implementations to replace ResponseWrapper implementation.
|
||||
*
|
||||
|
|
|
@ -27,6 +27,7 @@ import java.io.UnsupportedEncodingException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -460,7 +461,14 @@ public class MultiPartFilter implements Filter
|
|||
@Override
|
||||
public Map getParameterMap()
|
||||
{
|
||||
return Collections.unmodifiableMap(_params.toStringArrayMap());
|
||||
Map<String, String> cmap = new HashMap<String,String>();
|
||||
|
||||
for ( Object key : _params.keySet() )
|
||||
{
|
||||
cmap.put((String)key,getParameter((String)key));
|
||||
}
|
||||
|
||||
return Collections.unmodifiableMap(cmap);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
|
|
|
@ -597,12 +597,14 @@ public class ProxyServlet implements Servlet
|
|||
{
|
||||
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-Host",request.getHeader("Host"));
|
||||
exchange.addRequestHeader("X-Forwarded-Server",request.getLocalName());
|
||||
}
|
||||
|
||||
if (hasContent)
|
||||
{
|
||||
exchange.setRequestContentSource(in);
|
||||
}
|
||||
|
||||
customizeExchange(exchange, request);
|
||||
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
|
||||
package org.eclipse.jetty.servlets;
|
||||
|
@ -18,7 +18,6 @@ import java.util.Map;
|
|||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
|
@ -39,19 +38,20 @@ import javax.servlet.http.HttpServletRequest;
|
|||
* <dt>attribute</dt><dd>If set, then the request attribute of this name is set with the matched user agent string</dd>
|
||||
* <dt>cacheSize</dt><dd>The size of the user-agent cache, used to avoid reparsing of user agent strings. The entire cache is flushed
|
||||
* when this size is reached</dd>
|
||||
* <dt>userAgent</dt><dd>A regex {@link Pattern} to extract the essential elements of the user agent.
|
||||
* <dt>userAgent</dt><dd>A regex {@link Pattern} to extract the essential elements of the user agent.
|
||||
* The concatenation of matched pattern groups is used as the user agent name</dd>
|
||||
* <dl>
|
||||
* <dl>
|
||||
* An example value for pattern is <code>(?:Mozilla[^\(]*\(compatible;\s*+([^;]*);.*)|(?:.*?([^\s]+/[^\s]+).*)</code>. These two
|
||||
* pattern match the common compatibility user-agent strings and extract the real user agent, failing that, the first
|
||||
* element of the agent string is returned.
|
||||
*
|
||||
* element of the agent string is returned.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class UserAgentFilter implements Filter
|
||||
{
|
||||
private Pattern _pattern;
|
||||
private Map _agentCache = new ConcurrentHashMap();
|
||||
private static final String __defaultPattern = "(?:Mozilla[^\\(]*\\(compatible;\\s*+([^;]*);.*)|(?:.*?([^\\s]+/[^\\s]+).*)";
|
||||
private Pattern _pattern = Pattern.compile(__defaultPattern);
|
||||
private Map<String, String> _agentCache = new ConcurrentHashMap<String, String>();
|
||||
private int _agentCacheSize=1024;
|
||||
private String _attribute;
|
||||
|
||||
|
@ -70,7 +70,7 @@ public class UserAgentFilter implements Filter
|
|||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
|
||||
{
|
||||
if (_attribute!=null && _pattern!=null)
|
||||
{
|
||||
{
|
||||
String ua=getUserAgent(request);
|
||||
request.setAttribute(_attribute,ua);
|
||||
}
|
||||
|
@ -84,11 +84,11 @@ public class UserAgentFilter implements Filter
|
|||
public void init(FilterConfig filterConfig) throws ServletException
|
||||
{
|
||||
_attribute=filterConfig.getInitParameter("attribute");
|
||||
|
||||
|
||||
String p=filterConfig.getInitParameter("userAgent");
|
||||
if (p!=null)
|
||||
_pattern=Pattern.compile(p);
|
||||
|
||||
|
||||
String size=filterConfig.getInitParameter("cacheSize");
|
||||
if (size!=null)
|
||||
_agentCacheSize=Integer.parseInt(size);
|
||||
|
@ -100,7 +100,7 @@ public class UserAgentFilter implements Filter
|
|||
String ua=((HttpServletRequest)request).getHeader("User-Agent");
|
||||
return getUserAgent(ua);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get UserAgent.
|
||||
* The configured agent patterns are used to match against the passed user agent string.
|
||||
|
@ -111,37 +111,42 @@ public class UserAgentFilter implements Filter
|
|||
*/
|
||||
public String getUserAgent(String ua)
|
||||
{
|
||||
if (ua==null)
|
||||
if (ua == null)
|
||||
return null;
|
||||
|
||||
String tag = (String)_agentCache.get(ua);
|
||||
|
||||
|
||||
if (tag==null)
|
||||
String tag = _agentCache.get(ua);
|
||||
|
||||
if (tag == null)
|
||||
{
|
||||
Matcher matcher=_pattern.matcher(ua);
|
||||
if (matcher.matches())
|
||||
if (_pattern != null)
|
||||
{
|
||||
if(matcher.groupCount()>0)
|
||||
Matcher matcher = _pattern.matcher(ua);
|
||||
if (matcher.matches())
|
||||
{
|
||||
for (int g=1;g<=matcher.groupCount();g++)
|
||||
if (matcher.groupCount() > 0)
|
||||
{
|
||||
String group=matcher.group(g);
|
||||
if (group!=null)
|
||||
tag=tag==null?group:(tag+group);
|
||||
for (int g = 1; g <= matcher.groupCount(); g++)
|
||||
{
|
||||
String group = matcher.group(g);
|
||||
if (group != null)
|
||||
tag = tag == null ? group : tag + group;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tag = matcher.group();
|
||||
}
|
||||
}
|
||||
else
|
||||
tag=matcher.group();
|
||||
}
|
||||
else
|
||||
tag=ua;
|
||||
|
||||
if (_agentCache.size()>=_agentCacheSize)
|
||||
_agentCache.clear();
|
||||
_agentCache.put(ua,tag);
|
||||
if (tag == null)
|
||||
tag = ua;
|
||||
|
||||
if (_agentCache.size() >= _agentCacheSize)
|
||||
_agentCache.clear();
|
||||
_agentCache.put(ua, tag);
|
||||
}
|
||||
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -137,4 +137,26 @@ public class GzipFilterDefaultTest
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUserAgentExclusion() throws Exception
|
||||
{
|
||||
GzipTester tester = new GzipTester(testingdir);
|
||||
|
||||
FilterHolder holder = tester.setContentServlet(DefaultServlet.class);
|
||||
holder.setInitParameter("excludedAgents", "foo");
|
||||
tester.setUserAgent("foo");
|
||||
|
||||
int filesize = GzipResponseWrapper.DEFAULT_BUFFER_SIZE * 4;
|
||||
tester.prepareServerFile("file.txt",filesize);
|
||||
|
||||
try
|
||||
{
|
||||
tester.start();
|
||||
tester.assertIsResponseNotGzipCompressed("file.txt", filesize, HttpStatus.OK_200);
|
||||
}
|
||||
finally
|
||||
{
|
||||
tester.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,11 +50,14 @@ public class MultipartFilterTest
|
|||
assertNotNull(req.getParameter("fileup"));
|
||||
assertNotNull(req.getParameter("fileup"+MultiPartFilter.CONTENT_TYPE_SUFFIX));
|
||||
assertEquals(req.getParameter("fileup"+MultiPartFilter.CONTENT_TYPE_SUFFIX), "application/octet-stream");
|
||||
|
||||
|
||||
super.doPost(req, resp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
|
@ -245,6 +248,65 @@ public class MultipartFilterTest
|
|||
assertTrue(response.getContent().indexOf("brown cow")>=0);
|
||||
}
|
||||
|
||||
/*
|
||||
* see the testParameterMap test
|
||||
*
|
||||
*/
|
||||
public static class TestServletParameterMap extends DumpServlet
|
||||
{
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
|
||||
{
|
||||
assertEquals("How now brown cow.", req.getParameterMap().get("strupContent-Type: application/octet-stream"));
|
||||
|
||||
super.doPost(req, resp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that the getParameterMap() call is correctly unencoding the parameters in the
|
||||
* map that it returns.
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testParameterMap() throws Exception
|
||||
{
|
||||
// generated and parsed test
|
||||
HttpTester request = new HttpTester();
|
||||
HttpTester response = new HttpTester();
|
||||
|
||||
tester.addServlet(TestServletParameterMap.class,"/test2");
|
||||
|
||||
// test GET
|
||||
request.setMethod("POST");
|
||||
request.setVersion("HTTP/1.0");
|
||||
request.setHeader("Host","tester");
|
||||
request.setURI("/context/test2");
|
||||
|
||||
String boundary="XyXyXy";
|
||||
request.setHeader("Content-Type","multipart/form-data; boundary="+boundary);
|
||||
|
||||
|
||||
String content = "--" + boundary + "\r\n"+
|
||||
"Content-Disposition: form-data; name=\"fileup\"; filename=\"Diplomsko Delo Lektorirano KONČNA.doc\"\r\n"+
|
||||
"Content-Type: application/octet-stream\r\n\r\n"+
|
||||
"How now brown cow."+
|
||||
"\r\n--" + boundary + "\r\n"+
|
||||
"Content-Disposition: form-data; name=\"strup\""+
|
||||
"Content-Type: application/octet-stream\r\n\r\n"+
|
||||
"How now brown cow."+
|
||||
"\r\n--" + boundary + "--\r\n\r\n";
|
||||
|
||||
request.setContent(content);
|
||||
|
||||
response.parse(tester.getResponses(request.generate()));
|
||||
assertTrue(response.getMethod()==null);
|
||||
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
|
||||
assertTrue(response.getContent().indexOf("brown cow")>=0);
|
||||
}
|
||||
|
||||
public static class DumpServlet extends HttpServlet
|
||||
{
|
||||
private static final long serialVersionUID = 201012011130L;
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.io.File;
|
|||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -12,7 +13,6 @@ import javax.servlet.ServletOutputStream;
|
|||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import org.eclipse.jetty.client.ContentExchange;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
|
@ -30,21 +30,24 @@ import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
|||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
public class ProxyServletTest
|
||||
{
|
||||
private Server server;
|
||||
private Connector connector;
|
||||
private HttpClient client;
|
||||
private Server _server;
|
||||
private Connector _connector;
|
||||
private HttpClient _client;
|
||||
|
||||
public void init(HttpServlet servlet) throws Exception
|
||||
{
|
||||
server = new Server();
|
||||
_server = new Server();
|
||||
|
||||
connector = new SelectChannelConnector();
|
||||
server.addConnector(connector);
|
||||
_connector = new SelectChannelConnector();
|
||||
_server.addConnector(_connector);
|
||||
|
||||
HandlerCollection handlers = new HandlerCollection();
|
||||
server.setHandler(handlers);
|
||||
_server.setHandler(handlers);
|
||||
|
||||
ServletContextHandler proxyCtx = new ServletContextHandler(handlers, "/proxy", ServletContextHandler.NO_SESSIONS);
|
||||
ServletHolder proxyServletHolder = new ServletHolder(new ProxyServlet()
|
||||
|
@ -66,25 +69,49 @@ public class ProxyServletTest
|
|||
handlers.addHandler(proxyCtx);
|
||||
handlers.addHandler(appCtx);
|
||||
|
||||
server.start();
|
||||
_server.start();
|
||||
|
||||
client = new HttpClient();
|
||||
client.start();
|
||||
_client = new HttpClient();
|
||||
_client.start();
|
||||
}
|
||||
|
||||
@After
|
||||
public void destroy() throws Exception
|
||||
{
|
||||
if (client != null)
|
||||
client.stop();
|
||||
if (_client != null)
|
||||
_client.stop();
|
||||
|
||||
if (server != null)
|
||||
if (_server != null)
|
||||
{
|
||||
server.stop();
|
||||
server.join();
|
||||
_server.stop();
|
||||
_server.join();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testXForwardedHostHeader() throws Exception
|
||||
{
|
||||
init(new HttpServlet()
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
|
||||
{
|
||||
PrintWriter writer = resp.getWriter();
|
||||
writer.write(req.getHeader("X-Forwarded-Host"));
|
||||
writer.flush();
|
||||
}
|
||||
});
|
||||
|
||||
String url = "http://localhost:" + _connector.getLocalPort() + "/proxy/test";
|
||||
ContentExchange exchange = new ContentExchange();
|
||||
exchange.setURL(url);
|
||||
_client.send(exchange);
|
||||
exchange.waitForDone();
|
||||
assertThat("Response expected to contain content of X-Forwarded-Host Header from the request",exchange.getResponseContent(),equalTo("localhost:"
|
||||
+ _connector.getLocalPort()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBigDownloadWithSlowReader() throws Exception
|
||||
|
@ -101,6 +128,8 @@ public class ProxyServletTest
|
|||
|
||||
init(new HttpServlet()
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
|
@ -114,7 +143,7 @@ public class ProxyServletTest
|
|||
}
|
||||
});
|
||||
|
||||
String url = "http://localhost:" + connector.getLocalPort() + "/proxy" + "/test";
|
||||
String url = "http://localhost:" + _connector.getLocalPort() + "/proxy/test";
|
||||
ContentExchange exchange = new ContentExchange(true)
|
||||
{
|
||||
@Override
|
||||
|
@ -134,7 +163,7 @@ public class ProxyServletTest
|
|||
};
|
||||
exchange.setURL(url);
|
||||
long start = System.nanoTime();
|
||||
client.send(exchange);
|
||||
_client.send(exchange);
|
||||
Assert.assertEquals(HttpExchange.STATUS_COMPLETED, exchange.waitForDone());
|
||||
long elapsed = System.nanoTime() - start;
|
||||
Assert.assertEquals(HttpStatus.OK_200, exchange.getResponseStatus());
|
||||
|
|
|
@ -36,6 +36,7 @@ public class GzipTester
|
|||
{
|
||||
private Class<? extends GzipFilter> gzipFilterClass = GzipFilter.class;
|
||||
private String encoding = "ISO8859_1";
|
||||
private String userAgent = null;
|
||||
private ServletTester servletTester;
|
||||
private TestingDir testdir;
|
||||
|
||||
|
@ -61,6 +62,8 @@ public class GzipTester
|
|||
request.setVersion("HTTP/1.0");
|
||||
request.setHeader("Host","tester");
|
||||
request.setHeader("Accept-Encoding","gzip");
|
||||
if (this.userAgent != null)
|
||||
request.setHeader("User-Agent", this.userAgent);
|
||||
request.setURI("/context/" + requestedFilename);
|
||||
|
||||
// Issue the request
|
||||
|
@ -126,6 +129,8 @@ public class GzipTester
|
|||
request.setVersion("HTTP/1.0");
|
||||
request.setHeader("Host","tester");
|
||||
request.setHeader("Accept-Encoding","gzip");
|
||||
if (this.userAgent != null)
|
||||
request.setHeader("User-Agent", this.userAgent);
|
||||
request.setURI("/context/" + requestedFilename);
|
||||
|
||||
// Issue the request
|
||||
|
@ -211,6 +216,8 @@ public class GzipTester
|
|||
request.setVersion("HTTP/1.0");
|
||||
request.setHeader("Host","tester");
|
||||
request.setHeader("Accept-Encoding","gzip");
|
||||
if (this.userAgent != null)
|
||||
request.setHeader("User-Agent", this.userAgent);
|
||||
if (filename == null)
|
||||
request.setURI("/context/");
|
||||
else
|
||||
|
@ -384,6 +391,11 @@ public class GzipTester
|
|||
{
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
public void setUserAgent(String ua)
|
||||
{
|
||||
this.userAgent = ua;
|
||||
}
|
||||
|
||||
public void start() throws Exception
|
||||
{
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.eclipse.jetty.spdy</groupId>
|
||||
<artifactId>spdy-parent</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>Jetty :: SPDY :: Parent</name>
|
||||
|
||||
<modules>
|
||||
<module>spdy-core</module>
|
||||
<module>spdy-jetty</module>
|
||||
<module>spdy-jetty-http</module>
|
||||
<module>spdy-jetty-http-webapp</module>
|
||||
</modules>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>require-jdk7</id>
|
||||
<goals>
|
||||
<goal>enforce</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<rules>
|
||||
<requireJavaVersion>
|
||||
<version>[1.7,)</version>
|
||||
</requireJavaVersion>
|
||||
</rules>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>2.3.2</version>
|
||||
<configuration>
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-pmd-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.eclipse.jetty.spdy</groupId>
|
||||
<artifactId>spdy-parent</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spdy-core</artifactId>
|
||||
<name>Jetty :: SPDY :: Core</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>${slf4j-version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.eclipse.jetty.spdy;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* <p>A {@link ByteBuffer} pool.</p>
|
||||
* <p>Acquired buffers may be {@link #release(ByteBuffer) released} but they do not need to;
|
||||
* if they are released, they may be recycled and reused, otherwise they will be garbage
|
||||
* collected as usual.</p>
|
||||
*/
|
||||
public interface ByteBufferPool
|
||||
{
|
||||
/**
|
||||
* <p>Requests a {@link ByteBuffer} of the given size.</p>
|
||||
* <p>The returned buffer may have a bigger capacity than the size being
|
||||
* requested but it will have the limit set to the given size.</p>
|
||||
*
|
||||
* @param size the size of the buffer
|
||||
* @param direct whether the buffer must be direct or not
|
||||
* @return the requested buffer
|
||||
* @see #release(ByteBuffer)
|
||||
*/
|
||||
public ByteBuffer acquire(int size, boolean direct);
|
||||
|
||||
/**
|
||||
* <p>Returns a {@link ByteBuffer}, usually obtained with {@link #acquire(int, boolean)}
|
||||
* (but not necessarily), making it available for recycling and reuse.</p>
|
||||
*
|
||||
* @param buffer the buffer to return
|
||||
* @see #acquire(int, boolean)
|
||||
*/
|
||||
public void release(ByteBuffer buffer);
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (c) 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.eclipse.jetty.spdy;
|
||||
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
|
||||
public class CompressionDictionary
|
||||
{
|
||||
private static final byte[] DICTIONARY_V2 = ("" +
|
||||
"optionsgetheadpostputdeletetraceacceptaccept-charsetaccept-encodingaccept-" +
|
||||
"languageauthorizationexpectfromhostif-modified-sinceif-matchif-none-matchi" +
|
||||
"f-rangeif-unmodifiedsincemax-forwardsproxy-authorizationrangerefererteuser" +
|
||||
"-agent10010120020120220320420520630030130230330430530630740040140240340440" +
|
||||
"5406407408409410411412413414415416417500501502503504505accept-rangesageeta" +
|
||||
"glocationproxy-authenticatepublicretry-afterservervarywarningwww-authentic" +
|
||||
"ateallowcontent-basecontent-encodingcache-controlconnectiondatetrailertran" +
|
||||
"sfer-encodingupgradeviawarningcontent-languagecontent-lengthcontent-locati" +
|
||||
"oncontent-md5content-rangecontent-typeetagexpireslast-modifiedset-cookieMo" +
|
||||
"ndayTuesdayWednesdayThursdayFridaySaturdaySundayJanFebMarAprMayJunJulAugSe" +
|
||||
"pOctNovDecchunkedtext/htmlimage/pngimage/jpgimage/gifapplication/xmlapplic" +
|
||||
"ation/xhtmltext/plainpublicmax-agecharset=iso-8859-1utf-8gzipdeflateHTTP/1" +
|
||||
".1statusversionurl" +
|
||||
// Must be NUL terminated
|
||||
"\u0000").getBytes();
|
||||
|
||||
private static final byte[] DICTIONARY_V3 = ("" +
|
||||
"\u0000\u0000\u0000\u0007options\u0000\u0000\u0000\u0004head\u0000\u0000\u0000\u0004post" +
|
||||
"\u0000\u0000\u0000\u0003put\u0000\u0000\u0000\u0006delete\u0000\u0000\u0000\u0005trace" +
|
||||
"\u0000\u0000\u0000\u0006accept\u0000\u0000\u0000\u000Eaccept-charset" +
|
||||
"\u0000\u0000\u0000\u000Faccept-encoding\u0000\u0000\u0000\u000Faccept-language" +
|
||||
"\u0000\u0000\u0000\raccept-ranges\u0000\u0000\u0000\u0003age\u0000\u0000\u0000\u0005allow" +
|
||||
"\u0000\u0000\u0000\rauthorization\u0000\u0000\u0000\rcache-control" +
|
||||
"\u0000\u0000\u0000\nconnection\u0000\u0000\u0000\fcontent-base\u0000\u0000\u0000\u0010content-encoding" +
|
||||
"\u0000\u0000\u0000\u0010content-language\u0000\u0000\u0000\u000Econtent-length" +
|
||||
"\u0000\u0000\u0000\u0010content-location\u0000\u0000\u0000\u000Bcontent-md5" +
|
||||
"\u0000\u0000\u0000\rcontent-range\u0000\u0000\u0000\fcontent-type\u0000\u0000\u0000\u0004date" +
|
||||
"\u0000\u0000\u0000\u0004etag\u0000\u0000\u0000\u0006expect\u0000\u0000\u0000\u0007expires" +
|
||||
"\u0000\u0000\u0000\u0004from\u0000\u0000\u0000\u0004host\u0000\u0000\u0000\bif-match" +
|
||||
"\u0000\u0000\u0000\u0011if-modified-since\u0000\u0000\u0000\rif-none-match\u0000\u0000\u0000\bif-range" +
|
||||
"\u0000\u0000\u0000\u0013if-unmodified-since\u0000\u0000\u0000\rlast-modified" +
|
||||
"\u0000\u0000\u0000\blocation\u0000\u0000\u0000\fmax-forwards\u0000\u0000\u0000\u0006pragma" +
|
||||
"\u0000\u0000\u0000\u0012proxy-authenticate\u0000\u0000\u0000\u0013proxy-authorization" +
|
||||
"\u0000\u0000\u0000\u0005range\u0000\u0000\u0000\u0007referer\u0000\u0000\u0000\u000Bretry-after" +
|
||||
"\u0000\u0000\u0000\u0006server\u0000\u0000\u0000\u0002te\u0000\u0000\u0000\u0007trailer" +
|
||||
"\u0000\u0000\u0000\u0011transfer-encoding\u0000\u0000\u0000\u0007upgrade\u0000\u0000\u0000\nuser-agent" +
|
||||
"\u0000\u0000\u0000\u0004vary\u0000\u0000\u0000\u0003via\u0000\u0000\u0000\u0007warning" +
|
||||
"\u0000\u0000\u0000\u0010www-authenticate\u0000\u0000\u0000\u0006method\u0000\u0000\u0000\u0003get" +
|
||||
"\u0000\u0000\u0000\u0006status\u0000\u0000\u0000\u0006200 OK\u0000\u0000\u0000\u0007version" +
|
||||
"\u0000\u0000\u0000\bHTTP/1.1\u0000\u0000\u0000\u0003url\u0000\u0000\u0000\u0006public" +
|
||||
"\u0000\u0000\u0000\nset-cookie\u0000\u0000\u0000\nkeep-alive\u0000\u0000\u0000\u0006origin" +
|
||||
"100101201202205206300302303304305306307402405406407408409410411412413414415416417502504505" +
|
||||
"203 Non-Authoritative Information204 No Content301 Moved Permanently400 Bad Request401 Unauthorized" +
|
||||
"403 Forbidden404 Not Found500 Internal Server Error501 Not Implemented503 Service Unavailable" +
|
||||
"Jan Feb Mar Apr May Jun Jul Aug Sept Oct Nov Dec 00:00:00 Mon, Tue, Wed, Thu, Fri, Sat, Sun, GMT" +
|
||||
"chunked,text/html,image/png,image/jpg,image/gif,application/xml,application/xhtml+xml,text/plain," +
|
||||
"text/javascript,publicprivatemax-age=gzip,deflate,sdchcharset=utf-8charset=iso-8859-1,utf-,*,enq=0.")
|
||||
.getBytes();
|
||||
|
||||
public static byte[] get(short version)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
case SPDY.V2:
|
||||
return DICTIONARY_V2;
|
||||
case SPDY.V3:
|
||||
return DICTIONARY_V3;
|
||||
default:
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.eclipse.jetty.spdy;
|
||||
|
||||
import java.util.zip.ZipException;
|
||||
|
||||
public interface CompressionFactory
|
||||
{
|
||||
public Compressor newCompressor();
|
||||
|
||||
public Decompressor newDecompressor();
|
||||
|
||||
public interface Compressor
|
||||
{
|
||||
public void setInput(byte[] input);
|
||||
|
||||
public void setDictionary(byte[] dictionary);
|
||||
|
||||
public int compress(byte[] output);
|
||||
}
|
||||
|
||||
public interface Decompressor
|
||||
{
|
||||
public void setDictionary(byte[] dictionary);
|
||||
|
||||
public void setInput(byte[] input);
|
||||
|
||||
public int decompress(byte[] output) throws ZipException;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.eclipse.jetty.spdy;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.spdy.api.Handler;
|
||||
|
||||
public interface Controller<T>
|
||||
{
|
||||
public int write(ByteBuffer buffer, Handler<T> handler, T context);
|
||||
|
||||
public void close(boolean onlyOutput);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.eclipse.jetty.spdy;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.spdy.api.DataInfo;
|
||||
import org.eclipse.jetty.spdy.api.Handler;
|
||||
import org.eclipse.jetty.spdy.api.Session;
|
||||
import org.eclipse.jetty.spdy.frames.ControlFrame;
|
||||
|
||||
public interface ISession extends Session
|
||||
{
|
||||
/**
|
||||
* <p>Initiates the flush of data to the other peer.</p>
|
||||
* <p>Note that the flush may do nothing if, for example, there is nothing to flush, or
|
||||
* if the data to be flushed belong to streams that have their flow-control stalled.</p>
|
||||
*/
|
||||
public void flush();
|
||||
|
||||
public <C> void control(IStream stream, ControlFrame frame, long timeout, TimeUnit unit, Handler<C> handler, C context);
|
||||
|
||||
public <C> void data(IStream stream, DataInfo dataInfo, long timeout, TimeUnit unit, Handler<C> handler, C context);
|
||||
|
||||
public int getWindowSize();
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (c) 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.eclipse.jetty.spdy;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.spdy.api.SessionFrameListener;
|
||||
import org.eclipse.jetty.spdy.api.Stream;
|
||||
import org.eclipse.jetty.spdy.api.StreamFrameListener;
|
||||
import org.eclipse.jetty.spdy.api.SynInfo;
|
||||
import org.eclipse.jetty.spdy.frames.ControlFrame;
|
||||
import org.eclipse.jetty.spdy.frames.DataFrame;
|
||||
|
||||
/**
|
||||
* <p>The internal interface that represents a stream.</p>
|
||||
* <p>{@link IStream} contains additional methods used by a SPDY
|
||||
* implementation (and not by an application).</p>
|
||||
*/
|
||||
public interface IStream extends Stream
|
||||
{
|
||||
/**
|
||||
* <p>Senders of data frames need to know the current window size
|
||||
* to determine whether they can send more data.</p>
|
||||
*
|
||||
* @return the current window size for this stream.
|
||||
* @see #updateWindowSize(int)
|
||||
*/
|
||||
public int getWindowSize();
|
||||
|
||||
/**
|
||||
* <p>Updates the window size for this stream by the given amount,
|
||||
* that can be positive or negative.</p>
|
||||
* <p>Senders and recipients of data frames update the window size,
|
||||
* respectively, with negative values and positive values.</p>
|
||||
*
|
||||
* @param delta the signed amount the window size needs to be updated
|
||||
* @see #getWindowSize()
|
||||
*/
|
||||
public void updateWindowSize(int delta);
|
||||
|
||||
/**
|
||||
* @param listener the stream frame listener associated to this stream
|
||||
* as returned by {@link SessionFrameListener#onSyn(Stream, SynInfo)}
|
||||
*/
|
||||
public void setStreamFrameListener(StreamFrameListener listener);
|
||||
|
||||
/**
|
||||
* <p>A stream can be open, {@link #isHalfClosed() half closed} or
|
||||
* {@link #isClosed() closed} and this method updates the close state
|
||||
* of this stream.</p>
|
||||
* <p>If the stream is open, calling this method with a value of true
|
||||
* puts the stream into half closed state.</p>
|
||||
* <p>If the stream is half closed, calling this method with a value
|
||||
* of true puts the stream into closed state.</p>
|
||||
*
|
||||
* @param close whether the close state should be updated
|
||||
*/
|
||||
public void updateCloseState(boolean close);
|
||||
|
||||
/**
|
||||
* <p>Processes the given control frame,
|
||||
* for example by updating the stream's state or by calling listeners.</p>
|
||||
*
|
||||
* @param frame the control frame to process
|
||||
* @see #process(DataFrame, ByteBuffer)
|
||||
*/
|
||||
public void process(ControlFrame frame);
|
||||
|
||||
/**
|
||||
* <p>Processes the give data frame along with the given byte buffer,
|
||||
* for example by updating the stream's state or by calling listeners.</p>
|
||||
*
|
||||
* @param frame the data frame to process
|
||||
* @param data the byte buffer to process
|
||||
* @see #process(ControlFrame)
|
||||
*/
|
||||
public void process(DataFrame frame, ByteBuffer data);
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.eclipse.jetty.spdy;
|
||||
|
||||
public interface IdleListener
|
||||
{
|
||||
public void onIdle(boolean idle);
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (c) 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.eclipse.jetty.spdy;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.eclipse.jetty.spdy.api.Handler;
|
||||
|
||||
/**
|
||||
* <p>A {@link Promise} is a {@link Future} that allows a result or a failure to be set,
|
||||
* so that the {@link Future} will be {@link #isDone() done}.</p>
|
||||
*
|
||||
* @param <T> the type of the result object
|
||||
*/
|
||||
public class Promise<T> implements Handler<T>, Future<T>
|
||||
{
|
||||
private final CountDownLatch latch = new CountDownLatch(1);
|
||||
private boolean cancelled;
|
||||
private Throwable failure;
|
||||
private T promise;
|
||||
|
||||
@Override
|
||||
public void completed(T result)
|
||||
{
|
||||
this.promise = result;
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
this.failure = x;
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel(boolean mayInterruptIfRunning)
|
||||
{
|
||||
cancelled = true;
|
||||
latch.countDown();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled()
|
||||
{
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDone()
|
||||
{
|
||||
return cancelled || latch.getCount() == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get() throws InterruptedException, ExecutionException
|
||||
{
|
||||
latch.await();
|
||||
return result();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
|
||||
{
|
||||
latch.await(timeout, unit);
|
||||
return result();
|
||||
}
|
||||
|
||||
private T result() throws ExecutionException
|
||||
{
|
||||
Throwable failure = this.failure;
|
||||
if (failure != null)
|
||||
throw new ExecutionException(failure);
|
||||
return promise;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.eclipse.jetty.spdy;
|
||||
|
||||
import org.eclipse.jetty.spdy.api.SessionStatus;
|
||||
|
||||
public class SessionException extends RuntimeException
|
||||
{
|
||||
private final SessionStatus sessionStatus;
|
||||
|
||||
public SessionException(SessionStatus sessionStatus)
|
||||
{
|
||||
this.sessionStatus = sessionStatus;
|
||||
}
|
||||
|
||||
public SessionException(SessionStatus sessionStatus, String message)
|
||||
{
|
||||
super(message);
|
||||
this.sessionStatus = sessionStatus;
|
||||
}
|
||||
|
||||
public SessionException(SessionStatus sessionStatus, Throwable cause)
|
||||
{
|
||||
super(cause);
|
||||
this.sessionStatus = sessionStatus;
|
||||
}
|
||||
|
||||
public SessionStatus getSessionStatus()
|
||||
{
|
||||
return sessionStatus;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright (c) 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.eclipse.jetty.spdy;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
public class StandardByteBufferPool implements ByteBufferPool
|
||||
{
|
||||
private final ConcurrentMap<Integer, Queue<ByteBuffer>> directBuffers = new ConcurrentHashMap<>();
|
||||
private final ConcurrentMap<Integer, Queue<ByteBuffer>> heapBuffers = new ConcurrentHashMap<>();
|
||||
private final int factor;
|
||||
|
||||
public StandardByteBufferPool()
|
||||
{
|
||||
this(1024);
|
||||
}
|
||||
|
||||
public StandardByteBufferPool(int factor)
|
||||
{
|
||||
this.factor = factor;
|
||||
}
|
||||
|
||||
public ByteBuffer acquire(int size, boolean direct)
|
||||
{
|
||||
int bucket = bucketFor(size);
|
||||
ConcurrentMap<Integer, Queue<ByteBuffer>> buffers = buffersFor(direct);
|
||||
|
||||
ByteBuffer result = null;
|
||||
Queue<ByteBuffer> byteBuffers = buffers.get(bucket);
|
||||
if (byteBuffers != null)
|
||||
result = byteBuffers.poll();
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
int capacity = bucket * factor;
|
||||
result = direct ? ByteBuffer.allocateDirect(capacity) : ByteBuffer.allocate(capacity);
|
||||
}
|
||||
|
||||
result.clear();
|
||||
result.limit(size);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void release(ByteBuffer buffer)
|
||||
{
|
||||
int bucket = bucketFor(buffer.capacity());
|
||||
ConcurrentMap<Integer, Queue<ByteBuffer>> buffers = buffersFor(buffer.isDirect());
|
||||
|
||||
// Avoid to create a new queue every time, just to be discarded immediately
|
||||
Queue<ByteBuffer> byteBuffers = buffers.get(bucket);
|
||||
if (byteBuffers == null)
|
||||
{
|
||||
byteBuffers = new ConcurrentLinkedQueue<>();
|
||||
Queue<ByteBuffer> existing = buffers.putIfAbsent(bucket, byteBuffers);
|
||||
if (existing != null)
|
||||
byteBuffers = existing;
|
||||
}
|
||||
|
||||
buffer.clear();
|
||||
byteBuffers.offer(buffer);
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
directBuffers.clear();
|
||||
heapBuffers.clear();
|
||||
}
|
||||
|
||||
private int bucketFor(int size)
|
||||
{
|
||||
int bucket = size / factor;
|
||||
if (size % factor > 0)
|
||||
++bucket;
|
||||
return bucket;
|
||||
}
|
||||
|
||||
private ConcurrentMap<Integer, Queue<ByteBuffer>> buffersFor(boolean direct)
|
||||
{
|
||||
return direct ? directBuffers : heapBuffers;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (c) 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.eclipse.jetty.spdy;
|
||||
|
||||
import java.util.zip.DataFormatException;
|
||||
import java.util.zip.Deflater;
|
||||
import java.util.zip.Inflater;
|
||||
import java.util.zip.ZipException;
|
||||
|
||||
public class StandardCompressionFactory implements CompressionFactory
|
||||
{
|
||||
@Override
|
||||
public Compressor newCompressor()
|
||||
{
|
||||
return new StandardCompressor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Decompressor newDecompressor()
|
||||
{
|
||||
return new StandardDecompressor();
|
||||
}
|
||||
|
||||
public static class StandardCompressor implements Compressor
|
||||
{
|
||||
private final Deflater deflater = new Deflater();
|
||||
|
||||
@Override
|
||||
public void setInput(byte[] input)
|
||||
{
|
||||
deflater.setInput(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDictionary(byte[] dictionary)
|
||||
{
|
||||
deflater.setDictionary(dictionary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compress(byte[] output)
|
||||
{
|
||||
return deflater.deflate(output, 0, output.length, Deflater.SYNC_FLUSH);
|
||||
}
|
||||
}
|
||||
|
||||
public static class StandardDecompressor implements CompressionFactory.Decompressor
|
||||
{
|
||||
private final Inflater inflater = new Inflater();
|
||||
|
||||
@Override
|
||||
public void setDictionary(byte[] dictionary)
|
||||
{
|
||||
inflater.setDictionary(dictionary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInput(byte[] input)
|
||||
{
|
||||
inflater.setInput(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int decompress(byte[] output) throws ZipException
|
||||
{
|
||||
try
|
||||
{
|
||||
return inflater.inflate(output);
|
||||
}
|
||||
catch (DataFormatException x)
|
||||
{
|
||||
throw (ZipException)new ZipException().initCause(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,337 @@
|
|||
/*
|
||||
* Copyright (c) 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.eclipse.jetty.spdy;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.eclipse.jetty.spdy.api.ByteBufferDataInfo;
|
||||
import org.eclipse.jetty.spdy.api.DataInfo;
|
||||
import org.eclipse.jetty.spdy.api.Handler;
|
||||
import org.eclipse.jetty.spdy.api.HeadersInfo;
|
||||
import org.eclipse.jetty.spdy.api.ReplyInfo;
|
||||
import org.eclipse.jetty.spdy.api.RstInfo;
|
||||
import org.eclipse.jetty.spdy.api.Session;
|
||||
import org.eclipse.jetty.spdy.api.Stream;
|
||||
import org.eclipse.jetty.spdy.api.StreamFrameListener;
|
||||
import org.eclipse.jetty.spdy.api.StreamStatus;
|
||||
import org.eclipse.jetty.spdy.frames.ControlFrame;
|
||||
import org.eclipse.jetty.spdy.frames.DataFrame;
|
||||
import org.eclipse.jetty.spdy.frames.HeadersFrame;
|
||||
import org.eclipse.jetty.spdy.frames.SynReplyFrame;
|
||||
import org.eclipse.jetty.spdy.frames.SynStreamFrame;
|
||||
import org.eclipse.jetty.spdy.frames.WindowUpdateFrame;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class StandardStream implements IStream
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(Stream.class);
|
||||
private final Map<String, Object> attributes = new ConcurrentHashMap<>();
|
||||
private final SynStreamFrame frame;
|
||||
private final ISession session;
|
||||
private final AtomicInteger windowSize;
|
||||
private volatile StreamFrameListener listener;
|
||||
private volatile boolean opened;
|
||||
private volatile boolean halfClosed;
|
||||
private volatile boolean closed;
|
||||
|
||||
public StandardStream(SynStreamFrame frame, ISession session, int windowSize)
|
||||
{
|
||||
this.frame = frame;
|
||||
this.session = session;
|
||||
this.windowSize = new AtomicInteger(windowSize);
|
||||
this.halfClosed = frame.isClose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId()
|
||||
{
|
||||
return frame.getStreamId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getPriority()
|
||||
{
|
||||
return frame.getPriority();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWindowSize()
|
||||
{
|
||||
return windowSize.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateWindowSize(int delta)
|
||||
{
|
||||
int size = windowSize.addAndGet(delta);
|
||||
logger.debug("Updated window size by {}, new window size {}", delta, size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session getSession()
|
||||
{
|
||||
return session;
|
||||
}
|
||||
|
||||
public boolean isHalfClosed()
|
||||
{
|
||||
return halfClosed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAttribute(String key)
|
||||
{
|
||||
return attributes.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String key, Object value)
|
||||
{
|
||||
attributes.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object removeAttribute(String key)
|
||||
{
|
||||
return attributes.remove(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStreamFrameListener(StreamFrameListener listener)
|
||||
{
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCloseState(boolean close)
|
||||
{
|
||||
if (close)
|
||||
{
|
||||
if (isHalfClosed())
|
||||
closed = true;
|
||||
else
|
||||
halfClosed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(ControlFrame frame)
|
||||
{
|
||||
switch (frame.getType())
|
||||
{
|
||||
case SYN_STREAM:
|
||||
{
|
||||
opened = true;
|
||||
break;
|
||||
}
|
||||
case SYN_REPLY:
|
||||
{
|
||||
opened = true;
|
||||
SynReplyFrame synReply = (SynReplyFrame)frame;
|
||||
updateCloseState(synReply.isClose());
|
||||
ReplyInfo replyInfo = new ReplyInfo(synReply.getHeaders(), synReply.isClose());
|
||||
notifyOnReply(replyInfo);
|
||||
break;
|
||||
}
|
||||
case HEADERS:
|
||||
{
|
||||
HeadersFrame headers = (HeadersFrame)frame;
|
||||
updateCloseState(headers.isClose());
|
||||
HeadersInfo headersInfo = new HeadersInfo(headers.getHeaders(), headers.isClose(), headers.isResetCompression());
|
||||
notifyOnHeaders(headersInfo);
|
||||
break;
|
||||
}
|
||||
case WINDOW_UPDATE:
|
||||
{
|
||||
WindowUpdateFrame windowUpdate = (WindowUpdateFrame)frame;
|
||||
updateWindowSize(windowUpdate.getWindowDelta());
|
||||
break;
|
||||
}
|
||||
case RST_STREAM:
|
||||
{
|
||||
// TODO:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
session.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(DataFrame frame, ByteBuffer data)
|
||||
{
|
||||
if (!opened)
|
||||
{
|
||||
session.rst(new RstInfo(getId(), StreamStatus.PROTOCOL_ERROR));
|
||||
return;
|
||||
}
|
||||
|
||||
updateCloseState(frame.isClose());
|
||||
|
||||
ByteBufferDataInfo dataInfo = new ByteBufferDataInfo(data, frame.isClose(), frame.isCompress())
|
||||
{
|
||||
@Override
|
||||
public void consume(int delta)
|
||||
{
|
||||
super.consume(delta);
|
||||
|
||||
// This is the algorithm for flow control.
|
||||
// This method may be called multiple times with delta=1, but we only send a window
|
||||
// update when the whole dataInfo has been consumed.
|
||||
// Other policies may be to send window updates when consumed() is greater than
|
||||
// a certain threshold, etc. but for now the policy is not pluggable for simplicity.
|
||||
// Note that the frequency of window updates depends on the read buffer, that
|
||||
// should not be too smaller than the window size to avoid frequent window updates.
|
||||
// Therefore, a pluggable policy should be able to modify the read buffer capacity.
|
||||
if (consumed() == length() && !isClosed())
|
||||
windowUpdate(length());
|
||||
}
|
||||
};
|
||||
notifyOnData(dataInfo);
|
||||
session.flush();
|
||||
}
|
||||
|
||||
private void windowUpdate(int delta)
|
||||
{
|
||||
if (delta > 0)
|
||||
{
|
||||
WindowUpdateFrame windowUpdateFrame = new WindowUpdateFrame(session.getVersion(), getId(), delta);
|
||||
session.control(this, windowUpdateFrame, 0, TimeUnit.MILLISECONDS, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyOnReply(ReplyInfo replyInfo)
|
||||
{
|
||||
final StreamFrameListener listener = this.listener;
|
||||
try
|
||||
{
|
||||
if (listener != null)
|
||||
{
|
||||
logger.debug("Invoking reply callback with {} on listener {}", replyInfo, listener);
|
||||
listener.onReply(this, replyInfo);
|
||||
}
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
logger.info("Exception while notifying listener " + listener, x);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyOnHeaders(HeadersInfo headersInfo)
|
||||
{
|
||||
final StreamFrameListener listener = this.listener;
|
||||
try
|
||||
{
|
||||
if (listener != null)
|
||||
{
|
||||
logger.debug("Invoking headers callback with {} on listener {}", frame, listener);
|
||||
listener.onHeaders(this, headersInfo);
|
||||
}
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
logger.info("Exception while notifying listener " + listener, x);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyOnData(DataInfo dataInfo)
|
||||
{
|
||||
final StreamFrameListener listener = this.listener;
|
||||
try
|
||||
{
|
||||
if (listener != null)
|
||||
{
|
||||
logger.debug("Invoking data callback with {} on listener {}", dataInfo, listener);
|
||||
listener.onData(this, dataInfo);
|
||||
logger.debug("Invoked data callback with {} on listener {}", dataInfo, listener);
|
||||
}
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
logger.info("Exception while notifying listener " + listener, x);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<Void> reply(ReplyInfo replyInfo)
|
||||
{
|
||||
Promise<Void> result = new Promise<>();
|
||||
reply(replyInfo, 0, TimeUnit.MILLISECONDS, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reply(ReplyInfo replyInfo, long timeout, TimeUnit unit, Handler<Void> handler)
|
||||
{
|
||||
updateCloseState(replyInfo.isClose());
|
||||
SynReplyFrame frame = new SynReplyFrame(session.getVersion(), replyInfo.getFlags(), getId(), replyInfo.getHeaders());
|
||||
session.control(this, frame, timeout, unit, handler, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<Void> data(DataInfo dataInfo)
|
||||
{
|
||||
Promise<Void> result = new Promise<>();
|
||||
data(dataInfo, 0, TimeUnit.MILLISECONDS, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void data(DataInfo dataInfo, long timeout, TimeUnit unit, Handler<Void> handler)
|
||||
{
|
||||
// Cannot update the close state here, because the data that we send may
|
||||
// be flow controlled, so we need the stream to update the window size.
|
||||
session.data(this, dataInfo, timeout, unit, handler, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<Void> headers(HeadersInfo headersInfo)
|
||||
{
|
||||
Promise<Void> result = new Promise<>();
|
||||
headers(headersInfo, 0, TimeUnit.MILLISECONDS, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void headers(HeadersInfo headersInfo, long timeout, TimeUnit unit, Handler<Void> handler)
|
||||
{
|
||||
updateCloseState(headersInfo.isClose());
|
||||
HeadersFrame frame = new HeadersFrame(session.getVersion(), headersInfo.getFlags(), getId(), headersInfo.getHeaders());
|
||||
session.control(this, frame, timeout, unit, handler, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClosed()
|
||||
{
|
||||
return closed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("stream=%d v%d closed=%s", getId(), session.getVersion(), isClosed() ? "true" : isHalfClosed() ? "half" : "false");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.eclipse.jetty.spdy;
|
||||
|
||||
import org.eclipse.jetty.spdy.api.StreamStatus;
|
||||
|
||||
public class StreamException extends RuntimeException
|
||||
{
|
||||
private final int streamId;
|
||||
private final StreamStatus streamStatus;
|
||||
|
||||
public StreamException(int streamId, StreamStatus streamStatus)
|
||||
{
|
||||
this.streamId = streamId;
|
||||
this.streamStatus = streamStatus;
|
||||
}
|
||||
|
||||
public StreamException(int streamId, StreamStatus streamStatus, String message)
|
||||
{
|
||||
super(message);
|
||||
this.streamId = streamId;
|
||||
this.streamStatus = streamStatus;
|
||||
}
|
||||
|
||||
public int getStreamId()
|
||||
{
|
||||
return streamId;
|
||||
}
|
||||
|
||||
public StreamStatus getStreamStatus()
|
||||
{
|
||||
return streamStatus;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.eclipse.jetty.spdy.api;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* <p>Specialized {@link DataInfo} for {@link ByteBuffer} content.</p>
|
||||
*/
|
||||
public class ByteBufferDataInfo extends DataInfo
|
||||
{
|
||||
private final ByteBuffer buffer;
|
||||
private final int length;
|
||||
|
||||
public ByteBufferDataInfo(ByteBuffer buffer, boolean close)
|
||||
{
|
||||
this(buffer, close, false);
|
||||
}
|
||||
|
||||
public ByteBufferDataInfo(ByteBuffer buffer, boolean close, boolean compress)
|
||||
{
|
||||
super(close, compress);
|
||||
this.buffer = buffer;
|
||||
this.length = buffer.remaining();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length()
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available()
|
||||
{
|
||||
return buffer.remaining();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readInto(ByteBuffer output)
|
||||
{
|
||||
int space = output.remaining();
|
||||
if (available() > space)
|
||||
{
|
||||
int limit = buffer.limit();
|
||||
buffer.limit(buffer.position() + space);
|
||||
output.put(buffer);
|
||||
buffer.limit(limit);
|
||||
}
|
||||
else
|
||||
{
|
||||
space = buffer.remaining();
|
||||
output.put(buffer);
|
||||
}
|
||||
return space;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.eclipse.jetty.spdy.api;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* <p>Specialized {@link DataInfo} for byte array content.</p>
|
||||
*/
|
||||
public class BytesDataInfo extends DataInfo
|
||||
{
|
||||
private byte[] bytes;
|
||||
private int offset;
|
||||
|
||||
public BytesDataInfo(byte[] bytes, boolean close)
|
||||
{
|
||||
this(bytes, close, false);
|
||||
}
|
||||
|
||||
public BytesDataInfo(byte[] bytes, boolean close, boolean compress)
|
||||
{
|
||||
super(close, compress);
|
||||
this.bytes = bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length()
|
||||
{
|
||||
return bytes.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available()
|
||||
{
|
||||
return length() - offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readInto(ByteBuffer output)
|
||||
{
|
||||
int space = output.remaining();
|
||||
int length = Math.min(available(), space);
|
||||
output.put(bytes, offset, length);
|
||||
offset += length;
|
||||
return length;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,249 @@
|
|||
/*
|
||||
* Copyright (c) 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.eclipse.jetty.spdy.api;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* <p>A container for DATA frames metadata and content bytes.</p>
|
||||
* <p>Specialized subclasses (like {@link StringDataInfo}) may be used by applications
|
||||
* to send specific types of content.</p>
|
||||
* <p>Applications may send multiple instances of {@link DataInfo}, usually of the same
|
||||
* type, via {@link Stream#data(DataInfo)}. The last instance must have the
|
||||
* {@link #isClose() close flag} set, so that the client knows that no more content is
|
||||
* expected.</p>
|
||||
* <p>Receivers of {@link DataInfo} via {@link StreamFrameListener#onData(Stream, DataInfo)}
|
||||
* have two different APIs to read the data content bytes: a {@link #readInto(ByteBuffer) read}
|
||||
* API that does not interact with flow control, and a {@link #consumeInto(ByteBuffer) drain}
|
||||
* API that interacts with flow control.</p>
|
||||
* <p>Flow control is defined so that when the sender wants to sends a number of bytes larger
|
||||
* than the {@link Settings.ID#INITIAL_WINDOW_SIZE} value, it will stop sending as soon as it
|
||||
* has sent a number of bytes equal to the window size. The receiver has to <em>consume</em>
|
||||
* the data bytes that it received in order to tell the sender to send more bytes.</p>
|
||||
* <p>Consuming the data bytes can be done only via {@link #consumeInto(ByteBuffer)} or by a combination
|
||||
* of {@link #readInto(ByteBuffer)} and {@link #consume(int)} (possibly at different times).</p>
|
||||
*/
|
||||
public abstract class DataInfo
|
||||
{
|
||||
/**
|
||||
* <p>Flag that indicates that this {@link DataInfo} is the last frame in the stream.</p>
|
||||
*
|
||||
* @see #isClose()
|
||||
* @see #getFlags()
|
||||
*/
|
||||
public final static byte FLAG_CLOSE = 1;
|
||||
/**
|
||||
* <p>Flag that indicates that this {@link DataInfo}'s data is compressed.</p>
|
||||
*
|
||||
* @see #isCompress()
|
||||
* @see #getFlags()
|
||||
*/
|
||||
public final static byte FLAG_COMPRESS = 2;
|
||||
|
||||
private final AtomicInteger consumed = new AtomicInteger();
|
||||
private boolean close;
|
||||
private boolean compress;
|
||||
|
||||
/**
|
||||
* <p>Creates a new {@link DataInfo} with the given close flag and no compression flag.</p>
|
||||
*
|
||||
* @param close the value of the close flag
|
||||
*/
|
||||
public DataInfo(boolean close)
|
||||
{
|
||||
setClose(close);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Creates a new {@link DataInfo} with the given close flag and given compression flag.</p>
|
||||
*
|
||||
* @param close the close flag
|
||||
* @param compress the compress flag
|
||||
*/
|
||||
public DataInfo(boolean close, boolean compress)
|
||||
{
|
||||
setClose(close);
|
||||
setCompress(compress);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value of the compress flag
|
||||
* @see #setCompress(boolean)
|
||||
*/
|
||||
public boolean isCompress()
|
||||
{
|
||||
return compress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param compress the value of the compress flag
|
||||
* @see #isCompress()
|
||||
*/
|
||||
public void setCompress(boolean compress)
|
||||
{
|
||||
this.compress = compress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value of the close flag
|
||||
* @see #setClose(boolean)
|
||||
*/
|
||||
public boolean isClose()
|
||||
{
|
||||
return close;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param close the value of the close flag
|
||||
* @see #isClose()
|
||||
*/
|
||||
public void setClose(boolean close)
|
||||
{
|
||||
this.close = close;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the close and compress flags as integer
|
||||
* @see #FLAG_CLOSE
|
||||
* @see #FLAG_COMPRESS
|
||||
*/
|
||||
public byte getFlags()
|
||||
{
|
||||
byte flags = isClose() ? FLAG_CLOSE : 0;
|
||||
flags |= isCompress() ? FLAG_COMPRESS : 0;
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the total number of content bytes
|
||||
* @see #available()
|
||||
*/
|
||||
public abstract int length();
|
||||
|
||||
/**
|
||||
* <p>Returns the available content bytes that can be read via {@link #readInto(ByteBuffer)}.</p>
|
||||
* <p>Each invocation to {@link #readInto(ByteBuffer)} modifies the value returned by this method,
|
||||
* until no more content bytes are available.</p>
|
||||
*
|
||||
* @return the available content bytes
|
||||
* @see #readInto(ByteBuffer)
|
||||
*/
|
||||
public abstract int available();
|
||||
|
||||
/**
|
||||
* <p>Copies the content bytes of this {@link DataInfo} into the given {@link ByteBuffer}.</p>
|
||||
* <p>If the given {@link ByteBuffer} cannot contain the whole content of this {@link DataInfo}
|
||||
* then after the read {@link #available()} will return a positive value, and further content
|
||||
* may be retrieved by invoking again this method with a new output buffer.</p>
|
||||
*
|
||||
* @param output the {@link ByteBuffer} to copy to bytes into
|
||||
* @return the number of bytes copied
|
||||
* @see #available()
|
||||
* @see #consumeInto(ByteBuffer)
|
||||
*/
|
||||
public abstract int readInto(ByteBuffer output);
|
||||
|
||||
/**
|
||||
* <p>Reads and consumes the content bytes of this {@link DataInfo} into the given {@link ByteBuffer}.</p>
|
||||
*
|
||||
* @param output the {@link ByteBuffer} to copy to bytes into
|
||||
* @return the number of bytes copied
|
||||
* @see #consume(int)
|
||||
*/
|
||||
public int consumeInto(ByteBuffer output)
|
||||
{
|
||||
int read = readInto(output);
|
||||
consume(read);
|
||||
return read;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Consumes the given number of bytes from this {@link DataInfo}.</p>
|
||||
*
|
||||
* @param delta the number of bytes consumed
|
||||
*/
|
||||
public void consume(int delta)
|
||||
{
|
||||
if (delta < 0)
|
||||
throw new IllegalArgumentException();
|
||||
int read = length() - available();
|
||||
int newConsumed = consumed() + delta;
|
||||
// if (newConsumed > read)
|
||||
// throw new IllegalStateException("Consuming without reading: consumed " + newConsumed + " but only read " + read);
|
||||
consumed.addAndGet(delta);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of bytes consumed
|
||||
*/
|
||||
public int consumed()
|
||||
{
|
||||
return consumed.get();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param charset the charset used to convert the bytes
|
||||
* @param consume whether to consume the content
|
||||
* @return a String with the content of this {@link DataInfo}
|
||||
*/
|
||||
public String asString(String charset, boolean consume)
|
||||
{
|
||||
ByteBuffer buffer = asByteBuffer(consume);
|
||||
return Charset.forName(charset).decode(buffer).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a byte array with the content of this {@link DataInfo}
|
||||
* @param consume whether to consume the content
|
||||
*/
|
||||
public byte[] asBytes(boolean consume)
|
||||
{
|
||||
ByteBuffer buffer = asByteBuffer(consume);
|
||||
byte[] result = new byte[buffer.remaining()];
|
||||
buffer.get(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a {@link ByteBuffer} with the content of this {@link DataInfo}
|
||||
* @param consume whether to consume the content
|
||||
*/
|
||||
public ByteBuffer asByteBuffer(boolean consume)
|
||||
{
|
||||
ByteBuffer buffer = allocate(available());
|
||||
if (consume)
|
||||
consumeInto(buffer);
|
||||
else
|
||||
readInto(buffer);
|
||||
buffer.flip();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
protected ByteBuffer allocate(int size)
|
||||
{
|
||||
return ByteBuffer.allocate(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("DATA @%x available=%d consumed=%d close=%b compress=%b", hashCode(), available(), consumed(), isClose(), isCompress());
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue