();
-
- // Set the starting ciphers - either from the included or enabled list
- if (_includeCipherSuites!=null)
- {
- // Use only the supported included ciphers
- for (String cipherSuite : supportedCipherSuites)
- if (_includeCipherSuites.contains(cipherSuite))
- selected_ciphers.add(cipherSuite);
- }
- else
- selected_ciphers.addAll(Arrays.asList(enabledCipherSuites));
-
-
- // Remove any excluded ciphers
- if (_excludeCipherSuites != null)
- selected_ciphers.removeAll(_excludeCipherSuites);
- return selected_ciphers.toArray(new String[selected_ciphers.size()]);
- }
-
- /* ------------------------------------------------------------ */
- /**
- * Check if the lifecycle has been started and throw runtime exception
- */
- protected void checkNotStarted()
- {
- if (isStarted())
- throw new IllegalStateException("Cannot modify configuration when "+getState());
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @return true if CRL Distribution Points support is enabled
- */
- public boolean isEnableCRLDP()
- {
- return _enableCRLDP;
- }
-
- /* ------------------------------------------------------------ */
- /** Enables CRL Distribution Points Support
- * @param enableCRLDP true - turn on, false - turns off
- */
- public void setEnableCRLDP(boolean enableCRLDP)
- {
- checkNotStarted();
-
- _enableCRLDP = enableCRLDP;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @return true if On-Line Certificate Status Protocol support is enabled
- */
- public boolean isEnableOCSP()
- {
- return _enableOCSP;
- }
-
- /* ------------------------------------------------------------ */
- /** Enables On-Line Certificate Status Protocol support
- * @param enableOCSP true - turn on, false - turn off
- */
- public void setEnableOCSP(boolean enableOCSP)
- {
- checkNotStarted();
-
- _enableOCSP = enableOCSP;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @return Location of the OCSP Responder
- */
- public String getOcspResponderURL()
- {
- return _ocspResponderURL;
- }
-
- /* ------------------------------------------------------------ */
- /** Set the location of the OCSP Responder.
- * @param ocspResponderURL location of the OCSP Responder
- */
- public void setOcspResponderURL(String ocspResponderURL)
- {
- checkNotStarted();
-
- _ocspResponderURL = ocspResponderURL;
- }
-
- /* ------------------------------------------------------------ */
- /** Set the key store.
- * @param keyStore the key store to set
- */
- public void setKeyStore(KeyStore keyStore)
- {
- checkNotStarted();
-
- _keyStore = keyStore;
- }
-
- /* ------------------------------------------------------------ */
- /** Set the trust store.
- * @param trustStore the trust store to set
- */
- public void setTrustStore(KeyStore trustStore)
- {
- checkNotStarted();
-
- _trustStore = trustStore;
- }
-
- /* ------------------------------------------------------------ */
- /** Set the key store resource.
- * @param resource the key store resource to set
- */
- public void setKeyStoreResource(Resource resource)
- {
- checkNotStarted();
-
- try
- {
- _keyStoreInputStream = resource.getInputStream();
- }
- catch (IOException e)
- {
- throw new InvalidParameterException("Unable to get resource "+
- "input stream for resource "+resource.toString());
- }
- }
-
- /* ------------------------------------------------------------ */
- /** Set the trust store resource.
- * @param resource the trust store resource to set
- */
- public void setTrustStore(Resource resource)
- {
- checkNotStarted();
-
- try
- {
- _trustStoreInputStream = resource.getInputStream();
- }
- catch (IOException e)
- {
- throw new InvalidParameterException("Unable to get resource "+
- "input stream for resource "+resource.toString());
- }
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @return true if SSL Session caching is enabled
- */
- public boolean isSessionCachingEnabled()
- {
- return _sessionCachingEnabled;
- }
-
- /* ------------------------------------------------------------ */
- /** Set the flag to enable SSL Session caching.
- * @param enableSessionCaching the value of the flag
- */
- public void setSessionCachingEnabled(boolean enableSessionCaching)
- {
- _sessionCachingEnabled = enableSessionCaching;
- }
-
- /* ------------------------------------------------------------ */
- /** Get SSL session cache size.
- * @return SSL session cache size
- */
- public int getSslSessionCacheSize()
- {
- return _sslSessionCacheSize;
- }
-
- /* ------------------------------------------------------------ */
- /** SEt SSL session cache size.
- * @param sslSessionCacheSize SSL session cache size to set
- */
- public void setSslSessionCacheSize(int sslSessionCacheSize)
- {
- _sslSessionCacheSize = sslSessionCacheSize;
- }
-
- /* ------------------------------------------------------------ */
- /** Get SSL session timeout.
- * @return SSL session timeout
- */
- public int getSslSessionTimeout()
- {
- return _sslSessionTimeout;
- }
-
- /* ------------------------------------------------------------ */
- /** Set SSL session timeout.
- * @param sslSessionTimeout SSL session timeout to set
- */
- public void setSslSessionTimeout(int sslSessionTimeout)
- {
- _sslSessionTimeout = sslSessionTimeout;
- }
-
-
- /* ------------------------------------------------------------ */
- public SSLServerSocket newSslServerSocket(String host,int port,int backlog) throws IOException
- {
- SSLServerSocketFactory factory = _context.getServerSocketFactory();
-
- SSLServerSocket socket =
- (SSLServerSocket) (host==null ?
- factory.createServerSocket(port,backlog):
- factory.createServerSocket(port,backlog,InetAddress.getByName(host)));
-
- if (getWantClientAuth())
- socket.setWantClientAuth(getWantClientAuth());
- if (getNeedClientAuth())
- socket.setNeedClientAuth(getNeedClientAuth());
-
- socket.setEnabledCipherSuites(selectCipherSuites(
- socket.getEnabledCipherSuites(),
- socket.getSupportedCipherSuites()));
- socket.setEnabledProtocols(selectProtocols(socket.getEnabledProtocols(),socket.getSupportedProtocols()));
-
- return socket;
- }
-
- /* ------------------------------------------------------------ */
- public SSLSocket newSslSocket() throws IOException
- {
- SSLSocketFactory factory = _context.getSocketFactory();
-
- SSLSocket socket = (SSLSocket)factory.createSocket();
-
- if (getWantClientAuth())
- socket.setWantClientAuth(getWantClientAuth());
- if (getNeedClientAuth())
- socket.setNeedClientAuth(getNeedClientAuth());
-
- socket.setEnabledCipherSuites(selectCipherSuites(
- socket.getEnabledCipherSuites(),
- socket.getSupportedCipherSuites()));
- socket.setEnabledProtocols(selectProtocols(socket.getEnabledProtocols(),socket.getSupportedProtocols()));
-
- return socket;
- }
-
- /* ------------------------------------------------------------ */
- public SSLEngine newSslEngine(String host,int port)
- {
- SSLEngine sslEngine=isSessionCachingEnabled()
- ?_context.createSSLEngine(host, port)
- :_context.createSSLEngine();
-
- customize(sslEngine);
- return sslEngine;
- }
-
- /* ------------------------------------------------------------ */
- public SSLEngine newSslEngine()
- {
- SSLEngine sslEngine=_context.createSSLEngine();
- customize(sslEngine);
- return sslEngine;
- }
-
- /* ------------------------------------------------------------ */
- public void customize(SSLEngine sslEngine)
- {
- if (getWantClientAuth())
- sslEngine.setWantClientAuth(getWantClientAuth());
- if (getNeedClientAuth())
- sslEngine.setNeedClientAuth(getNeedClientAuth());
-
- sslEngine.setEnabledCipherSuites(selectCipherSuites(
- sslEngine.getEnabledCipherSuites(),
- sslEngine.getSupportedCipherSuites()));
-
- sslEngine.setEnabledProtocols(selectProtocols(sslEngine.getEnabledProtocols(),sslEngine.getSupportedProtocols()));
- }
-
}
diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java
index 6120f942aec..3ae9a409fd0 100644
--- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java
+++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java
@@ -14,10 +14,9 @@
package org.eclipse.jetty.http;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertFalse;
import java.util.Enumeration;
import java.util.HashSet;
diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java
index 46841564daa..18012e950f5 100644
--- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java
+++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java
@@ -138,7 +138,7 @@ public class HttpGeneratorClientTest
String t="v="+v+",r="+r+",chunks="+chunks+",c="+c+",tr="+tr[r];
// System.err.println(t);
- hb.reset(true);
+ hb.reset();
endp.reset();
fields.clear();
@@ -193,7 +193,7 @@ public class HttpGeneratorClientTest
}
private static final String[] headers= { "Content-Type","Content-Length","Connection","Transfer-Encoding","Other"};
- private class TR
+ private static class TR
{
private String[] values=new String[headers.length];
private String body;
diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorTest.java
index 547d4647bb9..bceb1541e9d 100644
--- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorTest.java
+++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorTest.java
@@ -86,7 +86,7 @@ public class HttpGeneratorTest
String t="v="+v+",r="+r+",chunks="+chunks+",connect="+c+",tr="+tr[r];
// System.err.println(t);
- hb.reset(true);
+ hb.reset();
endp.reset();
fields.clear();
@@ -138,7 +138,7 @@ public class HttpGeneratorTest
}
private static final String[] headers= { "Content-Type","Content-Length","Connection","Transfer-Encoding","Other"};
- private class TR
+ private static class TR
{
private int _code;
private String _body;
diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java
index ac4ae8a1552..85cf15c202c 100644
--- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java
+++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java
@@ -210,6 +210,7 @@ public class HttpParserTest
StringEndPoint io=new StringEndPoint();
io.setInput(
"GET /mp HTTP/1.0\015\012"
+ + "Connection: Keep-Alive\015\012"
+ "Header1: value1\015\012"
+ "Transfer-Encoding: chunked\015\012"
+ "\015\012"
@@ -219,10 +220,12 @@ public class HttpParserTest
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ\015\012"
+ "0\015\012"
+ "POST /foo HTTP/1.0\015\012"
+ + "Connection: Keep-Alive\015\012"
+ "Header2: value2\015\012"
+ "Content-Length: 0\015\012"
+ "\015\012"
+ "PUT /doodle HTTP/1.0\015\012"
+ + "Connection: close\015\012"
+ "Header3: value3\015\012"
+ "Content-Length: 10\015\012"
+ "\015\012"
@@ -238,27 +241,27 @@ public class HttpParserTest
assertEquals("GET", f0);
assertEquals("/mp", f1);
assertEquals("HTTP/1.0", f2);
- assertEquals(1, h);
- assertEquals("Header1", hdr[0]);
- assertEquals("value1", val[0]);
+ assertEquals(2, h);
+ assertEquals("Header1", hdr[1]);
+ assertEquals("value1", val[1]);
assertEquals("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", _content);
parser.parse();
assertEquals("POST", f0);
assertEquals("/foo", f1);
assertEquals("HTTP/1.0", f2);
- assertEquals(1, h);
- assertEquals("Header2", hdr[0]);
- assertEquals("value2", val[0]);
+ assertEquals(2, h);
+ assertEquals("Header2", hdr[1]);
+ assertEquals("value2", val[1]);
assertEquals(null, _content);
parser.parse();
assertEquals("PUT", f0);
assertEquals("/doodle", f1);
assertEquals("HTTP/1.0", f2);
- assertEquals(1, h);
- assertEquals("Header3", hdr[0]);
- assertEquals("value3", val[0]);
+ assertEquals(2, h);
+ assertEquals("Header3", hdr[1]);
+ assertEquals("value3", val[1]);
assertEquals("0123456789", _content);
}
@@ -266,7 +269,8 @@ public class HttpParserTest
public void testStreamParse() throws Exception
{
StringEndPoint io=new StringEndPoint();
- String http="GET / HTTP/1.0\015\012"
+ String http="GET / HTTP/1.1\015\012"
+ + "Host: test\015\012"
+ "Header1: value1\015\012"
+ "Transfer-Encoding: chunked\015\012"
+ "\015\012"
@@ -275,11 +279,14 @@ public class HttpParserTest
+ "1a\015\012"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ\015\012"
+ "0\015\012"
- + "POST /foo HTTP/1.0\015\012"
+ + "POST /foo HTTP/1.1\015\012"
+ + "Host: test\015\012"
+ "Header2: value2\015\012"
+ "Content-Length: 0\015\012"
+ "\015\012"
- + "PUT /doodle HTTP/1.0\015\012"
+ + "PUT /doodle HTTP/1.1\015\012"
+ + "Host: test\015\012"
+ + "Connection: close\015\012"
+ "Header3: value3\015\012"
+ "Content-Length: 10\015\012"
+ "\015\012"
@@ -296,15 +303,17 @@ public class HttpParserTest
http.length() - 2,
http.length() / 2,
http.length() / 3,
- 64,
+ 128,
32
};
for (int t= 0; t < tests.length; t++)
{
- String tst="t"+tests[t];
+ String tst="t"+t+"="+tests[t];
try
- {
+ {
+ f0=f1=f2=null;
+ h=0;
ByteArrayBuffer buffer= new ByteArrayBuffer(tests[t]);
ByteArrayBuffer content=new ByteArrayBuffer(8192);
SimpleBuffers buffers=new SimpleBuffers(buffer,content);
@@ -314,31 +323,32 @@ public class HttpParserTest
io.setInput(http);
+ // System.err.println(tst);
parser.parse();
assertEquals(tst,"GET", f0);
assertEquals(tst,"/", f1);
- assertEquals(tst,"HTTP/1.0", f2);
- assertEquals(tst,1, h);
- assertEquals(tst,"Header1", hdr[0]);
- assertEquals(tst,"value1", val[0]);
+ assertEquals(tst,"HTTP/1.1", f2);
+ assertEquals(tst,2, h);
+ assertEquals(tst,"Header1", hdr[1]);
+ assertEquals(tst,"value1", val[1]);
assertEquals(tst,"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", _content);
parser.parse();
assertEquals(tst,"POST", f0);
assertEquals(tst,"/foo", f1);
- assertEquals(tst,"HTTP/1.0", f2);
- assertEquals(tst,1, h);
- assertEquals(tst,"Header2", hdr[0]);
- assertEquals(tst,"value2", val[0]);
+ assertEquals(tst,"HTTP/1.1", f2);
+ assertEquals(tst,2, h);
+ assertEquals(tst,"Header2", hdr[1]);
+ assertEquals(tst,"value2", val[1]);
assertEquals(tst,null, _content);
parser.parse();
assertEquals(tst,"PUT", f0);
assertEquals(tst,"/doodle", f1);
- assertEquals(tst,"HTTP/1.0", f2);
- assertEquals(tst,1, h);
- assertEquals(tst,"Header3", hdr[0]);
- assertEquals(tst,"value3", val[0]);
+ assertEquals(tst,"HTTP/1.1", f2);
+ assertEquals(tst,3, h);
+ assertEquals(tst,"Header3", hdr[2]);
+ assertEquals(tst,"value3", val[2]);
assertEquals(tst,"0123456789", _content);
}
catch(Exception e)
@@ -401,7 +411,7 @@ public class HttpParserTest
StringEndPoint io=new StringEndPoint();
io.setInput(
"HTTP/1.1 204 No-Content\015\012"
- + "Connection: close\015\012"
+ + "Header: value\015\012"
+ "\015\012"
+ "HTTP/1.1 200 Correct\015\012"
+ "Content-Length: 10\015\012"
diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/SslContextFactoryTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/SslContextFactoryTest.java
deleted file mode 100644
index f7fce832c0e..00000000000
--- a/jetty-http/src/test/java/org/eclipse/jetty/http/SslContextFactoryTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package org.eclipse.jetty.http;
-
-import static junit.framework.Assert.assertTrue;
-
-import java.io.FileInputStream;
-import java.security.KeyStore;
-
-import org.eclipse.jetty.http.ssl.SslContextFactory;
-import org.junit.Test;
-
-
-public class SslContextFactoryTest
-{
- @Test
- public void testNoTsFileKs() throws Exception
- {
- String keystorePath = System.getProperty("basedir",".") + "/src/test/resources/keystore";
- SslContextFactory cf = new SslContextFactory(keystorePath);
- cf.setKeyStorePassword("storepwd");
- cf.setKeyManagerPassword("keypwd");
-
- cf.start();
-
- assertTrue(cf.getSslContext()!=null);
- }
-
- @Test
- public void testNoTsStreamKs() throws Exception
- {
- String keystorePath = System.getProperty("basedir",".") + "/src/test/resources/keystore";
-
- SslContextFactory cf = new SslContextFactory();
-
- cf.setKeyStoreInputStream(new FileInputStream(keystorePath));
- cf.setKeyStorePassword("storepwd");
- cf.setKeyManagerPassword("keypwd");
-
- cf.start();
-
- assertTrue(cf.getSslContext()!=null);
- }
-
- @Test
- public void testNoTsSetKs() throws Exception
- {
- String keystorePath = System.getProperty("basedir",".") + "/src/test/resources/keystore";
-
- KeyStore ks = KeyStore.getInstance("JKS");
- ks.load(new FileInputStream(keystorePath),"storepwd".toCharArray());
-
- SslContextFactory cf = new SslContextFactory();
- cf.setKeyStore(ks);
- cf.setKeyManagerPassword("keypwd");
-
- cf.start();
-
- assertTrue(cf.getSslContext()!=null);
- }
-
- @Test
- public void testNoTsNoKs() throws Exception
- {
- SslContextFactory cf = new SslContextFactory();
- cf.start();
- assertTrue(cf.getSslContext()!=null);
- }
-
- @Test
- public void testTrustAll() throws Exception
- {
- SslContextFactory cf = new SslContextFactory();
- cf.start();
- assertTrue(cf.getSslContext()!=null);
- }
-}
diff --git a/jetty-io/pom.xml b/jetty-io/pom.xml
index f4c816d3f27..8a5f69852a6 100644
--- a/jetty-io/pom.xml
+++ b/jetty-io/pom.xml
@@ -2,7 +2,7 @@
jetty-project
org.eclipse.jetty
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
4.0.0
org.eclipse.jetty
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractConnection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractConnection.java
index 04a6e26ec87..a9167eba32e 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractConnection.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractConnection.java
@@ -15,13 +15,13 @@ public abstract class AbstractConnection implements Connection
public AbstractConnection(EndPoint endp)
{
- _endp=endp;
+ _endp=(EndPoint)endp;
_timeStamp = System.currentTimeMillis();
}
-
+
public AbstractConnection(EndPoint endp,long timestamp)
{
- _endp=endp;
+ _endp=(EndPoint)endp;
_timeStamp = timestamp;
}
@@ -29,17 +29,21 @@ public abstract class AbstractConnection implements Connection
{
return _timeStamp;
}
-
+
public EndPoint getEndPoint()
{
return _endp;
}
- public void idleExpired()
+ public void onIdleExpired(long idleForMs)
{
try
{
- _endp.shutdownOutput();
+ LOG.debug("onIdleExpired {}ms {} {}",idleForMs,this,_endp);
+ if (_endp.isInputShutdown() || _endp.isOutputShutdown())
+ _endp.close();
+ else
+ _endp.shutdownOutput();
}
catch(IOException e)
{
@@ -52,13 +56,18 @@ public abstract class AbstractConnection implements Connection
catch(IOException e2)
{
LOG.ignore(e2);
-
}
}
}
-
+
public String toString()
{
- return super.toString()+"@"+_endp.getLocalAddr()+":"+_endp.getLocalPort()+"<->"+_endp.getRemoteAddr()+":"+_endp.getRemotePort();
+ return String.format("%s@%x//%s:%d<->%s:%d",
+ getClass().getSimpleName(),
+ hashCode(),
+ _endp.getLocalAddr(),
+ _endp.getLocalPort(),
+ _endp.getRemoteAddr(),
+ _endp.getRemotePort());
}
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/AsyncEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/AsyncEndPoint.java
index 5eebc36ad80..992ad7a195a 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/AsyncEndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/AsyncEndPoint.java
@@ -13,36 +13,59 @@
package org.eclipse.jetty.io;
-public interface AsyncEndPoint extends EndPoint
+import org.eclipse.jetty.util.thread.Timeout;
+
+public interface AsyncEndPoint extends ConnectedEndPoint
{
/* ------------------------------------------------------------ */
/**
* Dispatch the endpoint to a thread to attend to it.
*
*/
- public void dispatch();
-
- /**
- * @return true if this endpoint can accept a dispatch. False if the
- * endpoint cannot accept a dispatched (eg is suspended or already dispatched)
- */
- public boolean isReadyForDispatch();
+ public void asyncDispatch();
/* ------------------------------------------------------------ */
/** Schedule a write dispatch.
* Set the endpoint to not be writable and schedule a dispatch when
* it becomes writable.
*/
- public void scheduleWrite();
-
- /* ------------------------------------------------------------ */
- /** Schedule a call to the idle timeout
- */
- public void scheduleIdle();
-
- /* ------------------------------------------------------------ */
- /** Cancel a call to the idle timeout
- */
- public void cancelIdle();
+ public void scheduleWrite();
+ /* ------------------------------------------------------------ */
+ /** Callback when idle.
+ * An endpoint is idle if there has been no IO activity for
+ * {@link #getMaxIdleTime()} and {@link #isCheckForIdle()} is true.
+ * @param idleForMs TODO
+ */
+ public void onIdleExpired(long idleForMs);
+
+ /* ------------------------------------------------------------ */
+ /** Set if the endpoint should be checked for idleness
+ */
+ public void setCheckForIdle(boolean check);
+
+ /* ------------------------------------------------------------ */
+ /** Get if the endpoint should be checked for idleness
+ */
+ public boolean isCheckForIdle();
+
+
+ /* ------------------------------------------------------------ */
+ public boolean isWritable();
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return True if IO has been successfully performed since the last call to {@link #hasProgressed()}
+ */
+ public boolean hasProgressed();
+
+ /* ------------------------------------------------------------ */
+ /**
+ */
+ public void scheduleTimeout(Timeout.Task task, long timeoutMs);
+
+ /* ------------------------------------------------------------ */
+ /**
+ */
+ public void cancelTimeout(Timeout.Task task);
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/BufferCache.java b/jetty-io/src/main/java/org/eclipse/jetty/io/BufferCache.java
index 904961087dc..0abc1270182 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/BufferCache.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/BufferCache.java
@@ -103,6 +103,12 @@ public class BufferCache
return lookup(buffer).toString();
}
+ public int getOrdinal(String value)
+ {
+ CachedBuffer buffer = (CachedBuffer)_stringMap.get(value);
+ return buffer==null?-1:buffer.getOrdinal();
+ }
+
public int getOrdinal(Buffer buffer)
{
if (buffer instanceof CachedBuffer)
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/BufferDateCache.java b/jetty-io/src/main/java/org/eclipse/jetty/io/BufferDateCache.java
index c1aebb88829..275d2f3b77d 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/BufferDateCache.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/BufferDateCache.java
@@ -46,7 +46,6 @@ public class BufferDateCache extends DateCache
public synchronized Buffer formatBuffer(long date)
{
String d = super.format(date);
- //noinspection StringEquality
if (d==_last)
return _buffer;
_last=d;
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java
index fcae2f99fda..a0e4f8e96df 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java
@@ -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.io;
@@ -19,7 +19,7 @@ import java.io.IOException;
/* ------------------------------------------------------------ */
/** ByteArrayEndPoint.
- *
+ *
*
*/
public class ByteArrayEndPoint implements ConnectedEndPoint
@@ -36,12 +36,12 @@ public class ByteArrayEndPoint implements ConnectedEndPoint
/* ------------------------------------------------------------ */
/**
- *
+ *
*/
public ByteArrayEndPoint()
{
}
-
+
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.io.ConnectedEndPoint#getConnection()
@@ -80,7 +80,7 @@ public class ByteArrayEndPoint implements ConnectedEndPoint
/* ------------------------------------------------------------ */
/**
- *
+ *
*/
public ByteArrayEndPoint(byte[] input, int outputSize)
{
@@ -121,9 +121,9 @@ public class ByteArrayEndPoint implements ConnectedEndPoint
{
_out = out;
}
-
+
/* ------------------------------------------------------------ */
- /*
+ /*
* @see org.eclipse.io.EndPoint#isOpen()
*/
public boolean isOpen()
@@ -150,7 +150,7 @@ public class ByteArrayEndPoint implements ConnectedEndPoint
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see org.eclipse.io.EndPoint#isBlocking()
*/
public boolean isBlocking()
@@ -171,7 +171,7 @@ public class ByteArrayEndPoint implements ConnectedEndPoint
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see org.eclipse.io.EndPoint#shutdownOutput()
*/
public void shutdownOutput() throws IOException
@@ -180,16 +180,16 @@ public class ByteArrayEndPoint implements ConnectedEndPoint
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see org.eclipse.io.EndPoint#shutdownInput()
*/
public void shutdownInput() throws IOException
{
close();
}
-
+
/* ------------------------------------------------------------ */
- /*
+ /*
* @see org.eclipse.io.EndPoint#close()
*/
public void close() throws IOException
@@ -198,30 +198,30 @@ public class ByteArrayEndPoint implements ConnectedEndPoint
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see org.eclipse.io.EndPoint#fill(org.eclipse.io.Buffer)
*/
public int fill(Buffer buffer) throws IOException
{
if (_closed)
throw new IOException("CLOSED");
-
+
if (_in!=null && _in.length()>0)
{
int len = buffer.put(_in);
_in.skip(len);
return len;
}
-
+
if (_in!=null && _in.length()==0 && _nonBlocking)
return 0;
-
+
close();
return -1;
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see org.eclipse.io.EndPoint#flush(org.eclipse.io.Buffer)
*/
public int flush(Buffer buffer) throws IOException
@@ -252,24 +252,24 @@ public class ByteArrayEndPoint implements ConnectedEndPoint
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see org.eclipse.io.EndPoint#flush(org.eclipse.io.Buffer, org.eclipse.io.Buffer, org.eclipse.io.Buffer)
*/
public int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException
{
if (_closed)
throw new IOException("CLOSED");
-
+
int flushed=0;
-
+
if (header!=null && header.length()>0)
flushed=flush(header);
-
+
if (header==null || header.length()==0)
{
if (buffer!=null && buffer.length()>0)
flushed+=flush(buffer);
-
+
if (buffer==null || buffer.length()==0)
{
if (trailer!=null && trailer.length()>0)
@@ -278,13 +278,13 @@ public class ByteArrayEndPoint implements ConnectedEndPoint
}
}
}
-
+
return flushed;
}
/* ------------------------------------------------------------ */
/**
- *
+ *
*/
public void reset()
{
@@ -296,7 +296,7 @@ public class ByteArrayEndPoint implements ConnectedEndPoint
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see org.eclipse.io.EndPoint#getLocalAddr()
*/
public String getLocalAddr()
@@ -305,7 +305,7 @@ public class ByteArrayEndPoint implements ConnectedEndPoint
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see org.eclipse.io.EndPoint#getLocalHost()
*/
public String getLocalHost()
@@ -314,7 +314,7 @@ public class ByteArrayEndPoint implements ConnectedEndPoint
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see org.eclipse.io.EndPoint#getLocalPort()
*/
public int getLocalPort()
@@ -323,7 +323,7 @@ public class ByteArrayEndPoint implements ConnectedEndPoint
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see org.eclipse.io.EndPoint#getRemoteAddr()
*/
public String getRemoteAddr()
@@ -332,7 +332,7 @@ public class ByteArrayEndPoint implements ConnectedEndPoint
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see org.eclipse.io.EndPoint#getRemoteHost()
*/
public String getRemoteHost()
@@ -341,7 +341,7 @@ public class ByteArrayEndPoint implements ConnectedEndPoint
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see org.eclipse.io.EndPoint#getRemotePort()
*/
public int getRemotePort()
@@ -350,7 +350,7 @@ public class ByteArrayEndPoint implements ConnectedEndPoint
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see org.eclipse.io.EndPoint#getConnection()
*/
public Object getTransport()
@@ -360,27 +360,9 @@ public class ByteArrayEndPoint implements ConnectedEndPoint
/* ------------------------------------------------------------ */
public void flush() throws IOException
- {
- }
-
- /* ------------------------------------------------------------ */
- public boolean isBufferingInput()
{
- return false;
}
-
- /* ------------------------------------------------------------ */
- public boolean isBufferingOutput()
- {
- return false;
- }
-
- /* ------------------------------------------------------------ */
- public boolean isBufferred()
- {
- return false;
- }
-
+
/* ------------------------------------------------------------ */
/**
* @return the growOutput
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/Connection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/Connection.java
index 431964afe8f..19cf3bee60e 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/Connection.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/Connection.java
@@ -50,10 +50,11 @@ public interface Connection
/**
* Called when the connection is closed
*/
- void closed();
+ void onClose();
/**
* Called when the connection idle timeout expires
+ * @param idleForMs TODO
*/
- void idleExpired();
+ void onIdleExpired(long idleForMs);
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java
index 6940991f387..231b752b9ee 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java
@@ -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.io;
@@ -17,7 +17,7 @@ import java.io.IOException;
/**
- *
+ *
* A transport EndPoint
*/
public interface EndPoint
@@ -28,36 +28,36 @@ public interface EndPoint
void shutdownOutput() throws IOException;
boolean isOutputShutdown();
-
+
/**
* Shutdown any backing input stream associated with the endpoint
*/
void shutdownInput() throws IOException;
-
+
boolean isInputShutdown();
-
+
/**
* Close any backing stream associated with the endpoint
*/
void close() throws IOException;
/**
- * Fill the buffer from the current putIndex to it's capacity from whatever
+ * Fill the buffer from the current putIndex to it's capacity from whatever
* byte source is backing the buffer. The putIndex is increased if bytes filled.
* The buffer may chose to do a compact before filling.
- * @return an int
value indicating the number of bytes
+ * @return an int
value indicating the number of bytes
* filled or -1 if EOF is reached.
* @throws EofException If input is shutdown or the endpoint is closed.
*/
int fill(Buffer buffer) throws IOException;
-
+
/**
* Flush the buffer from the current getIndex to it's putIndex using whatever byte
* sink is backing the buffer. The getIndex is updated with the number of bytes flushed.
* Any mark set is cleared.
* If the entire contents of the buffer are flushed, then an implicit empty() is done.
- *
+ *
* @param buffer The buffer to flush. This buffers getIndex is updated.
* @return the number of bytes written
* @throws EofException If the endpoint is closed or output is shutdown.
@@ -69,7 +69,7 @@ public interface EndPoint
* sink is backing the buffer. The getIndex is updated with the number of bytes flushed.
* Any mark set is cleared.
* If the entire contents of the buffer are flushed, then an implicit empty() is done.
- * The passed header/trailer buffers are written before/after the contents of this buffer. This may be done
+ * The passed header/trailer buffers are written before/after the contents of this buffer. This may be done
* either as gather writes, as a poke into this buffer or as several writes. The implementation is free to
* select the optimal mechanism.
* @param header A buffer to write before flushing this buffer. This buffers getIndex is updated.
@@ -79,14 +79,14 @@ public interface EndPoint
*/
int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException;
-
+
/* ------------------------------------------------------------ */
/**
* @return The local IP address to which this EndPoint
is bound, or null
* if this EndPoint
does not represent a network connection.
*/
public String getLocalAddr();
-
+
/* ------------------------------------------------------------ */
/**
* @return The local host name to which this EndPoint
is bound, or null
@@ -122,13 +122,9 @@ public interface EndPoint
*/
public int getRemotePort();
-
/* ------------------------------------------------------------ */
public boolean isBlocking();
-
- /* ------------------------------------------------------------ */
- public boolean isBufferred();
-
+
/* ------------------------------------------------------------ */
public boolean blockReadable(long millisecs) throws IOException;
@@ -143,27 +139,14 @@ public interface EndPoint
* @return The underlying transport object (socket, channel, etc.)
*/
public Object getTransport();
-
- /* ------------------------------------------------------------ */
- /**
- * @return True if the endpoint has some buffered input data
- */
- public boolean isBufferingInput();
-
- /* ------------------------------------------------------------ */
- /**
- * @return True if the endpoint has some buffered output data
- */
- public boolean isBufferingOutput();
-
+
/* ------------------------------------------------------------ */
/** Flush any buffered output.
* May fail to write all data if endpoint is non-blocking
* @throws EofException If the endpoint is closed or output is shutdown.
*/
public void flush() throws IOException;
-
-
+
/* ------------------------------------------------------------ */
/** Get the max idle time in ms.
*
The max idle time is the time the endpoint can be idle before
@@ -174,14 +157,14 @@ public interface EndPoint
* @return the max idle time in ms or if ms <= 0 implies an infinite timeout
*/
public int getMaxIdleTime();
-
+
/* ------------------------------------------------------------ */
/** Set the max idle time.
* @param timeMs the max idle time in MS. Timeout <= 0 implies an infinite timeout
* @throws IOException if the timeout cannot be set.
*/
public void setMaxIdleTime(int timeMs) throws IOException;
-
-
-
+
+
+
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/EofException.java b/jetty-io/src/main/java/org/eclipse/jetty/io/EofException.java
index 9c864aa078a..03369e5a79d 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/EofException.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/EofException.java
@@ -15,6 +15,13 @@ package org.eclipse.jetty.io;
import java.io.EOFException;
+
+/* ------------------------------------------------------------ */
+/** A Jetty specialization of EOFException.
+ *
This is thrown by Jetty to distinguish between EOF received from
+ * the connection, vs and EOF thrown by some application talking to some other file/socket etc.
+ * The only difference in handling is that Jetty EOFs are logged less verbosely.
+ */
public class EofException extends EOFException
{
public EofException()
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/UncheckedPrintWriter.java b/jetty-io/src/main/java/org/eclipse/jetty/io/UncheckedPrintWriter.java
index f114417e800..cfb05447a29 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/UncheckedPrintWriter.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/UncheckedPrintWriter.java
@@ -35,7 +35,8 @@ public class UncheckedPrintWriter extends PrintWriter
private static final Logger LOG = Log.getLogger(UncheckedPrintWriter.class);
private boolean _autoFlush = false;
- private boolean _throwUnchecked=true;
+ private IOException _ioException;
+ private boolean _isClosed = false;
/* ------------------------------------------------------------ */
/**
@@ -102,38 +103,45 @@ public class UncheckedPrintWriter extends PrintWriter
this(new BufferedWriter(new OutputStreamWriter(out)),autoFlush);
}
+
/* ------------------------------------------------------------ */
- private void setError(Throwable th)
+ public boolean checkError()
{
- setError();
- if (_throwUnchecked)
- throw new RuntimeIOException(th);
- LOG.debug(th);
- }
-
- /* ------------------------------------------------------------ */
- /** Are unchecked exceptions thrown.
- * @return True if {@link RuntimeIOException}s are thrown
- */
- public boolean isUncheckedPrintWriter()
- {
- return _throwUnchecked;
- }
-
- /* ------------------------------------------------------------ */
- /** Set if unchecked exceptions are thrown
- * @param uncheckedPrintWriter True if {@link RuntimeIOException}s are to be thrown
- */
- public void setUncheckedPrintWriter(boolean uncheckedPrintWriter)
- {
- _throwUnchecked = uncheckedPrintWriter;
+ return _ioException!=null || super.checkError();
}
+ /* ------------------------------------------------------------ */
+ private void setError(Throwable th)
+ {
+
+ super.setError();
+
+ if (th instanceof IOException)
+ _ioException=(IOException)th;
+ else
+ {
+ _ioException=new IOException(String.valueOf(th));
+ _ioException.initCause(th);
+ }
+
+ LOG.debug(th);
+ }
+
+
+ @Override
+ protected void setError()
+ {
+ setError(new IOException());
+ }
+
/* ------------------------------------------------------------ */
/** Check to make sure that the stream has not been closed */
private void isOpen() throws IOException
- {
- if (super.out == null)
+ {
+ if (_ioException!=null)
+ throw new RuntimeIOException(_ioException);
+
+ if (_isClosed)
throw new IOException("Stream closed");
}
@@ -170,6 +178,7 @@ public class UncheckedPrintWriter extends PrintWriter
synchronized (lock)
{
out.close();
+ _isClosed = true;
}
}
catch (IOException ex)
@@ -248,7 +257,7 @@ public class UncheckedPrintWriter extends PrintWriter
*/
@Override
public void write(char buf[])
- {
+ {
this.write(buf,0,buf.length);
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/bio/SocketEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/bio/SocketEndPoint.java
index f749f0ba417..67fb8ab214f 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/bio/SocketEndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/bio/SocketEndPoint.java
@@ -17,17 +17,13 @@ import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
+
import javax.net.ssl.SSLSocket;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
-/**
- *
- * To change the template for this generated type comment go to
- * Window - Preferences - Java - Code Generation - Code and Comments
- */
public class SocketEndPoint extends StreamEndPoint
{
private static final Logger LOG = Log.getLogger(SocketEndPoint.class);
@@ -79,14 +75,34 @@ public class SocketEndPoint extends StreamEndPoint
@Override
public boolean isInputShutdown()
{
- return !isOpen() || super.isInputShutdown();
+ if (_socket instanceof SSLSocket)
+ return super.isInputShutdown();
+ return _socket.isClosed() || _socket.isInputShutdown();
}
/* ------------------------------------------------------------ */
@Override
public boolean isOutputShutdown()
{
- return !isOpen() || super.isOutputShutdown();
+ if (_socket instanceof SSLSocket)
+ return super.isOutputShutdown();
+
+ return _socket.isClosed() || _socket.isOutputShutdown();
+ }
+
+
+ /* ------------------------------------------------------------ */
+ /*
+ */
+ protected final void shutdownSocketOutput() throws IOException
+ {
+ if (!_socket.isClosed())
+ {
+ if (!_socket.isOutputShutdown())
+ _socket.shutdownOutput();
+ if (_socket.isInputShutdown())
+ _socket.close();
+ }
}
/* ------------------------------------------------------------ */
@@ -96,15 +112,27 @@ public class SocketEndPoint extends StreamEndPoint
@Override
public void shutdownOutput() throws IOException
{
- if (!isOutputShutdown())
- {
+ if (_socket instanceof SSLSocket)
super.shutdownOutput();
- if (!(_socket instanceof SSLSocket))
- _socket.shutdownOutput();
- }
+ else
+ shutdownSocketOutput();
}
+ /* ------------------------------------------------------------ */
+ /*
+ */
+ public void shutdownSocketInput() throws IOException
+ {
+ if (!_socket.isClosed())
+ {
+ if (!_socket.isInputShutdown())
+ _socket.shutdownInput();
+ if (_socket.isOutputShutdown())
+ _socket.close();
+ }
+ }
+
/* ------------------------------------------------------------ */
/*
* @see org.eclipse.jetty.io.bio.StreamEndPoint#shutdownOutput()
@@ -112,12 +140,10 @@ public class SocketEndPoint extends StreamEndPoint
@Override
public void shutdownInput() throws IOException
{
- if (!isInputShutdown())
- {
+ if (_socket instanceof SSLSocket)
super.shutdownInput();
- if (!(_socket instanceof SSLSocket))
- _socket.shutdownInput();
- }
+ else
+ shutdownSocketInput();
}
/* ------------------------------------------------------------ */
@@ -247,4 +273,9 @@ public class SocketEndPoint extends StreamEndPoint
}
}
+ @Override
+ public String toString()
+ {
+ return _local + " <--> " + _remote;
+ }
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/bio/StreamEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/bio/StreamEndPoint.java
index 48dce3723df..0ebab0058d3 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/bio/StreamEndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/bio/StreamEndPoint.java
@@ -72,10 +72,8 @@ public class StreamEndPoint implements EndPoint
public void shutdownOutput() throws IOException
{
- if (_oshut)
- return;
_oshut = true;
- if (_out!=null)
+ if (_ishut && _out!=null)
_out.close();
}
@@ -86,10 +84,8 @@ public class StreamEndPoint implements EndPoint
public void shutdownInput() throws IOException
{
- if (_ishut)
- return;
_ishut = true;
- if (_in!=null)
+ if (_oshut&&_in!=null)
_in.close();
}
@@ -122,6 +118,8 @@ public class StreamEndPoint implements EndPoint
*/
public int fill(Buffer buffer) throws IOException
{
+ if (_ishut)
+ return -1;
if (_in==null)
return 0;
@@ -135,15 +133,10 @@ public class StreamEndPoint implements EndPoint
try
{
- int read=buffer.readFrom(_in, space);
- if (read<0 && isOpen())
- {
- if (!isInputShutdown())
- shutdownInput();
- else if (isOutputShutdown())
- close();
- }
- return read;
+ int filled=buffer.readFrom(_in, space);
+ if (filled<0)
+ shutdownInput();
+ return filled;
}
catch(SocketTimeoutException e)
{
@@ -157,8 +150,10 @@ public class StreamEndPoint implements EndPoint
*/
public int flush(Buffer buffer) throws IOException
{
- if (_out==null)
+ if (_oshut)
return -1;
+ if (_out==null)
+ return 0;
int length=buffer.length();
if (length>0)
buffer.writeTo(_out);
@@ -310,24 +305,6 @@ public class StreamEndPoint implements EndPoint
_out.flush();
}
- /* ------------------------------------------------------------ */
- public boolean isBufferingInput()
- {
- return false;
- }
-
- /* ------------------------------------------------------------ */
- public boolean isBufferingOutput()
- {
- return false;
- }
-
- /* ------------------------------------------------------------ */
- public boolean isBufferred()
- {
- return false;
- }
-
/* ------------------------------------------------------------ */
public int getMaxIdleTime()
{
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/bio/StringEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/bio/StringEndPoint.java
index 1e8aad30a26..1698249d438 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/bio/StringEndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/bio/StringEndPoint.java
@@ -53,6 +53,8 @@ public class StringEndPoint extends StreamEndPoint
_in=_bin;
_bout = new ByteArrayOutputStream();
_out=_bout;
+ _ishut=false;
+ _oshut=false;
}
catch(Exception e)
{
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/AsyncConnection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/AsyncConnection.java
new file mode 100644
index 00000000000..717d01294ab
--- /dev/null
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/AsyncConnection.java
@@ -0,0 +1,23 @@
+// ========================================================================
+// Copyright (c) 2010 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+
+package org.eclipse.jetty.io.nio;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.io.Connection;
+
+public interface AsyncConnection extends Connection
+{
+ void onInputShutdown() throws IOException;
+}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java
index 9aefa436cb9..fb3c09145a8 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java
@@ -43,7 +43,9 @@ public class ChannelEndPoint implements EndPoint
protected final Socket _socket;
protected final InetSocketAddress _local;
protected final InetSocketAddress _remote;
- protected int _maxIdleTime;
+ protected volatile int _maxIdleTime;
+ private volatile boolean _ishut;
+ private volatile boolean _oshut;
public ChannelEndPoint(ByteChannel channel) throws IOException
{
@@ -102,20 +104,76 @@ public class ChannelEndPoint implements EndPoint
return _channel.isOpen();
}
+ /** Shutdown the channel Input.
+ * Cannot be overridden. To override, see {@link #shutdownInput()}
+ * @throws IOException
+ */
+ protected final void shutdownChannelInput() throws IOException
+ {
+ LOG.debug("ishut {}", this);
+ _ishut = true;
+ if (_channel.isOpen())
+ {
+ if (_socket != null)
+ {
+ try
+ {
+ if (!_socket.isInputShutdown())
+ {
+ _socket.shutdownInput();
+ }
+ }
+ catch (SocketException e)
+ {
+ LOG.debug(e.toString());
+ LOG.ignore(e);
+ }
+ finally
+ {
+ if (_oshut)
+ {
+ close();
+ }
+ }
+ }
+ }
+ }
+
/* (non-Javadoc)
* @see org.eclipse.io.EndPoint#close()
*/
public void shutdownInput() throws IOException
{
- if (_channel.isOpen() && _channel instanceof SocketChannel)
+ shutdownChannelInput();
+ }
+
+ protected final void shutdownChannelOutput() throws IOException
+ {
+ LOG.debug("oshut {}",this);
+ _oshut = true;
+ if (_channel.isOpen())
{
- Socket socket= ((SocketChannel)_channel).socket();
- if (!socket.isClosed())
+ if (_socket != null)
{
- if(socket.isOutputShutdown())
- socket.close();
- else if (!socket.isInputShutdown())
- socket.shutdownInput();
+ try
+ {
+ if (!_socket.isOutputShutdown())
+ {
+ _socket.shutdownOutput();
+ }
+ }
+ catch (SocketException e)
+ {
+ LOG.debug(e.toString());
+ LOG.ignore(e);
+ }
+ finally
+ {
+ if (_ishut)
+ {
+ close();
+ }
+ }
}
}
}
@@ -125,34 +183,17 @@ public class ChannelEndPoint implements EndPoint
*/
public void shutdownOutput() throws IOException
{
- if (_channel.isOpen() && _channel instanceof SocketChannel)
- {
- Socket socket= ((SocketChannel)_channel).socket();
- if (!socket.isClosed())
- {
- try
- {
- if (socket.isInputShutdown())
- socket.close();
- else if (!socket.isOutputShutdown())
- socket.shutdownOutput();
- }
- catch(SocketException e)
- {
- LOG.ignore(e);
- }
- }
- }
+ shutdownChannelOutput();
}
public boolean isOutputShutdown()
{
- return _channel.isOpen() && _socket!=null && _socket.isOutputShutdown();
+ return _oshut || !_channel.isOpen() || _socket != null && _socket.isOutputShutdown();
}
public boolean isInputShutdown()
{
- return _channel.isOpen() && _socket!=null && _socket.isInputShutdown();
+ return _ishut || !_channel.isOpen() || _socket != null && _socket.isInputShutdown();
}
/* (non-Javadoc)
@@ -160,6 +201,7 @@ public class ChannelEndPoint implements EndPoint
*/
public void close() throws IOException
{
+ LOG.debug("close {}",this);
_channel.close();
}
@@ -168,13 +210,15 @@ public class ChannelEndPoint implements EndPoint
*/
public int fill(Buffer buffer) throws IOException
{
+ if (_ishut)
+ return -1;
Buffer buf = buffer.buffer();
int len=0;
if (buf instanceof NIOBuffer)
{
final NIOBuffer nbuf = (NIOBuffer)buf;
final ByteBuffer bbuf=nbuf.getByteBuffer();
-
+
//noinspection SynchronizationOnLocalVariableOrMethodParameter
try
{
@@ -196,22 +240,24 @@ public class ChannelEndPoint implements EndPoint
{
if (!isInputShutdown())
shutdownInput();
- else if (isOutputShutdown())
+ if (isOutputShutdown())
_channel.close();
}
}
catch (IOException x)
{
- LOG.debug(x);
+ LOG.debug(x.toString());
+ LOG.ignore(x);
try
{
- close();
+ if (_channel.isOpen())
+ _channel.close();
}
- catch (IOException xx)
+ catch (Exception xx)
{
LOG.ignore(xx);
}
-
+
if (len>0)
throw x;
len=-1;
@@ -221,7 +267,7 @@ public class ChannelEndPoint implements EndPoint
{
throw new IOException("Not Implemented");
}
-
+
return len;
}
@@ -293,20 +339,6 @@ public class ChannelEndPoint implements EndPoint
}
else
{
- if (header!=null)
- {
- if (buffer!=null && buffer.length()>0 && header.space()>buffer.length())
- {
- header.put(buffer);
- buffer.clear();
- }
- if (trailer!=null && trailer.length()>0 && header.space()>trailer.length())
- {
- header.put(trailer);
- trailer.clear();
- }
- }
-
// flush header
if (header!=null && header.length()>0)
length=flush(header);
@@ -478,24 +510,6 @@ public class ChannelEndPoint implements EndPoint
{
}
- /* ------------------------------------------------------------ */
- public boolean isBufferingInput()
- {
- return false;
- }
-
- /* ------------------------------------------------------------ */
- public boolean isBufferingOutput()
- {
- return false;
- }
-
- /* ------------------------------------------------------------ */
- public boolean isBufferred()
- {
- return false;
- }
-
/* ------------------------------------------------------------ */
public int getMaxIdleTime()
{
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java
index a318543f647..39cd2205dc3 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java
@@ -27,6 +27,7 @@ import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.io.nio.SelectorManager.SelectSet;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.thread.Timeout.Task;
/* ------------------------------------------------------------ */
/**
@@ -35,7 +36,7 @@ import org.eclipse.jetty.util.log.Logger;
public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPoint, ConnectedEndPoint
{
public static final Logger LOG=Log.getLogger("org.eclipse.jetty.io.nio");
-
+
private final SelectorManager.SelectSet _selectSet;
private final SelectorManager _manager;
private SelectionKey _key;
@@ -46,36 +47,38 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
/** The desired value for {@link SelectionKey#interestOps()} */
private int _interestOps;
-
+
/**
* The connection instance is the handler for any IO activity on the endpoint.
- * There is a different type of connection for HTTP, AJP, WebSocket and
- * ProxyConnect. The connection may change for an SCEP as it is upgraded
+ * There is a different type of connection for HTTP, AJP, WebSocket and
+ * ProxyConnect. The connection may change for an SCEP as it is upgraded
* from HTTP to proxy connect or websocket.
*/
- private volatile Connection _connection;
-
+ private volatile AsyncConnection _connection;
+
/** true if a thread has been dispatched to handle this endpoint */
private boolean _dispatched = false;
-
+
/** true if a non IO dispatch (eg async resume) is outstanding */
- private boolean _redispatched = false;
-
+ private boolean _asyncDispatch = false;
+
/** true if the last write operation succeed and wrote all offered bytes */
private volatile boolean _writable = true;
-
+
/** True if a thread has is blocked in {@link #blockReadable(long)} */
private boolean _readBlocked;
/** True if a thread has is blocked in {@link #blockWritable(long)} */
private boolean _writeBlocked;
-
+
/** true if {@link SelectSet#destroyEndPoint(SelectChannelEndPoint)} has not been called */
private boolean _open;
-
+
private volatile long _idleTimestamp;
-
+
+ private boolean _ishut;
+
/* ------------------------------------------------------------ */
public SelectChannelEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key, int maxIdleTime)
throws IOException
@@ -85,33 +88,13 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
_manager = selectSet.getManager();
_selectSet = selectSet;
_dispatched = false;
- _redispatched = false;
+ _asyncDispatch = false;
_open=true;
_key = key;
- _connection = _manager.newConnection(channel,this);
-
- scheduleIdle();
+ setCheckForIdle(true);
}
- /* ------------------------------------------------------------ */
- public SelectChannelEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key)
- throws IOException
- {
- super(channel);
-
- _manager = selectSet.getManager();
- _selectSet = selectSet;
- _dispatched = false;
- _redispatched = false;
- _open=true;
- _key = key;
-
- _connection = _manager.newConnection(channel,this);
-
- scheduleIdle();
- }
-
/* ------------------------------------------------------------ */
public SelectionKey getSelectionKey()
{
@@ -137,8 +120,9 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
public void setConnection(Connection connection)
{
Connection old=_connection;
- _connection=connection;
- _manager.endPointUpgraded(this,old);
+ _connection=(AsyncConnection)connection;
+ if (old!=null && old!=_connection)
+ _manager.endPointUpgraded(this,old);
}
/* ------------------------------------------------------------ */
@@ -146,7 +130,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{
return _idleTimestamp;
}
-
+
/* ------------------------------------------------------------ */
/** Called by selectSet to schedule handling
*
@@ -176,17 +160,10 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
// wake them up is as good as a dispatched.
this.notifyAll();
- // we are not interested in further selecting
- if (_dispatched)
- _key.interestOps(0);
- return;
- }
-
- // Otherwise if we are still dispatched
- if (!isReadyForDispatch())
- {
// we are not interested in further selecting
_key.interestOps(0);
+ if (!_dispatched)
+ updateKey();
return;
}
@@ -211,6 +188,18 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
}
}
+ /* ------------------------------------------------------------ */
+ public void asyncDispatch()
+ {
+ synchronized(this)
+ {
+ if (_dispatched)
+ _asyncDispatch=true;
+ else
+ dispatch();
+ }
+ }
+
/* ------------------------------------------------------------ */
public void dispatch()
{
@@ -218,7 +207,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{
if (_dispatched)
{
- _redispatched=true;
+ throw new IllegalStateException("dispatched");
}
else
{
@@ -245,9 +234,9 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{
synchronized (this)
{
- if (_redispatched)
+ if (_asyncDispatch)
{
- _redispatched=false;
+ _asyncDispatch=false;
return false;
}
_dispatched = false;
@@ -257,48 +246,74 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
}
/* ------------------------------------------------------------ */
- public void scheduleIdle()
+ public void cancelTimeout(Task task)
{
- _idleTimestamp=System.currentTimeMillis();
+ getSelectSet().cancelTimeout(task);
}
/* ------------------------------------------------------------ */
- public void cancelIdle()
+ public void scheduleTimeout(Task task, long timeoutMs)
{
- _idleTimestamp=0;
+ getSelectSet().scheduleTimeout(task,timeoutMs);
+ }
+
+ /* ------------------------------------------------------------ */
+ public void setCheckForIdle(boolean check)
+ {
+ _idleTimestamp=check?System.currentTimeMillis():0;
+ }
+
+ /* ------------------------------------------------------------ */
+ public boolean isCheckForIdle()
+ {
+ return _idleTimestamp!=0;
+ }
+
+ /* ------------------------------------------------------------ */
+ protected void notIdle()
+ {
+ if (_idleTimestamp!=0)
+ _idleTimestamp=System.currentTimeMillis();
}
/* ------------------------------------------------------------ */
public void checkIdleTimestamp(long now)
{
long idleTimestamp=_idleTimestamp;
- if (!getChannel().isOpen() || idleTimestamp!=0 && _maxIdleTime>0 && now>(idleTimestamp+_maxIdleTime))
- idleExpired();
+
+ if (idleTimestamp!=0 && _maxIdleTime>0)
+ {
+ long idleForMs=now-idleTimestamp;
+ if (idleForMs>_maxIdleTime)
+ {
+ onIdleExpired(idleForMs);
+ _idleTimestamp=now;
+ }
+ }
}
/* ------------------------------------------------------------ */
- protected void idleExpired()
+ public void onIdleExpired(long idleForMs)
{
- _connection.idleExpired();
+ _connection.onIdleExpired(idleForMs);
}
/* ------------------------------------------------------------ */
- /**
- * @return True if the endpoint has produced/consumed bytes itself (non application data).
- */
- public boolean isProgressing()
+ @Override
+ public int fill(Buffer buffer) throws IOException
{
- return false;
+ int fill=super.fill(buffer);
+ if (fill>0)
+ notIdle();
+ return fill;
}
-
+
/* ------------------------------------------------------------ */
- /*
- */
@Override
public int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException
{
int l = super.flush(header, buffer, trailer);
-
+
// If there was something to write and it wasn't written, then we are not writable.
if (l==0 && ( header!=null && header.hasContent() || buffer!=null && buffer.hasContent() || trailer!=null && trailer.hasContent()))
{
@@ -309,8 +324,11 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
updateKey();
}
}
- else
+ else if (l>0)
+ {
_writable=true;
+ notIdle();
+ }
return l;
}
@@ -321,7 +339,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
public int flush(Buffer buffer) throws IOException
{
int l = super.flush(buffer);
-
+
// If there was something to write and it wasn't written, then we are not writable.
if (l==0 && buffer!=null && buffer.hasContent())
{
@@ -332,20 +350,13 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
updateKey();
}
}
- else
- _writable=true;
-
- return l;
- }
-
- /* ------------------------------------------------------------ */
- public boolean isReadyForDispatch()
- {
- synchronized (this)
+ else if (l>0)
{
- // Ready if not dispatched and not suspended
- return !(_dispatched || getConnection().isSuspended());
+ _writable=true;
+ notIdle();
}
+
+ return l;
}
/* ------------------------------------------------------------ */
@@ -357,12 +368,17 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{
synchronized (this)
{
+ if (isInputShutdown())
+ throw new EofException();
+
long now=_selectSet.getNow();
long end=now+timeoutMs;
+ boolean check=isCheckForIdle();
+ setCheckForIdle(true);
try
{
_readBlocked=true;
- while (isOpen() && _readBlocked)
+ while (!isInputShutdown() && _readBlocked)
{
try
{
@@ -385,6 +401,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
finally
{
_readBlocked=false;
+ setCheckForIdle(check);
}
}
return true;
@@ -399,15 +416,17 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{
synchronized (this)
{
- if (!isOpen() || isOutputShutdown())
+ if (isOutputShutdown())
throw new EofException();
-
+
long now=_selectSet.getNow();
long end=now+timeoutMs;
+ boolean check=isCheckForIdle();
+ setCheckForIdle(true);
try
{
_writeBlocked=true;
- while (isOpen() && _writeBlocked && !isOutputShutdown())
+ while (_writeBlocked && !isOutputShutdown())
{
try
{
@@ -426,21 +445,10 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
return false;
}
}
- catch(Throwable e)
- {
- // TODO remove this if it finds nothing
- LOG.warn(e);
- if (e instanceof RuntimeException)
- throw (RuntimeException)e;
- if (e instanceof Error)
- throw (Error)e;
- throw new RuntimeException(e);
- }
finally
{
_writeBlocked=false;
- if (_idleTimestamp!=-1)
- scheduleIdle();
+ setCheckForIdle(check);
}
}
return true;
@@ -452,17 +460,32 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{
_writable=false;
}
-
+
/* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.io.AsyncEndPoint#scheduleWrite()
+ */
public void scheduleWrite()
{
if (_writable==true)
LOG.debug("Required scheduleWrite {}",this);
-
+
_writable=false;
updateKey();
}
+ /* ------------------------------------------------------------ */
+ public boolean isWritable()
+ {
+ return _writable;
+ }
+
+ /* ------------------------------------------------------------ */
+ public boolean hasProgressed()
+ {
+ return false;
+ }
+
/* ------------------------------------------------------------ */
/**
* Updates selection key. Adds operations types to the selection key as needed. No operations
@@ -471,17 +494,21 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
*/
private void updateKey()
{
+ final boolean changed;
synchronized (this)
{
- int ops=-1;
+ int current_ops=-1;
if (getChannel().isOpen())
{
+ boolean read_interest = _readBlocked || (!_dispatched && !_connection.isSuspended());
+ boolean write_interest= _writeBlocked || (!_dispatched && !_writable);
+
_interestOps =
- ((!_socket.isInputShutdown() && (!_dispatched || _readBlocked)) ? SelectionKey.OP_READ : 0)
- | ((!_socket.isOutputShutdown()&& (!_writable || _writeBlocked)) ? SelectionKey.OP_WRITE : 0);
+ ((!_socket.isInputShutdown() && read_interest ) ? SelectionKey.OP_READ : 0)
+ | ((!_socket.isOutputShutdown()&& write_interest) ? SelectionKey.OP_WRITE : 0);
try
{
- ops = ((_key!=null && _key.isValid())?_key.interestOps():-1);
+ current_ops = ((_key!=null && _key.isValid())?_key.interestOps():-1);
}
catch(Exception e)
{
@@ -489,14 +516,17 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
LOG.ignore(e);
}
}
-
- if(_interestOps == ops && getChannel().isOpen())
- return;
+ changed=_interestOps!=current_ops;
+ }
+
+ if(changed)
+ {
+ _selectSet.addChange(this);
+ _selectSet.wakeup();
}
- _selectSet.addChange(this);
- _selectSet.wakeup();
}
+
/* ------------------------------------------------------------ */
/**
* Synchronize the interestOps with the actual key. Call is scheduled by a call to updateKey
@@ -529,7 +559,6 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{
_key.cancel();
}
- cancelIdle();
if (_open)
{
@@ -558,7 +587,6 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
if (_key!=null && _key.isValid())
_key.cancel();
- cancelIdle();
if (_open)
{
_open=false;
@@ -583,11 +611,13 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{
while(true)
{
- final Connection next = _connection.handle();
+ final AsyncConnection next = (AsyncConnection)_connection.handle();
if (next!=_connection)
{
LOG.debug("{} replaced {}",next,_connection);
+ Connection old=_connection;
_connection=next;
+ _manager.endPointUpgraded(this,old);
continue;
}
break;
@@ -600,23 +630,44 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
catch (EofException e)
{
LOG.debug("EOF", e);
- try{getChannel().close();}
+ try{close();}
catch(IOException e2){LOG.ignore(e2);}
}
catch (IOException e)
{
LOG.warn(e.toString());
LOG.debug(e);
- try{getChannel().close();}
+ try{close();}
catch(IOException e2){LOG.ignore(e2);}
}
catch (Throwable e)
{
LOG.warn("handle failed", e);
- try{getChannel().close();}
+ try{close();}
catch(IOException e2){LOG.ignore(e2);}
}
- dispatched=!undispatch();
+ finally
+ {
+ if (!_ishut && isInputShutdown() && isOpen())
+ {
+ _ishut=true;
+ try
+ {
+ _connection.onInputShutdown();
+ }
+ catch(Throwable x)
+ {
+ LOG.warn("onInputShutdown failed", x);
+ try{close();}
+ catch(IOException e2){LOG.ignore(e2);}
+ }
+ finally
+ {
+ updateKey();
+ }
+ }
+ dispatched=!undispatch();
+ }
}
}
finally
@@ -660,9 +711,21 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{
synchronized(this)
{
- return "SCEP@" + hashCode() + _channel+
- "[o="+isOpen()+" d=" + _dispatched + ",io=" + _interestOps+
- ",w=" + _writable + ",rb=" + _readBlocked + ",wb=" + _writeBlocked + "]";
+ return String.format("SCEP@%x{%s->%s,d=%b,open=%b,ishut=%b,oshut=%b,rb=%b,wb=%b,w=%b,i=%d%s%s%s}",
+ hashCode(),
+ _socket.getRemoteSocketAddress(),
+ _socket.getLocalSocketAddress(),
+ _dispatched,
+ isOpen(),
+ isInputShutdown(),
+ isOutputShutdown(),
+ _readBlocked,
+ _writeBlocked,
+ _writable,
+ _interestOps,
+ _key != null && _key.isValid() ? "" : "!",
+ _key != null && _key.isValid() && _key.isReadable() ? "r" : "",
+ _key != null && _key.isValid() && _key.isWritable() ? "w" : "");
}
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java
index 1b8218832a4..eaeabc88624 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java
@@ -30,6 +30,7 @@ import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import org.eclipse.jetty.io.AsyncEndPoint;
import org.eclipse.jetty.io.ConnectedEndPoint;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
@@ -54,7 +55,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
public static final Logger LOG=Log.getLogger("org.eclipse.jetty.io.nio");
private static final int __MONITOR_PERIOD=Integer.getInteger("org.eclipse.jetty.io.nio.MONITOR_PERIOD",1000).intValue();
- private static final int __MAX_SELECTS=Integer.getInteger("org.eclipse.jetty.io.nio.MAX_SELECTS",25000).intValue();
+ private static final int __MAX_SELECTS=Integer.getInteger("org.eclipse.jetty.io.nio.MAX_SELECTS",100000).intValue();
private static final int __BUSY_PAUSE=Integer.getInteger("org.eclipse.jetty.io.nio.BUSY_PAUSE",50).intValue();
private static final int __IDLE_TICK=Integer.getInteger("org.eclipse.jetty.io.nio.IDLE_TICK",400).intValue();
@@ -63,7 +64,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
private long _lowResourcesConnections;
private SelectSet[] _selectSet;
private int _selectSets=1;
- private volatile int _set;
+ private volatile int _set=0;
private boolean _deferringInterestedOps0=true;
private int _selectorPriorityDelta=0;
@@ -128,6 +129,8 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
// be distributed over the available sets.
int s=_set++;
+ if (s<0)
+ s=-s;
s=s%_selectSets;
SelectSet[] sets=_selectSet;
if (sets!=null)
@@ -150,6 +153,8 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
// be distributed over the available sets.
int s=_set++;
+ if (s<0)
+ s=-s;
s=s%_selectSets;
SelectSet[] sets=_selectSet;
if (sets!=null)
@@ -167,6 +172,8 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
public void register(ServerSocketChannel acceptChannel)
{
int s=_set++;
+ if (s<0)
+ s=-s;
s=s%_selectSets;
SelectSet set=_selectSet[s];
set.addChange(acceptChannel);
@@ -276,10 +283,6 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
{
set.doSelect();
}
- catch(ThreadDeath e)
- {
- throw e;
- }
catch(IOException e)
{
LOG.ignore(e);
@@ -337,7 +340,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
protected abstract void endPointUpgraded(ConnectedEndPoint endpoint,Connection oldConnection);
/* ------------------------------------------------------------------------------- */
- protected abstract Connection newConnection(SocketChannel channel, SelectChannelEndPoint endpoint);
+ public abstract AsyncConnection newConnection(SocketChannel channel, AsyncEndPoint endpoint, Object attachment);
/* ------------------------------------------------------------ */
/**
@@ -502,9 +505,6 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
}
catch (Throwable e)
{
- if (e instanceof ThreadDeath)
- throw (ThreadDeath)e;
-
if (isRunning())
LOG.warn(e);
else
@@ -570,21 +570,13 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
{
// Start injecting pauses
_pausing=true;
-
+
// if this is the first pause
if (!_paused)
{
// Log and dump some status
_paused=true;
LOG.warn("Selector {} is too busy, pausing!",this);
- final SelectSet set = this;
- SelectorManager.this.dispatch(
- new Runnable(){
- public void run()
- {
- System.err.println(set+":\n"+set.dump());
- }
- });
}
}
}
@@ -713,17 +705,18 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
endp.checkIdleTimestamp(idle_now);
}
}
+ public String toString() {return "Idle-"+super.toString();}
});
-
+
}
-
+
// Reset busy select monitor counts
if (__MONITOR_PERIOD>0 && now>_monitorNext)
{
_busySelects=0;
_pausing=false;
_monitorNext=now+__MONITOR_PERIOD;
-
+
}
}
catch (ClosedSelectorException e)
@@ -837,6 +830,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
private SelectChannelEndPoint createEndPoint(SocketChannel channel, SelectionKey sKey) throws IOException
{
SelectChannelEndPoint endp = newEndPoint(channel,this,sKey);
+ LOG.debug("created {}",endp);
endPointOpened(endp);
_endPoints.put(endp,this);
return endp;
@@ -975,11 +969,22 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
for (SelectionKey key: selector.keys())
{
if (key.isValid())
- dumpto.add(key.attachment()+" "+key.interestOps()+" "+key.readyOps());
+ dumpto.add(key.attachment()+" iOps="+key.interestOps()+" rOps="+key.readyOps());
else
- dumpto.add(key.attachment()+" - - ");
+ dumpto.add(key.attachment()+" iOps=-1 rOps=-1");
}
}
+
+ /* ------------------------------------------------------------ */
+ public String toString()
+ {
+ Selector selector=_selector;
+ return String.format("%s %s keys=%d selected=%d",
+ super.toString(),
+ SelectorManager.this.getState(),
+ selector != null && selector.isOpen() ? selector.keys().size() : -1,
+ selector != null && selector.isOpen() ? selector.selectedKeys().size() : -1);
+ }
}
/* ------------------------------------------------------------ */
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslConnection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslConnection.java
new file mode 100644
index 00000000000..d8cee6277f5
--- /dev/null
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslConnection.java
@@ -0,0 +1,812 @@
+// ========================================================================
+// Copyright (c) 2004-2011 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+
+package org.eclipse.jetty.io.nio;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.concurrent.atomic.AtomicBoolean;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+
+import org.eclipse.jetty.io.AbstractConnection;
+import org.eclipse.jetty.io.AsyncEndPoint;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.thread.Timeout.Task;
+
+/* ------------------------------------------------------------ */
+/** SSL Connection.
+ * An AysyncConnection that acts as an interceptor between and EndPoint and another
+ * Connection, that implements TLS encryption using an {@link SSLEngine}.
+ *
+ * The connector uses an {@link AsyncEndPoint} (like {@link SelectChannelEndPoint}) as
+ * it's source/sink of encrypted data. It then provides {@link #getSslEndPoint()} to
+ * expose a source/sink of unencrypted data to another connection (eg HttpConnection).
+ */
+public class SslConnection extends AbstractConnection implements AsyncConnection
+{
+ static final Logger LOG=Log.getLogger("org.eclipse.jetty.io.nio.ssl");
+
+ private static final NIOBuffer __ZERO_BUFFER=new IndirectNIOBuffer(0);
+
+ private static final ThreadLocal __buffers = new ThreadLocal();
+ private final SSLEngine _engine;
+ private final SSLSession _session;
+ private AsyncConnection _connection;
+ private final SslEndPoint _sslEndPoint = new SslEndPoint();
+ private int _allocations;
+ private SslBuffers _buffers;
+ private NIOBuffer _inbound;
+ private NIOBuffer _unwrapBuf;
+ private NIOBuffer _outbound;
+ private AsyncEndPoint _aEndp;
+ private boolean _allowRenegotiate=true;
+ private boolean _handshook;
+ private boolean _ishut;
+ private boolean _oshut;
+ private final AtomicBoolean _progressed = new AtomicBoolean();
+
+ /* ------------------------------------------------------------ */
+ /* this is a half baked buffer pool
+ */
+ private static class SslBuffers
+ {
+ final NIOBuffer _in;
+ final NIOBuffer _out;
+ final NIOBuffer _unwrap;
+
+ SslBuffers(int packetSize, int appSize)
+ {
+ _in=new IndirectNIOBuffer(packetSize);
+ _out=new IndirectNIOBuffer(packetSize);
+ _unwrap=new IndirectNIOBuffer(appSize);
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ public SslConnection(SSLEngine engine,EndPoint endp)
+ {
+ this(engine,endp,System.currentTimeMillis());
+ }
+
+ /* ------------------------------------------------------------ */
+ public SslConnection(SSLEngine engine,EndPoint endp, long timeStamp)
+ {
+ super(endp,timeStamp);
+ _engine=engine;
+ _session=_engine.getSession();
+ _aEndp=(AsyncEndPoint)endp;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return True if SSL re-negotiation is allowed (default false)
+ */
+ public boolean isAllowRenegotiate()
+ {
+ return _allowRenegotiate;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set if SSL re-negotiation is allowed. CVE-2009-3555 discovered
+ * a vulnerability in SSL/TLS with re-negotiation. If your JVM
+ * does not have CVE-2009-3555 fixed, then re-negotiation should
+ * not be allowed. CVE-2009-3555 was fixed in Sun java 1.6 with a ban
+ * of renegotiates in u19 and with RFC5746 in u22.
+ *
+ * @param allowRenegotiate
+ * true if re-negotiation is allowed (default false)
+ */
+ public void setAllowRenegotiate(boolean allowRenegotiate)
+ {
+ _allowRenegotiate = allowRenegotiate;
+ }
+
+ /* ------------------------------------------------------------ */
+ private void allocateBuffers()
+ {
+ synchronized (this)
+ {
+ if (_allocations++==0)
+ {
+ if (_buffers==null)
+ {
+ _buffers=__buffers.get();
+ if (_buffers==null)
+ _buffers=new SslBuffers(_session.getPacketBufferSize()*2,_session.getApplicationBufferSize()*2);
+ _inbound=_buffers._in;
+ _outbound=_buffers._out;
+ _unwrapBuf=_buffers._unwrap;
+ __buffers.set(null);
+ }
+ }
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ private void releaseBuffers()
+ {
+ synchronized (this)
+ {
+ if (--_allocations==0)
+ {
+ if (_buffers!=null &&
+ _inbound.length()==0 &&
+ _outbound.length()==0 &&
+ _unwrapBuf.length()==0)
+ {
+ _inbound=null;
+ _outbound=null;
+ _unwrapBuf=null;
+ __buffers.set(_buffers);
+ _buffers=null;
+ }
+ }
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ public Connection handle() throws IOException
+ {
+ try
+ {
+ allocateBuffers();
+
+ boolean progress=true;
+
+ while (progress)
+ {
+ progress=false;
+
+ // If we are handshook let the delegate connection
+ if (_engine.getHandshakeStatus()!=HandshakeStatus.NOT_HANDSHAKING)
+ {
+ progress=process(null,null);
+ }
+ else
+ {
+ // handle the delegate connection
+ AsyncConnection next = (AsyncConnection)_connection.handle();
+ if (next!=_connection && next!=null)
+ {
+ _connection=next;
+ progress=true;
+ }
+ }
+
+ LOG.debug("{} handle {} progress=",_session,this, progress);
+ }
+ }
+ finally
+ {
+ releaseBuffers();
+
+ if (!_ishut && _sslEndPoint.isInputShutdown() && _sslEndPoint.isOpen())
+ {
+ _ishut=true;
+ try
+ {
+ _connection.onInputShutdown();
+ }
+ catch(Throwable x)
+ {
+ LOG.warn("onInputShutdown failed", x);
+ try{_sslEndPoint.close();}
+ catch(IOException e2){LOG.ignore(e2);}
+ }
+ }
+ }
+
+ return this;
+ }
+
+ /* ------------------------------------------------------------ */
+ public boolean isIdle()
+ {
+ return false;
+ }
+
+ /* ------------------------------------------------------------ */
+ public boolean isSuspended()
+ {
+ return false;
+ }
+
+ /* ------------------------------------------------------------ */
+ public void onClose()
+ {
+ }
+
+ /* ------------------------------------------------------------ */
+ @Override
+ public void onIdleExpired(long idleForMs)
+ {
+ try
+ {
+ LOG.debug("onIdleExpired {}ms on {}",idleForMs,this);
+ _sslEndPoint.shutdownOutput();
+ }
+ catch (IOException e)
+ {
+ LOG.warn(e);
+ super.onIdleExpired(idleForMs);
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ public void onInputShutdown() throws IOException
+ {
+
+ }
+
+ /* ------------------------------------------------------------ */
+ private synchronized boolean process(Buffer toFill, Buffer toFlush) throws IOException
+ {
+ boolean some_progress=false;
+ try
+ {
+ allocateBuffers();
+ if (toFill==null)
+ {
+ _unwrapBuf.compact();
+ toFill=_unwrapBuf;
+ }
+ else if (toFill.capacity()<_session.getApplicationBufferSize())
+ {
+ boolean progress=process(null,toFlush);
+ if (_unwrapBuf!=null && _unwrapBuf.hasContent())
+ {
+ _unwrapBuf.skip(toFill.put(_unwrapBuf));
+ return true;
+ }
+ else
+ return progress;
+ }
+ else if (_unwrapBuf!=null && _unwrapBuf.hasContent())
+ {
+ _unwrapBuf.skip(toFill.put(_unwrapBuf));
+ return true;
+ }
+
+
+ if (toFlush==null)
+ toFlush=__ZERO_BUFFER;
+
+ boolean progress=true;
+
+ while (progress)
+ {
+ progress=false;
+ int filled=0,flushed=0;
+
+ try
+ {
+ // Read any available data
+ if (_inbound.space()>0 && (filled=_endp.fill(_inbound))>0)
+ progress = true;
+
+ // flush any output data
+ if (_outbound.hasContent() && (flushed=_endp.flush(_outbound))>0)
+ progress = true;
+ }
+ catch (Exception e)
+ {
+ LOG.debug(e.toString());
+ LOG.ignore(e);
+ }
+ LOG.debug("{} {} {} filled={}/{} flushed={}/{}",_session,this,_engine.getHandshakeStatus(),filled,_inbound.length(),flushed,_outbound.length());
+
+ // handle the current hand share status
+ switch(_engine.getHandshakeStatus())
+ {
+ case FINISHED:
+ throw new IllegalStateException();
+
+ case NOT_HANDSHAKING:
+ {
+ // Try wrapping some application data
+ if (toFlush.hasContent() && _outbound.space()>0 && wrap(toFlush))
+ progress=true;
+
+ // Try unwrapping some application data
+ if (toFill.space()>0 && _inbound.hasContent() && unwrap(toFill))
+ progress=true;
+ }
+ break;
+
+ case NEED_TASK:
+ {
+ // A task needs to be run, so run it!
+ Runnable task;
+ while ((task=_engine.getDelegatedTask())!=null)
+ {
+ progress=true;
+ task.run();
+ }
+
+ // Detect SUN JVM Bug!!!
+ /* TODO
+ if(initialStatus==HandshakeStatus.NOT_HANDSHAKING &&
+ _engine.getHandshakeStatus()==HandshakeStatus.NEED_UNWRAP && sent==0 )
+ {
+ // This should be NEED_WRAP
+ // The fix simply detects the signature of the bug and then close the connection (fail-fast) so that ff3 will delegate to using SSL instead of TLS.
+ // This is a jvm bug on java1.6 where the SSLEngine expects more data from the initial handshake when the client(ff3-tls) already had given it.
+ // See http://jira.codehaus.org/browse/JETTY-567 for more details
+ LOG.warn("{} JETTY-567",_session);
+ _endp.close();
+ return false;
+ }
+ */
+ }
+ break;
+
+ case NEED_WRAP:
+ {
+ // The SSL needs to send some handshake data to the other side
+ if (_handshook && !_allowRenegotiate)
+ _endp.close();
+ else if (wrap(toFlush))
+ progress=true;
+ }
+ break;
+
+ case NEED_UNWRAP:
+ {
+ // The SSL needs to receive some handshake data from the other side
+ if (_handshook && !_allowRenegotiate)
+ _endp.close();
+ else if (unwrap(toFill))
+ progress=true;
+ }
+ break;
+ }
+
+ // pass on ishut/oshut state
+ if (_endp.isOpen() && _endp.isInputShutdown() && !_inbound.hasContent())
+ _engine.closeInbound();
+
+ if (_endp.isOpen() && _engine.isOutboundDone() && !_outbound.hasContent())
+ _endp.shutdownOutput();
+
+ some_progress|=progress;
+ }
+ }
+ finally
+ {
+ releaseBuffers();
+ if (some_progress)
+ _progressed.set(true);
+ }
+ return some_progress;
+ }
+
+ private synchronized boolean wrap(final Buffer buffer) throws IOException
+ {
+ ByteBuffer bbuf=extractByteBuffer(buffer);
+ final SSLEngineResult result;
+
+ synchronized(bbuf)
+ {
+ _outbound.compact();
+ ByteBuffer out_buffer=_outbound.getByteBuffer();
+ synchronized(out_buffer)
+ {
+ try
+ {
+ bbuf.position(buffer.getIndex());
+ bbuf.limit(buffer.putIndex());
+ out_buffer.position(_outbound.putIndex());
+ out_buffer.limit(out_buffer.capacity());
+ result=_engine.wrap(bbuf,out_buffer);
+ if (LOG.isDebugEnabled())
+ LOG.debug("{} wrap {} {} consumed={} produced={}",
+ _session,
+ result.getStatus(),
+ result.getHandshakeStatus(),
+ result.bytesConsumed(),
+ result.bytesProduced());
+
+
+ buffer.skip(result.bytesConsumed());
+ _outbound.setPutIndex(_outbound.putIndex()+result.bytesProduced());
+ }
+ catch(SSLException e)
+ {
+ LOG.warn(_endp+":",e);
+ _endp.close();
+ throw e;
+ }
+ finally
+ {
+ out_buffer.position(0);
+ out_buffer.limit(out_buffer.capacity());
+ bbuf.position(0);
+ bbuf.limit(bbuf.capacity());
+ }
+ }
+ }
+
+ switch(result.getStatus())
+ {
+ case BUFFER_UNDERFLOW:
+ throw new IllegalStateException();
+
+ case BUFFER_OVERFLOW:
+ break;
+
+ case OK:
+ if (result.getHandshakeStatus()==HandshakeStatus.FINISHED)
+ _handshook=true;
+ break;
+
+ case CLOSED:
+ LOG.debug("wrap CLOSE {} {}",this,result);
+ if (result.getHandshakeStatus()==HandshakeStatus.FINISHED)
+ _endp.close();
+ break;
+
+ default:
+ LOG.warn("{} wrap default {}",_session,result);
+ throw new IOException(result.toString());
+ }
+
+ return result.bytesConsumed()>0 || result.bytesProduced()>0;
+ }
+
+ private synchronized boolean unwrap(final Buffer buffer) throws IOException
+ {
+ if (!_inbound.hasContent())
+ return false;
+
+ ByteBuffer bbuf=extractByteBuffer(buffer);
+ final SSLEngineResult result;
+
+ synchronized(bbuf)
+ {
+ ByteBuffer in_buffer=_inbound.getByteBuffer();
+ synchronized(in_buffer)
+ {
+ try
+ {
+ bbuf.position(buffer.putIndex());
+ bbuf.limit(buffer.capacity());
+ in_buffer.position(_inbound.getIndex());
+ in_buffer.limit(_inbound.putIndex());
+
+ result=_engine.unwrap(in_buffer,bbuf);
+ if (LOG.isDebugEnabled())
+ LOG.debug("{} unwrap {} {} consumed={} produced={}",
+ _session,
+ result.getStatus(),
+ result.getHandshakeStatus(),
+ result.bytesConsumed(),
+ result.bytesProduced());
+
+ _inbound.skip(result.bytesConsumed());
+ _inbound.compact();
+ buffer.setPutIndex(buffer.putIndex()+result.bytesProduced());
+ }
+ catch(SSLException e)
+ {
+ LOG.warn(_endp+":"+e);
+ LOG.debug(e);
+ if (_endp.isOpen())
+ _endp.close();
+ throw e;
+ }
+ finally
+ {
+ in_buffer.position(0);
+ in_buffer.limit(in_buffer.capacity());
+ bbuf.position(0);
+ bbuf.limit(bbuf.capacity());
+ }
+ }
+ }
+
+ switch(result.getStatus())
+ {
+ case BUFFER_UNDERFLOW:
+ break;
+
+ case BUFFER_OVERFLOW:
+ LOG.debug("{} unwrap {} {}->{}",_session,result.getStatus(),_inbound.toDetailString(),buffer.toDetailString());
+ break;
+
+ case OK:
+ if (result.getHandshakeStatus()==HandshakeStatus.FINISHED)
+ _handshook=true;
+ break;
+
+ case CLOSED:
+ LOG.debug("unwrap CLOSE {} {}",this,result);
+ if (result.getHandshakeStatus()==HandshakeStatus.FINISHED)
+ _endp.close();
+ break;
+
+ default:
+ LOG.warn("{} wrap default {}",_session,result);
+ throw new IOException(result.toString());
+ }
+
+ //if (LOG.isDebugEnabled() && result.bytesProduced()>0)
+ // LOG.debug("{} unwrapped '{}'",_session,buffer);
+
+ return result.bytesConsumed()>0 || result.bytesProduced()>0;
+ }
+
+
+ /* ------------------------------------------------------------ */
+ private ByteBuffer extractByteBuffer(Buffer buffer)
+ {
+ if (buffer.buffer() instanceof NIOBuffer)
+ return ((NIOBuffer)buffer.buffer()).getByteBuffer();
+ return ByteBuffer.wrap(buffer.array());
+ }
+
+ /* ------------------------------------------------------------ */
+ public AsyncEndPoint getSslEndPoint()
+ {
+ return _sslEndPoint;
+ }
+
+ public String toString()
+ {
+ return String.format("%s | %s", super.toString(), _sslEndPoint);
+ }
+
+ /* ------------------------------------------------------------ */
+ /* ------------------------------------------------------------ */
+ public class SslEndPoint implements AsyncEndPoint
+ {
+ public SSLEngine getSslEngine()
+ {
+ return _engine;
+ }
+
+ public void shutdownOutput() throws IOException
+ {
+ synchronized (SslConnection.this)
+ {
+ LOG.debug("{} ssl endp.oshut {}",_session,this);
+ _engine.closeOutbound();
+ _oshut=true;
+ }
+ flush();
+ }
+
+ public boolean isOutputShutdown()
+ {
+ synchronized (SslConnection.this)
+ {
+ return _oshut||!isOpen()||_engine.isOutboundDone();
+ }
+ }
+
+ public void shutdownInput() throws IOException
+ {
+ LOG.debug("{} ssl endp.ishut!",_session);
+ // We do not do a closeInput here, as SSL does not support half close.
+ // isInputShutdown works it out itself from buffer state and underlying endpoint state.
+ }
+
+ public boolean isInputShutdown()
+ {
+ synchronized (SslConnection.this)
+ {
+ return _endp.isInputShutdown() &&
+ !(_unwrapBuf!=null&&_unwrapBuf.hasContent()) &&
+ !(_inbound!=null&&_inbound.hasContent());
+ }
+ }
+
+ public void close() throws IOException
+ {
+ LOG.debug("{} ssl endp.close",_session);
+ _endp.close();
+ }
+
+ public int fill(Buffer buffer) throws IOException
+ {
+ int size=buffer.length();
+ process(buffer,null);
+
+ int filled=buffer.length()-size;
+
+ if (filled==0 && isInputShutdown())
+ return -1;
+ return filled;
+ }
+
+ public int flush(Buffer buffer) throws IOException
+ {
+ int size = buffer.length();
+ process(null, buffer);
+ return size-buffer.length();
+ }
+
+ public int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException
+ {
+ if (header!=null && header.hasContent())
+ return flush(header);
+ if (buffer!=null && buffer.hasContent())
+ return flush(buffer);
+ if (trailer!=null && trailer.hasContent())
+ return flush(trailer);
+ return 0;
+ }
+
+ public boolean blockReadable(long millisecs) throws IOException
+ {
+ long now = System.currentTimeMillis();
+ long end=millisecs>0?(now+millisecs):Long.MAX_VALUE;
+
+ while (now
- * A SelectChannelEndPoint that uses an {@link SSLEngine} to handle an
- * SSL connection.
- *
- * There is a named logger "org.eclipse.jetty.http.ssl"
- *
- */
-public class SslSelectChannelEndPoint extends SelectChannelEndPoint
-{
- public static final Logger LOG=Log.getLogger("org.eclipse.jetty.io.nio").getLogger("ssl");
-
- private static final Buffer __EMPTY_BUFFER=new DirectNIOBuffer(0);
- private static final ByteBuffer __ZERO_BUFFER=ByteBuffer.allocate(0);
-
- private final Buffers _buffers;
-
- private final SSLEngine _engine;
- private final SSLSession _session;
- private volatile NIOBuffer _inNIOBuffer;
- private volatile NIOBuffer _outNIOBuffer;
-
- private boolean _closing=false;
- private SSLEngineResult _result;
-
- private volatile boolean _handshook=false;
- private boolean _allowRenegotiate=true;
-
- private volatile boolean _debug = LOG.isDebugEnabled(); // snapshot debug status for optimizer
-
- /* ------------------------------------------------------------ */
- public SslSelectChannelEndPoint(Buffers buffers,SocketChannel channel, SelectorManager.SelectSet selectSet, SelectionKey key, SSLEngine engine, int maxIdleTime)
- throws IOException
- {
- super(channel,selectSet,key, maxIdleTime);
- _buffers=buffers;
-
- // ssl
- _engine=engine;
- _session=engine.getSession();
-
- if (_debug) LOG.debug(_session+" channel="+channel);
- }
-
- /* ------------------------------------------------------------ */
- public SslSelectChannelEndPoint(Buffers buffers,SocketChannel channel, SelectorManager.SelectSet selectSet, SelectionKey key, SSLEngine engine)
- throws IOException
- {
- super(channel,selectSet,key);
- _buffers=buffers;
-
- // ssl
- _engine=engine;
- _session=engine.getSession();
-
- if (_debug) LOG.debug(_session+" channel="+channel);
- }
-
-
- /* ------------------------------------------------------------ */
- private void needOutBuffer()
- {
- synchronized (this)
- {
- if (_outNIOBuffer==null)
- _outNIOBuffer=(NIOBuffer)_buffers.getBuffer(_session.getPacketBufferSize());
- }
- }
-
- /* ------------------------------------------------------------ */
- private void freeOutBuffer()
- {
- synchronized (this)
- {
- if (_outNIOBuffer!=null && _outNIOBuffer.length()==0)
- {
- _buffers.returnBuffer(_outNIOBuffer);
- _outNIOBuffer=null;
- }
- }
- }
-
- /* ------------------------------------------------------------ */
- private void needInBuffer()
- {
- synchronized (this)
- {
- if(_inNIOBuffer==null)
- _inNIOBuffer=(NIOBuffer)_buffers.getBuffer(_session.getPacketBufferSize());
- }
- }
-
- /* ------------------------------------------------------------ */
- private void freeInBuffer()
- {
- synchronized (this)
- {
- if (_inNIOBuffer!=null && _inNIOBuffer.length()==0)
- {
- _buffers.returnBuffer(_inNIOBuffer);
- _inNIOBuffer=null;
- }
- }
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @return True if the endpoint has produced/consumed bytes itself (non application data).
- */
- public boolean isProgressing()
- {
- SSLEngineResult result = _result;
- _result=null;
- return result!=null && (result.bytesConsumed()>0 || result.bytesProduced()>0);
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @return True if SSL re-negotiation is allowed (default false)
- */
- public boolean isAllowRenegotiate()
- {
- return _allowRenegotiate;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * Set if SSL re-negotiation is allowed. CVE-2009-3555 discovered
- * a vulnerability in SSL/TLS with re-negotiation. If your JVM
- * does not have CVE-2009-3555 fixed, then re-negotiation should
- * not be allowed.
- * @param allowRenegotiate true if re-negotiation is allowed (default false)
- */
- public void setAllowRenegotiate(boolean allowRenegotiate)
- {
- _allowRenegotiate = allowRenegotiate;
- }
-
-
- /* ------------------------------------------------------------ */
- @Override
- public boolean isOutputShutdown()
- {
- return _engine!=null && _engine.isOutboundDone();
- }
-
- /* ------------------------------------------------------------ */
- @Override
- public boolean isInputShutdown()
- {
- return _engine!=null && _engine.isInboundDone();
- }
-
- /* ------------------------------------------------------------ */
- @Override
- public void shutdownOutput() throws IOException
- {
- LOG.debug("{} shutdownOutput",_session);
- // All SSL closes should be graceful, as it is more secure.
- // So normal SSL close can be used here.
- close();
- }
-
- /* ------------------------------------------------------------ */
- private int process(ByteBuffer inBBuf, Buffer outBuf) throws IOException
- {
- if (_debug)
- LOG.debug("{} process closing={} in={} out={}",_session,_closing,inBBuf,outBuf);
-
- // If there is no place to put incoming application data,
- if (inBBuf==null)
- {
- // use ZERO buffer
- inBBuf=__ZERO_BUFFER;
- }
-
- int received=0;
- int sent=0;
-
-
- HandshakeStatus initialStatus = _engine.getHandshakeStatus();
- boolean progress=true;
-
- while (progress)
- {
- progress=false;
-
- // flush output data
- int len=_outNIOBuffer==null?0:_outNIOBuffer.length();
-
- // we must flush it, as the other end might be
- // waiting for that outgoing data before sending
- // more incoming data
- flush();
-
- // If we have written some bytes, then progress has been made.
- progress|=(_outNIOBuffer==null?0:_outNIOBuffer.length())0||_result.bytesProduced()>0||_result.bytesConsumed()>0;
-
- if (c>0)
- sent+=c;
- else if (c<0 && sent==0)
- sent=-1;
- }
-
- // Try unwrapping some application data
- if (inBBuf.remaining()>0 && _inNIOBuffer!=null && _inNIOBuffer.hasContent())
- {
- int space=inBBuf.remaining();
- progress|=unwrap(inBBuf);
- received+=space-inBBuf.remaining();
- }
- break;
-
-
- case NEED_TASK:
- {
- // A task needs to be run, so run it!
- Runnable task;
- while ((task=_engine.getDelegatedTask())!=null)
- {
- progress=true;
- task.run();
- }
-
- // Detect SUN JVM Bug!!!
- if(initialStatus==HandshakeStatus.NOT_HANDSHAKING &&
- _engine.getHandshakeStatus()==HandshakeStatus.NEED_UNWRAP && sent==0)
- {
- // This should be NEED_WRAP
- // The fix simply detects the signature of the bug and then close the connection (fail-fast) so that ff3 will delegate to using SSL instead of TLS.
- // This is a jvm bug on java1.6 where the SSLEngine expects more data from the initial handshake when the client(ff3-tls) already had given it.
- // See http://jira.codehaus.org/browse/JETTY-567 for more details
- if (_debug) LOG.warn("{} JETTY-567",_session);
- return -1;
- }
- break;
- }
-
- case NEED_WRAP:
- {
- checkRenegotiate();
-
- // The SSL needs to send some handshake data to the other side
- int c=0;
- if (outBuf!=null && outBuf.hasContent())
- c=wrap(outBuf);
- else
- c=wrap(__EMPTY_BUFFER);
-
- progress=_result.bytesProduced()>0||_result.bytesConsumed()>0;
- if (c>0)
- sent+=c;
- else if (c<0 && sent==0)
- sent=-1;
- break;
- }
-
- case NEED_UNWRAP:
- {
- checkRenegotiate();
-
- // Need more data to be unwrapped so try another call to unwrap
- progress|=unwrap(inBBuf);
- if (_closing && inBBuf.hasRemaining())
- inBBuf.clear();
- break;
- }
- }
-
- if (_debug) LOG.debug("{} progress {}",_session,progress);
- }
-
- if (_debug) LOG.debug("{} received {} sent {}",_session,received,sent);
-
- freeInBuffer();
- return (received<0||sent<0)?-1:(received+sent);
- }
-
-
-
- /* ------------------------------------------------------------ */
- @Override
- public void close() throws IOException
- {
- // For safety we always force a close calling super
- try
- {
- if (!_closing)
- {
- _closing=true;
- LOG.debug("{} close",_session);
- _engine.closeOutbound();
- process(null,null);
- }
- }
- catch (IOException e)
- {
- // We could not write the SSL close message because the
- // socket was already closed, nothing more we can do.
- LOG.ignore(e);
- }
- finally
- {
- super.close();
- }
- }
-
- /* ------------------------------------------------------------ */
- /** Fill the buffer with unencrypted bytes.
- * Called by a Http Parser when more data is
- * needed to continue parsing a request or a response.
- */
- @Override
- public int fill(Buffer buffer) throws IOException
- {
- _debug=LOG.isDebugEnabled();
- LOG.debug("{} fill",_session);
- // This end point only works on NIO buffer type (director
- // or indirect), so extract the NIO buffer that is wrapped
- // by the passed jetty Buffer.
- ByteBuffer bbuf=((NIOBuffer)buffer).getByteBuffer();
-
-
- // remember the original size of the unencrypted buffer
- int size=buffer.length();
-
-
- synchronized (bbuf)
- {
- bbuf.position(buffer.putIndex());
- try
- {
- // Call the SSLEngine unwrap method to process data in
- // the inBuffer. If there is no data in the inBuffer, then
- // super.fill is called to read encrypted bytes.
- unwrap(bbuf);
- process(bbuf,null);
- }
- finally
- {
- // reset the Buffers
- buffer.setPutIndex(bbuf.position());
- bbuf.position(0);
- }
- }
- // return the number of unencrypted bytes filled.
- int filled=buffer.length()-size;
- if (filled==0 && (isInputShutdown() || !isOpen()))
- return -1;
-
- return filled;
- }
-
- /* ------------------------------------------------------------ */
- @Override
- public int flush(Buffer buffer) throws IOException
- {
- _debug=LOG.isDebugEnabled();
- LOG.debug("{} flush1",_session);
- return process(null,buffer);
- }
-
-
- /* ------------------------------------------------------------ */
- /*
- */
- @Override
- public int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException
- {
- _debug=LOG.isDebugEnabled();
- LOG.debug("{} flush3",_session);
-
- int len=0;
- int flushed=0;
- if (header!=null && header.hasContent())
- {
- len=header.length();
- flushed=flush(header);
- }
- if (flushed==len && buffer!=null && buffer.hasContent())
- {
- int f=flush(buffer);
- if (f>=0)
- flushed+=f;
- else if (flushed==0)
- flushed=-1;
- }
-
- return flushed;
- }
-
- /* ------------------------------------------------------------ */
- @Override
- public void flush() throws IOException
- {
- LOG.debug("{} flush",_session);
- if (!isOpen())
- throw new EofException();
-
- if (isBufferingOutput())
- {
- int flushed=super.flush(_outNIOBuffer);
- if (_debug)
- LOG.debug("{} flushed={} left={}",_session,flushed,_outNIOBuffer.length());
- }
- else if (_engine.isOutboundDone() && super.isOpen())
- {
- if (_debug)
- LOG.debug("{} flush shutdownOutput",_session);
- try
- {
- super.shutdownOutput();
- }
- catch(IOException e)
- {
- LOG.ignore(e);
- }
- }
-
- freeOutBuffer();
- }
-
- /* ------------------------------------------------------------ */
- private void checkRenegotiate() throws IOException
- {
- if (_handshook && !_allowRenegotiate && _channel!=null && _channel.isOpen())
- {
- LOG.warn("SSL renegotiate denied: {}",_channel);
- super.close();
- }
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @return true if progress is made
- */
- private boolean unwrap(ByteBuffer buffer) throws IOException
- {
- needInBuffer();
- ByteBuffer in_buffer=_inNIOBuffer.getByteBuffer();
-
- _inNIOBuffer.compact();
-
- int total_filled=0;
- boolean remoteClosed = false;
-
- LOG.debug("{} unwrap space={} open={}",_session,_inNIOBuffer.space(),super.isOpen());
-
- // loop filling as much encrypted data as we can into the buffer
- while (_inNIOBuffer.space()>0 && super.isOpen())
- {
- int filled=super.fill(_inNIOBuffer);
- if (_debug) LOG.debug("{} filled {}",_session,filled);
- if (filled < 0)
- remoteClosed = true;
- // break the loop if no progress is made (we have read everything there is to read)
- if (filled<=0)
- break;
- total_filled+=filled;
- }
-
- // If we have no progress and no data
- if (total_filled==0 && _inNIOBuffer.length()==0)
- {
- // Do we need to close?
- if (isOpen() && remoteClosed)
- {
- try
- {
- _engine.closeInbound();
- }
- catch (SSLException x)
- {
- // It may happen, for example, in case of truncation
- // attacks, we close so that we do not spin forever
- super.close();
- }
- }
-
- if (!isOpen())
- throw new EofException();
-
- return false;
- }
-
- // We have some in data, so try to unwrap it.
- try
- {
- // inBuffer is the NIO buffer inside the _inNIOBuffer,
- // so update its position and limit from the inNIOBuffer.
- in_buffer.position(_inNIOBuffer.getIndex());
- in_buffer.limit(_inNIOBuffer.putIndex());
-
- // Do the unwrap
- _result=_engine.unwrap(in_buffer,buffer);
- if (!_handshook && _result.getHandshakeStatus()==SSLEngineResult.HandshakeStatus.FINISHED)
- _handshook=true;
- if (_debug) LOG.debug("{} unwrap {}",_session,_result);
-
- // skip the bytes consumed
- _inNIOBuffer.skip(_result.bytesConsumed());
- }
- catch(SSLException e)
- {
- LOG.debug(getRemoteAddr() + ":" + getRemotePort() + " ",e);
- super.close();
- throw e;
- }
- finally
- {
- // reset the buffer so it can be managed by the _inNIOBuffer again.
- in_buffer.position(0);
- in_buffer.limit(in_buffer.capacity());
- }
-
- // handle the unwrap results
- switch(_result.getStatus())
- {
- case BUFFER_OVERFLOW:
- LOG.debug("{} unwrap overflow",_session);
- return false;
-
- case BUFFER_UNDERFLOW:
- // Not enough data,
- // If we are closed, we will never get more, so EOF
- // else return and we will be tried again
- // later when more data arriving causes another dispatch.
- if (LOG.isDebugEnabled()) LOG.debug("{} unwrap {}",_session,_result);
- if(!isOpen())
- {
- _inNIOBuffer.clear();
- if (_outNIOBuffer!=null)
- _outNIOBuffer.clear();
- throw new EofException();
- }
- return (total_filled > 0);
-
- case CLOSED:
- _closing=true;
- // return true is some bytes somewhere were moved about.
- return total_filled>0 ||_result.bytesConsumed()>0 || _result.bytesProduced()>0;
-
- case OK:
- // return true is some bytes somewhere were moved about.
- return total_filled>0 ||_result.bytesConsumed()>0 || _result.bytesProduced()>0;
-
- default:
- LOG.warn("{} unwrap default: {}",_session,_result);
- throw new IOException(_result.toString());
- }
- }
-
- /* ------------------------------------------------------------ */
- private ByteBuffer extractOutputBuffer(Buffer buffer)
- {
- if (buffer.buffer() instanceof NIOBuffer)
- return ((NIOBuffer)buffer.buffer()).getByteBuffer();
-
- return ByteBuffer.wrap(buffer.array());
- }
-
- /* ------------------------------------------------------------ */
- private int wrap(final Buffer buffer) throws IOException
- {
- ByteBuffer bbuf=extractOutputBuffer(buffer);
- synchronized(bbuf)
- {
- int consumed=0;
- needOutBuffer();
- _outNIOBuffer.compact();
- ByteBuffer out_buffer=_outNIOBuffer.getByteBuffer();
- synchronized(out_buffer)
- {
- try
- {
- bbuf.position(buffer.getIndex());
- bbuf.limit(buffer.putIndex());
- out_buffer.position(_outNIOBuffer.putIndex());
- out_buffer.limit(out_buffer.capacity());
- _result=_engine.wrap(bbuf,out_buffer);
- if (_debug) LOG.debug("{} wrap {}",_session,_result);
- if (!_handshook && _result.getHandshakeStatus()==SSLEngineResult.HandshakeStatus.FINISHED)
- _handshook=true;
- _outNIOBuffer.setPutIndex(out_buffer.position());
- consumed=_result.bytesConsumed();
- }
- catch(SSLException e)
- {
- LOG.warn(getRemoteAddr()+":"+getRemotePort()+" ",e);
- if (getChannel().isOpen())
- getChannel().close();
- throw e;
- }
- finally
- {
- out_buffer.position(0);
- bbuf.position(0);
- bbuf.limit(bbuf.capacity());
-
- if (consumed>0)
- {
- int len=consumed0?_result.bytesConsumed():-1;
-
- default:
- LOG.warn("{} wrap default {}",_session,_result);
- throw new IOException(_result.toString());
- }
- }
-
- /* ------------------------------------------------------------ */
- @Override
- public boolean isBufferingInput()
- {
- final Buffer in = _inNIOBuffer;
- return in!=null && in.hasContent();
- }
-
- /* ------------------------------------------------------------ */
- @Override
- public boolean isBufferingOutput()
- {
- final NIOBuffer out = _outNIOBuffer;
- return out!=null && out.hasContent();
- }
-
- /* ------------------------------------------------------------ */
- @Override
- public boolean isBufferred()
- {
- return true;
- }
-
- /* ------------------------------------------------------------ */
- public SSLEngine getSSLEngine()
- {
- return _engine;
- }
-
- /* ------------------------------------------------------------ */
- @Override
- public String toString()
- {
- final NIOBuffer i=_inNIOBuffer;
- final NIOBuffer o=_outNIOBuffer;
- return "SSL"+super.toString()+","+(_engine==null?"-":_engine.getHandshakeStatus())+", in/out="+
- (i==null?0:i.length())+"/"+(o==null?0:o.length())+
- " bi/o="+isBufferingInput()+"/"+isBufferingOutput()+
- " "+_result;
- }
-}
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/EndPointTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/EndPointTest.java
index 75922f50437..51be3cd751f 100644
--- a/jetty-io/src/test/java/org/eclipse/jetty/io/EndPointTest.java
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/EndPointTest.java
@@ -1,62 +1,157 @@
package org.eclipse.jetty.io;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.concurrent.Exchanger;
-import java.util.concurrent.TimeUnit;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
-import org.eclipse.jetty.io.bio.SocketEndPoint;
import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
-import org.junit.Assert;
import org.junit.Test;
-public class EndPointTest
+public abstract class EndPointTest
{
+ public static class EndPointPair
+ {
+ public T client;
+ public T server;
+ }
+
+ protected abstract EndPointPair newConnection() throws Exception;
+
+
@Test
- public void testSocketEndPoints() throws Exception
+ public void testClientServerExchange() throws Exception
{
- final ServerSocket server = new ServerSocket();
- server.bind(null);
+ EndPointPair c = newConnection();
+ Buffer buffer = new IndirectNIOBuffer(4096);
- final Exchanger accepted = new Exchanger();
- new Thread(){
- public void run()
- {
- try
- {
- accepted.exchange(server.accept());
- }
- catch(Exception e)
- {
- e.printStackTrace();
- }
- }
- }.start();
+ // Client sends a request
+ c.client.flush(new ByteArrayBuffer("request"));
- Socket s0 = new Socket(server.getInetAddress(),server.getLocalPort());
- Socket s1 = accepted.exchange(null,5,TimeUnit.SECONDS);
+ // Server receives the request
+ int len = c.server.fill(buffer);
+ assertEquals(7,len);
+ assertEquals("request",buffer.toString());
+
+ // Client and server are open
+ assertTrue(c.client.isOpen());
+ assertFalse(c.client.isInputShutdown());
+ assertFalse(c.client.isOutputShutdown());
+ assertTrue(c.server.isOpen());
+ assertFalse(c.server.isInputShutdown());
+ assertFalse(c.server.isOutputShutdown());
- SocketEndPoint in = new SocketEndPoint(s0);
- SocketEndPoint out = new SocketEndPoint(s1);
+ // Server sends response and closes output
+ c.server.flush(new ByteArrayBuffer("response"));
+ c.server.shutdownOutput();
+
+ // client server are open, server is oshut
+ assertTrue(c.client.isOpen());
+ assertFalse(c.client.isInputShutdown());
+ assertFalse(c.client.isOutputShutdown());
+ assertTrue(c.server.isOpen());
+ assertFalse(c.server.isInputShutdown());
+ assertTrue(c.server.isOutputShutdown());
+
+ // Client reads response
+ buffer.clear();
+ len = c.client.fill(buffer);
+ assertEquals(8,len);
+ assertEquals("response",buffer.toString());
+
+ // Client and server are open, server is oshut
+ assertTrue(c.client.isOpen());
+ assertFalse(c.client.isInputShutdown());
+ assertFalse(c.client.isOutputShutdown());
+ assertTrue(c.server.isOpen());
+ assertFalse(c.server.isInputShutdown());
+ assertTrue(c.server.isOutputShutdown());
+
+ // Client reads -1
+ buffer.clear();
+ len = c.client.fill(buffer);
+ assertEquals(-1,len);
+
+ // Client and server are open, server is oshut, client is ishut
+ assertTrue(c.client.isOpen());
+ assertTrue(c.client.isInputShutdown());
+ assertFalse(c.client.isOutputShutdown());
+ assertTrue(c.server.isOpen());
+ assertFalse(c.server.isInputShutdown());
+ assertTrue(c.server.isOutputShutdown());
+
+ // Client shutsdown output, which is a close because already ishut
+ c.client.shutdownOutput();
+
+ // Client is closed. Server is open and oshut
+ assertFalse(c.client.isOpen());
+ assertTrue(c.client.isInputShutdown());
+ assertTrue(c.client.isOutputShutdown());
+ assertTrue(c.server.isOpen());
+ assertFalse(c.server.isInputShutdown());
+ assertTrue(c.server.isOutputShutdown());
+
+ // Server reads close
+ buffer.clear();
+ len = c.server.fill(buffer);
+ assertEquals(-1,len);
+
+ // Client and Server are closed
+ assertFalse(c.client.isOpen());
+ assertTrue(c.client.isInputShutdown());
+ assertTrue(c.client.isOutputShutdown());
+ assertFalse(c.server.isOpen());
+ assertTrue(c.server.isInputShutdown());
+ assertTrue(c.server.isOutputShutdown());
- check(in,out);
}
-
- private void check(EndPoint in, EndPoint out) throws Exception
+
+
+ @Test
+ public void testClientClose() throws Exception
{
- String data="Now is the time for all good men to come to the aid of the party";
- Buffer send = new ByteArrayBuffer(data);
- Buffer receive = new IndirectNIOBuffer(4096);
+ EndPointPair c = newConnection();
+ Buffer buffer = new IndirectNIOBuffer(4096);
- int lo=out.flush(send);
- int li=in.fill(receive);
+ c.client.flush(new ByteArrayBuffer("request"));
+ int len = c.server.fill(buffer);
+ assertEquals(7,len);
+ assertEquals("request",buffer.toString());
+
+ assertTrue(c.client.isOpen());
+ assertFalse(c.client.isInputShutdown());
+ assertFalse(c.client.isOutputShutdown());
+ assertTrue(c.server.isOpen());
+ assertFalse(c.server.isInputShutdown());
+ assertFalse(c.server.isOutputShutdown());
- Assert.assertEquals(data.length(),lo);
- Assert.assertEquals(data.length(),li);
- Assert.assertEquals(data,receive.toString());
+ c.client.close();
+
+ assertFalse(c.client.isOpen());
+ assertTrue(c.client.isInputShutdown());
+ assertTrue(c.client.isOutputShutdown());
+ assertTrue(c.server.isOpen());
+ assertFalse(c.server.isInputShutdown());
+ assertFalse(c.server.isOutputShutdown());
- in.close();
- out.close();
- }
+ len = c.server.fill(buffer);
+ assertEquals(-1,len);
+
+ assertFalse(c.client.isOpen());
+ assertTrue(c.client.isInputShutdown());
+ assertTrue(c.client.isOutputShutdown());
+ assertTrue(c.server.isOpen());
+ assertTrue(c.server.isInputShutdown());
+ assertFalse(c.server.isOutputShutdown());
+
+ c.server.shutdownOutput();
+
+ assertFalse(c.client.isOpen());
+ assertTrue(c.client.isInputShutdown());
+ assertTrue(c.client.isOutputShutdown());
+ assertFalse(c.server.isOpen());
+ assertTrue(c.server.isInputShutdown());
+ assertTrue(c.server.isOutputShutdown());
+ }
+
}
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java
index 1ca3b75fdfc..8575ab7f229 100644
--- a/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java
@@ -14,15 +14,17 @@
package org.eclipse.jetty.io;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
-import java.io.Reader;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
import org.eclipse.jetty.util.IO;
import org.junit.Test;
@@ -50,14 +52,12 @@ public class IOTest
}
@Test
- public void testHalfCloses() throws Exception
+ public void testHalfClose() throws Exception
{
ServerSocket connector = new ServerSocket(0);
Socket client = new Socket("localhost",connector.getLocalPort());
- System.err.println(client);
Socket server = connector.accept();
- System.err.println(server);
// we can write both ways
client.getOutputStream().write(1);
@@ -76,7 +76,7 @@ public class IOTest
assertEquals(-1,server.getInputStream().read());
// but cannot write
- try { client.getOutputStream().write(1); assertTrue(false); } catch (SocketException e) {}
+ try { client.getOutputStream().write(1); fail("exception expected"); } catch (SocketException e) {}
// but can still write in opposite direction.
server.getOutputStream().write(1);
@@ -87,7 +87,7 @@ public class IOTest
server.shutdownInput();
// now we EOF instead of reading -1
- try { server.getInputStream().read(); assertTrue(false); } catch (SocketException e) {}
+ try { server.getInputStream().read(); fail("exception expected"); } catch (SocketException e) {}
// but can still write in opposite direction.
@@ -98,7 +98,7 @@ public class IOTest
client.shutdownInput();
// now we EOF instead of reading -1
- try { client.getInputStream().read(); assertTrue(false); } catch (SocketException e) {}
+ try { client.getInputStream().read(); fail("exception expected"); } catch (SocketException e) {}
// But we can still write at the server (data which will never be read)
server.getOutputStream().write(1);
@@ -110,7 +110,7 @@ public class IOTest
server.shutdownOutput();
// and now we can't write
- try { server.getOutputStream().write(1); assertTrue(false); } catch (SocketException e) {}
+ try { server.getOutputStream().write(1); fail("exception expected"); } catch (SocketException e) {}
// but the sockets are still open
assertFalse(client.isClosed());
@@ -128,8 +128,114 @@ public class IOTest
// which has to be closed explictly
server.close();
assertTrue(server.isClosed());
-
-
-
+
}
+
+
+ @Test
+ public void testHalfCloseClientServer() throws Exception
+ {
+ ServerSocketChannel connector = ServerSocketChannel.open();
+ connector.socket().bind(null);
+
+ Socket client = SocketChannel.open(connector.socket().getLocalSocketAddress()).socket();
+ client.setSoTimeout(1000);
+ client.setSoLinger(false,-1);
+ Socket server = connector.accept().socket();
+ server.setSoTimeout(1000);
+ server.setSoLinger(false,-1);
+
+ // Write from client to server
+ client.getOutputStream().write(1);
+
+ // Server reads
+ assertEquals(1,server.getInputStream().read());
+
+ // Write from server to client with oshut
+ server.getOutputStream().write(1);
+ System.err.println("OSHUT "+server);
+ server.shutdownOutput();
+
+ // Client reads response
+ assertEquals(1,client.getInputStream().read());
+
+ try
+ {
+ // Client reads -1 and does ishut
+ assertEquals(-1,client.getInputStream().read());
+ assertFalse(client.isInputShutdown());
+ System.err.println("ISHUT "+client);
+ client.shutdownInput();
+
+ // Client ???
+ System.err.println("OSHUT "+client);
+ client.shutdownOutput();
+ System.err.println("CLOSE "+client);
+ client.close();
+
+ // Server reads -1, does ishut and then close
+ assertEquals(-1,server.getInputStream().read());
+ assertFalse(server.isInputShutdown());
+ System.err.println("ISHUT "+server);
+
+ try
+ {
+ server.shutdownInput();
+ }
+ catch(SocketException e)
+ {
+ System.err.println(e);
+ }
+ System.err.println("CLOSE "+server);
+ server.close();
+
+ }
+ catch(Exception e)
+ {
+ // Dang OSX!
+ System.err.println(e);
+ }
+ }
+
+ @Test
+ public void testReset() throws Exception
+ {
+ ServerSocket connector;
+ Socket client;
+ Socket server;
+
+ connector = new ServerSocket(9123);
+ client = new Socket("127.0.0.1",connector.getLocalPort());
+ server = connector.accept();
+ client.setTcpNoDelay(true);
+ client.setSoLinger(true,0);
+ server.setTcpNoDelay(true);
+ server.setSoLinger(true,0);
+
+ client.getOutputStream().write(1);
+ assertEquals(1,server.getInputStream().read());
+ server.getOutputStream().write(1);
+ assertEquals(1,client.getInputStream().read());
+
+ // Server generator shutdowns output after non persistent sending response.
+ server.shutdownOutput();
+
+ // client endpoint reads EOF and shutdown input as result
+ assertEquals(-1,client.getInputStream().read());
+ client.shutdownInput();
+
+ // client connection see's EOF and shutsdown output as no more requests to be sent.
+ client.shutdownOutput();
+
+ // Since input already shutdown, client also closes socket.
+ client.close();
+
+ // Server reads the EOF from client oshut and shut's down it's input
+ assertEquals(-1,server.getInputStream().read());
+ server.shutdownInput();
+
+ // Since output was already shutdown, server closes
+ server.close();
+ }
+
}
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/bio/SocketEndPointTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/bio/SocketEndPointTest.java
new file mode 100644
index 00000000000..277c6c7ccba
--- /dev/null
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/bio/SocketEndPointTest.java
@@ -0,0 +1,38 @@
+package org.eclipse.jetty.io.bio;
+
+import java.net.ServerSocket;
+import java.net.Socket;
+
+import org.eclipse.jetty.io.EndPointTest;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public class SocketEndPointTest extends EndPointTest
+{
+ static ServerSocket connector;
+
+ @BeforeClass
+ public static void open() throws Exception
+ {
+ connector = new ServerSocket();
+ connector.bind(null);
+ }
+
+ @AfterClass
+ public static void close() throws Exception
+ {
+ connector.close();
+ connector=null;
+ }
+
+ @Override
+ protected EndPointPair newConnection() throws Exception
+ {
+ EndPointPair c = new EndPointPair();
+ c.client=new SocketEndPoint(new Socket(connector.getInetAddress(),connector.getLocalPort()));
+ c.server=new SocketEndPoint(connector.accept());
+ return c;
+ }
+
+
+}
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/nio/ChannelEndPointTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/nio/ChannelEndPointTest.java
new file mode 100644
index 00000000000..1d8d5b2c7eb
--- /dev/null
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/nio/ChannelEndPointTest.java
@@ -0,0 +1,43 @@
+package org.eclipse.jetty.io.nio;
+
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+
+import org.eclipse.jetty.io.EndPointTest;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public class ChannelEndPointTest extends EndPointTest
+{
+ static ServerSocketChannel connector;
+
+ @BeforeClass
+ public static void open() throws Exception
+ {
+ connector = ServerSocketChannel.open();
+ connector.socket().bind(null);
+ }
+
+ @AfterClass
+ public static void close() throws Exception
+ {
+ connector.close();
+ connector=null;
+ }
+
+ @Override
+ protected EndPointPair newConnection() throws Exception
+ {
+ EndPointPair c = new EndPointPair();
+
+ c.client=new ChannelEndPoint(SocketChannel.open(connector.socket().getLocalSocketAddress()));
+ c.server=new ChannelEndPoint(connector.accept());
+ return c;
+ }
+
+ @Override
+ public void testClientServerExchange() throws Exception
+ {
+ super.testClientServerExchange();
+ }
+}
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/nio/NIOTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/nio/NIOTest.java
new file mode 100644
index 00000000000..9366d8ce843
--- /dev/null
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/nio/NIOTest.java
@@ -0,0 +1,131 @@
+// ========================================================================
+// Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+
+package org.eclipse.jetty.io.nio;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.SocketChannel;
+
+import org.junit.Test;
+
+/**
+ *
+ */
+public class NIOTest
+{
+ @Test
+ public void testSelector() throws Exception
+ {
+ ServerSocket acceptor = new ServerSocket(0);
+
+ Selector selector = Selector.open();
+
+ // Create client server socket pair
+ SocketChannel client = SocketChannel.open(acceptor.getLocalSocketAddress());
+ Socket server = acceptor.accept();
+ server.setTcpNoDelay(true);
+
+ // Make the client non blocking and register it with selector for reads
+ client.configureBlocking(false);
+ SelectionKey key = client.register(selector,SelectionKey.OP_READ);
+
+ // assert it is not selected
+ assertTrue(key.isValid());
+ assertFalse(key.isReadable());
+ assertEquals(0,key.readyOps());
+
+ // try selecting and assert nothing selected
+ int selected = selector.selectNow();
+ assertEquals(0,selected);
+ assertEquals(0,selector.selectedKeys().size());
+ assertTrue(key.isValid());
+ assertFalse(key.isReadable());
+ assertEquals(0,key.readyOps());
+
+ // Write a byte from server to client
+ server.getOutputStream().write(42);
+ server.getOutputStream().flush();
+
+ // select again and assert selection found for read
+ selected = selector.select(1000);
+ assertEquals(1,selected);
+ assertEquals(1,selector.selectedKeys().size());
+ assertTrue(key.isValid());
+ assertTrue(key.isReadable());
+ assertEquals(1,key.readyOps());
+
+ // select again and see that it is not reselect, but stays selected
+ selected = selector.select(100);
+ assertEquals(0,selected);
+ assertEquals(1,selector.selectedKeys().size());
+ assertTrue(key.isValid());
+ assertTrue(key.isReadable());
+ assertEquals(1,key.readyOps());
+
+ // read the byte
+ ByteBuffer buf = ByteBuffer.allocate(1024);
+ int len=client.read(buf);
+ assertEquals(1,len);
+ buf.flip();
+ assertEquals(42,buf.get());
+ buf.clear();
+
+ // But this does not change the key
+ assertTrue(key.isValid());
+ assertTrue(key.isReadable());
+ assertEquals(1,key.readyOps());
+
+ // Even if we select again ?
+ selected = selector.select(100);
+ assertEquals(0,selected);
+ assertEquals(1,selector.selectedKeys().size());
+ assertTrue(key.isValid());
+ assertTrue(key.isReadable());
+ assertEquals(1,key.readyOps());
+
+ // Unless we remove the key from the select set
+ // and then it is still flagged as isReadable()
+ selector.selectedKeys().clear();
+ assertEquals(0,selector.selectedKeys().size());
+ assertTrue(key.isValid());
+ assertTrue(key.isReadable());
+ assertEquals(1,key.readyOps());
+
+ // Now if we select again - it is still flagged as readable!!!
+ selected = selector.select(100);
+ assertEquals(0,selected);
+ assertEquals(0,selector.selectedKeys().size());
+ assertTrue(key.isValid());
+ assertTrue(key.isReadable());
+ assertEquals(1,key.readyOps());
+
+ // Only when it is selected for something else does that state change.
+ key.interestOps(SelectionKey.OP_READ|SelectionKey.OP_WRITE);
+ selected = selector.select(1000);
+ assertEquals(1,selected);
+ assertEquals(1,selector.selectedKeys().size());
+ assertTrue(key.isValid());
+ assertTrue(key.isWritable());
+ assertFalse(key.isReadable());
+ assertEquals(SelectionKey.OP_WRITE,key.readyOps());
+ }
+
+}
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/nio/SelectChannelEndPointSslTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/nio/SelectChannelEndPointSslTest.java
new file mode 100644
index 00000000000..d6a6a46a06a
--- /dev/null
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/nio/SelectChannelEndPointSslTest.java
@@ -0,0 +1,187 @@
+package org.eclipse.jetty.io.nio;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.Socket;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import javax.net.ssl.SSLSocket;
+
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+
+public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
+{
+ static SslContextFactory __sslCtxFactory=new SslContextFactory();
+
+ @BeforeClass
+ public static void initSslEngine() throws Exception
+ {
+ File keystore = MavenTestingUtils.getTestResourceFile("keystore");
+ __sslCtxFactory.setKeyStorePath(keystore.getAbsolutePath());
+ __sslCtxFactory.setKeyStorePassword("storepwd");
+ __sslCtxFactory.setKeyManagerPassword("keypwd");
+ __sslCtxFactory.start();
+ }
+
+ @Override
+ protected Socket newClient() throws IOException
+ {
+ SSLSocket socket = __sslCtxFactory.newSslSocket();
+ socket.connect(_connector.socket().getLocalSocketAddress());
+ return socket;
+ }
+
+ @Override
+ protected AsyncConnection newConnection(SocketChannel channel, EndPoint endpoint)
+ {
+ SSLEngine engine = __sslCtxFactory.newSslEngine();
+ engine.setUseClientMode(false);
+ SslConnection connection = new SslConnection(engine,endpoint);
+
+ AsyncConnection delegate = super.newConnection(channel,connection.getSslEndPoint());
+ connection.getSslEndPoint().setConnection(delegate);
+ return connection;
+ }
+
+ @Test
+ @Override
+ public void testEcho() throws Exception
+ {
+ super.testEcho();
+ }
+
+
+ @Test
+ @Override
+ public void testShutdown() throws Exception
+ {
+ // SSL does not do half closes
+ }
+
+ @Test
+ public void testTcpClose() throws Exception
+ {
+
+ // This test replaces SSLSocket() with a very manual SSL client
+ // so we can close TCP underneath SSL.
+
+ SocketChannel client = SocketChannel.open(_connector.socket().getLocalSocketAddress());
+ client.socket().setSoTimeout(500);
+
+ SocketChannel server = _connector.accept();
+ server.configureBlocking(false);
+ _manager.register(server);
+
+ SSLEngine engine = __sslCtxFactory.newSslEngine();
+ engine.setUseClientMode(true);
+ engine.beginHandshake();
+
+ ByteBuffer appOut = ByteBuffer.allocate(engine.getSession().getApplicationBufferSize());
+ ByteBuffer sslOut = ByteBuffer.allocate(engine.getSession().getPacketBufferSize()*2);
+ ByteBuffer appIn = ByteBuffer.allocate(engine.getSession().getApplicationBufferSize());
+ ByteBuffer sslIn = ByteBuffer.allocate(engine.getSession().getPacketBufferSize()*2);
+
+ boolean debug=SslConnection.LOG.isDebugEnabled();
+
+ if (debug) System.err.println(engine.getHandshakeStatus());
+ int loop=20;
+ while (engine.getHandshakeStatus()!=HandshakeStatus.NOT_HANDSHAKING)
+ {
+ if (--loop==0)
+ throw new IllegalStateException();
+
+ if (engine.getHandshakeStatus()==HandshakeStatus.NEED_WRAP)
+ {
+ if (debug) System.err.printf("sslOut %d-%d-%d%n",sslOut.position(),sslOut.limit(),sslOut.capacity());
+ if (debug) System.err.printf("appOut %d-%d-%d%n",appOut.position(),appOut.limit(),appOut.capacity());
+ SSLEngineResult result =engine.wrap(appOut,sslOut);
+ if (debug) System.err.println(result);
+ sslOut.flip();
+ int flushed=client.write(sslOut);
+ if (debug) System.err.println("out="+flushed);
+ sslOut.clear();
+ }
+
+ if (engine.getHandshakeStatus()==HandshakeStatus.NEED_UNWRAP)
+ {
+ if (debug) System.err.printf("sslIn %d-%d-%d%n",sslIn.position(),sslIn.limit(),sslIn.capacity());
+ if (sslIn.position()==0)
+ {
+ int filled=client.read(sslIn);
+ if (debug) System.err.println("in="+filled);
+ }
+ sslIn.flip();
+ if (debug) System.err.printf("sslIn %d-%d-%d%n",sslIn.position(),sslIn.limit(),sslIn.capacity());
+ SSLEngineResult result =engine.unwrap(sslIn,appIn);
+ if (debug) System.err.println(result);
+ if (debug) System.err.printf("sslIn %d-%d-%d%n",sslIn.position(),sslIn.limit(),sslIn.capacity());
+ if (sslIn.hasRemaining())
+ sslIn.compact();
+ else
+ sslIn.clear();
+ if (debug) System.err.printf("sslIn %d-%d-%d%n",sslIn.position(),sslIn.limit(),sslIn.capacity());
+ }
+
+ if (engine.getHandshakeStatus()==HandshakeStatus.NEED_TASK)
+ {
+ Runnable task;
+ while ((task=engine.getDelegatedTask())!=null)
+ task.run();
+ if (debug) System.err.println(engine.getHandshakeStatus());
+ }
+ }
+
+ if (debug) System.err.println("\nSay Hello");
+
+ // write a message
+ appOut.put("HelloWorld".getBytes("UTF-8"));
+ appOut.flip();
+ SSLEngineResult result =engine.wrap(appOut,sslOut);
+ if (debug) System.err.println(result);
+ sslOut.flip();
+ int flushed=client.write(sslOut);
+ if (debug) System.err.println("out="+flushed);
+ sslOut.clear();
+ appOut.clear();
+
+ // read the response
+ int filled=client.read(sslIn);
+ if (debug) System.err.println("in="+filled);
+ sslIn.flip();
+ result =engine.unwrap(sslIn,appIn);
+ if (debug) System.err.println(result);
+ if (sslIn.hasRemaining())
+ sslIn.compact();
+ else
+ sslIn.clear();
+
+ appIn.flip();
+ String reply= new String(appIn.array(),appIn.arrayOffset(),appIn.remaining());
+ appIn.clear();
+
+ Assert.assertEquals("HelloWorld",reply);
+
+ SelectorManager.LOG.info("javax.net.ssl.SSLException: Inbound closed... is expected soon");
+ if (debug) System.err.println("\nSudden Death");
+ client.socket().shutdownOutput();
+
+ filled=client.read(sslIn);
+ Assert.assertEquals(-1,filled);
+ }
+
+ @Test
+ public void testStress() throws Exception
+ {
+ super.testStress();
+ }
+}
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/nio/SelectChannelEndPointTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/nio/SelectChannelEndPointTest.java
new file mode 100644
index 00000000000..768f872258e
--- /dev/null
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/nio/SelectChannelEndPointTest.java
@@ -0,0 +1,434 @@
+package org.eclipse.jetty.io.nio;
+
+import static org.hamcrest.Matchers.greaterThanOrEqualTo;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jetty.io.AbstractConnection;
+import org.eclipse.jetty.io.AsyncEndPoint;
+import org.eclipse.jetty.io.ConnectedEndPoint;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SelectChannelEndPointTest
+{
+ protected SelectChannelEndPoint _lastEndp;
+ protected ServerSocketChannel _connector;
+ protected QueuedThreadPool _threadPool = new QueuedThreadPool();
+ protected SelectorManager _manager = new SelectorManager()
+ {
+ @Override
+ public boolean dispatch(Runnable task)
+ {
+ return _threadPool.dispatch(task);
+ }
+
+ @Override
+ protected void endPointClosed(SelectChannelEndPoint endpoint)
+ {
+ }
+
+ @Override
+ protected void endPointOpened(SelectChannelEndPoint endpoint)
+ {
+ }
+
+ @Override
+ protected void endPointUpgraded(ConnectedEndPoint endpoint, org.eclipse.jetty.io.Connection oldConnection)
+ {
+ }
+
+ @Override
+ public AsyncConnection newConnection(SocketChannel channel, AsyncEndPoint endpoint, Object attachment)
+ {
+ return SelectChannelEndPointTest.this.newConnection(channel,endpoint);
+ }
+
+ @Override
+ protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key) throws IOException
+ {
+ SelectChannelEndPoint endp = new SelectChannelEndPoint(channel,selectSet,key,2000);
+ endp.setConnection(selectSet.getManager().newConnection(channel,endp, key.attachment()));
+ _lastEndp=endp;
+ return endp;
+ }
+ };
+
+ // Must be volatile or the test may fail spuriously
+ private volatile int _blockAt=0;
+
+ @Before
+ public void startManager() throws Exception
+ {
+ _connector = ServerSocketChannel.open();
+ _connector.socket().bind(null);
+ _threadPool.start();
+ _manager.start();
+ }
+
+ @After
+ public void stopManager() throws Exception
+ {
+ _manager.stop();
+ _threadPool.stop();
+ _connector.close();
+ }
+
+ protected Socket newClient() throws IOException
+ {
+ return new Socket(_connector.socket().getInetAddress(),_connector.socket().getLocalPort());
+ }
+
+ protected AsyncConnection newConnection(SocketChannel channel, EndPoint endpoint)
+ {
+ return new TestConnection(endpoint);
+ }
+
+ public class TestConnection extends AbstractConnection implements AsyncConnection
+ {
+ NIOBuffer _in = new IndirectNIOBuffer(32*1024);
+ NIOBuffer _out = new IndirectNIOBuffer(32*1024);
+
+ public TestConnection(EndPoint endp)
+ {
+ super(endp);
+ }
+
+ public org.eclipse.jetty.io.Connection handle() throws IOException
+ {
+ boolean progress=true;
+ while(progress)
+ {
+ progress=false;
+ _in.compact();
+ if (_in.space()>0 && _endp.fill(_in)>0)
+ progress=true;
+
+ while (_blockAt>0 && _in.length()>0 && _in.length()<_blockAt)
+ {
+ _endp.blockReadable(10000);
+ if (_in.space()>0 && _endp.fill(_in)>0)
+ progress=true;
+ }
+
+ if (_in.hasContent() && _in.skip(_out.put(_in))>0)
+ progress=true;
+
+ if (_out.hasContent() && _endp.flush(_out)>0)
+ progress=true;
+
+ _out.compact();
+
+ if (!_out.hasContent() && _endp.isInputShutdown())
+ _endp.shutdownOutput();
+ }
+ return this;
+ }
+
+ public boolean isIdle()
+ {
+ return false;
+ }
+
+ public boolean isSuspended()
+ {
+ return false;
+ }
+
+ public void onClose()
+ {
+ // System.err.println("onClose");
+ }
+
+ public void onInputShutdown() throws IOException
+ {
+ // System.err.println("onInputShutdown");
+ }
+
+ }
+
+ @Test
+ public void testEcho() throws Exception
+ {
+ Socket client = newClient();
+
+ client.setSoTimeout(500);
+
+ SocketChannel server = _connector.accept();
+ server.configureBlocking(false);
+
+ _manager.register(server);
+
+ // Write client to server
+ client.getOutputStream().write("HelloWorld".getBytes("UTF-8"));
+
+ // Verify echo server to client
+ for (char c : "HelloWorld".toCharArray())
+ {
+ int b = client.getInputStream().read();
+ assertTrue(b>0);
+ assertEquals(c,(char)b);
+ }
+
+ // wait for read timeout
+ long start=System.currentTimeMillis();
+ try
+ {
+ client.getInputStream().read();
+ Assert.fail();
+ }
+ catch(SocketTimeoutException e)
+ {
+ assertTrue(System.currentTimeMillis()-start>=400);
+ }
+
+ // write then shutdown
+ client.getOutputStream().write("Goodbye Cruel TLS".getBytes("UTF-8"));
+
+ // Verify echo server to client
+ for (char c : "Goodbye Cruel TLS".toCharArray())
+ {
+ int b = client.getInputStream().read();
+ assertTrue(b>0);
+ assertEquals(c,(char)b);
+ }
+ client.close();
+
+ int i=0;
+ while (server.isOpen())
+ {
+ assert(i++<10);
+ Thread.sleep(10);
+ }
+
+ }
+
+
+ @Test
+ public void testShutdown() throws Exception
+ {
+ Socket client = newClient();
+
+ client.setSoTimeout(500);
+
+ SocketChannel server = _connector.accept();
+ server.configureBlocking(false);
+
+ _manager.register(server);
+
+ // Write client to server
+ client.getOutputStream().write("HelloWorld".getBytes("UTF-8"));
+
+ // Verify echo server to client
+ for (char c : "HelloWorld".toCharArray())
+ {
+ int b = client.getInputStream().read();
+ assertTrue(b>0);
+ assertEquals(c,(char)b);
+ }
+
+ // wait for read timeout
+ long start=System.currentTimeMillis();
+ try
+ {
+ client.getInputStream().read();
+ Assert.fail();
+ }
+ catch(SocketTimeoutException e)
+ {
+ assertTrue(System.currentTimeMillis()-start>=400);
+ }
+
+ // write then shutdown
+ client.getOutputStream().write("Goodbye Cruel TLS".getBytes("UTF-8"));
+ client.shutdownOutput();
+
+
+ // Verify echo server to client
+ for (char c : "Goodbye Cruel TLS".toCharArray())
+ {
+ int b = client.getInputStream().read();
+ assertTrue(b>0);
+ assertEquals(c,(char)b);
+ }
+
+ // Read close
+ assertEquals(-1,client.getInputStream().read());
+
+ }
+
+
+
+ @Test
+ public void testBlockIn() throws Exception
+ {
+ Socket client = newClient();
+
+ SocketChannel server = _connector.accept();
+ server.configureBlocking(false);
+
+ _manager.register(server);
+
+ OutputStream clientOutputStream = client.getOutputStream();
+ InputStream clientInputStream = client.getInputStream();
+
+ int specifiedTimeout = 400;
+ client.setSoTimeout(specifiedTimeout);
+
+ // Write 8 and cause block for 10
+ _blockAt=10;
+ clientOutputStream.write("12345678".getBytes("UTF-8"));
+ clientOutputStream.flush();
+
+ Thread.sleep(2 * specifiedTimeout);
+
+ // No echo as blocking for 10
+ long start=System.currentTimeMillis();
+ try
+ {
+ int b = clientInputStream.read();
+ Assert.fail("Should have timed out waiting for a response, but read "+b);
+ }
+ catch(SocketTimeoutException e)
+ {
+ int elapsed = Long.valueOf(System.currentTimeMillis() - start).intValue();
+ System.err.println("blocked for " + elapsed+ "ms");
+ Assert.assertThat("Expected timeout", elapsed, greaterThanOrEqualTo(3*specifiedTimeout/4));
+ }
+
+ // write remaining characters
+ clientOutputStream.write("90ABCDEF".getBytes("UTF-8"));
+ clientOutputStream.flush();
+
+ // Verify echo server to client
+ for (char c : "1234567890ABCDEF".toCharArray())
+ {
+ int b = clientInputStream.read();
+ assertTrue(b>0);
+ assertEquals(c,(char)b);
+ }
+ }
+
+ @Test
+ public void testIdle() throws Exception
+ {
+ Socket client = newClient();
+
+ client.setSoTimeout(3000);
+
+ SocketChannel server = _connector.accept();
+ server.configureBlocking(false);
+
+ _manager.register(server);
+
+ // Write client to server
+ client.getOutputStream().write("HelloWorld".getBytes("UTF-8"));
+
+ // Verify echo server to client
+ for (char c : "HelloWorld".toCharArray())
+ {
+ int b = client.getInputStream().read();
+ assertTrue(b>0);
+ assertEquals(c,(char)b);
+ }
+
+ // Set Max idle
+ _lastEndp.setMaxIdleTime(500);
+
+ // read until idle shutdown received
+ long start=System.currentTimeMillis();
+ int b=client.getInputStream().read();
+ assertEquals(-1,b);
+ long idle=System.currentTimeMillis()-start;
+ assertTrue(idle>400);
+ assertTrue(idle<2000);
+
+ // But endpoint is still open.
+ assertTrue(_lastEndp.isOpen());
+
+
+ // Wait for another idle callback
+ Thread.sleep(2000);
+ // endpoint is closed.
+
+ assertFalse(_lastEndp.isOpen());
+
+ }
+
+
+
+ @Test
+ public void testStress() throws Exception
+ {
+ Socket client = newClient();
+ client.setSoTimeout(30000);
+
+ SocketChannel server = _connector.accept();
+ server.configureBlocking(false);
+
+ _manager.register(server);
+ int writes = 100000;
+
+ final byte[] bytes="HelloWorld".getBytes("UTF-8");
+ final CountDownLatch latch = new CountDownLatch(writes);
+ final InputStream in = new BufferedInputStream(client.getInputStream());
+ final long start = System.currentTimeMillis();
+ client.getOutputStream().write(bytes);
+ client.getOutputStream().flush();
+
+ new Thread()
+ {
+ public void run()
+ {
+ try
+ {
+ while (latch.getCount()>0)
+ {
+ // Verify echo server to client
+ for (byte b0 : bytes)
+ {
+ int b = in.read();
+ assertTrue(b>0);
+ assertEquals(0xff&b0,b);
+ }
+ latch.countDown();
+ }
+ }
+ catch(Throwable e)
+ {
+ System.err.println("latch="+latch.getCount());
+ System.err.println("time="+(System.currentTimeMillis()-start));
+ e.printStackTrace();
+ }
+ }
+ }.start();
+
+
+ // Write client to server
+ for (int i=1;i
org.eclipse.jetty
jetty-project
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
4.0.0
jetty-jaspi
diff --git a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/callback/CredentialValidationCallback.java b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/callback/CredentialValidationCallback.java
index e22aaa32e60..bf2c82c8c33 100644
--- a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/callback/CredentialValidationCallback.java
+++ b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/callback/CredentialValidationCallback.java
@@ -17,7 +17,7 @@ package org.eclipse.jetty.security.jaspi.callback;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
-import org.eclipse.jetty.http.security.Credential;
+import org.eclipse.jetty.util.security.Credential;
/**
* CredentialValidationCallback
diff --git a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/BaseAuthModule.java b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/BaseAuthModule.java
index 7099661a4da..4eb1ad6e256 100644
--- a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/BaseAuthModule.java
+++ b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/BaseAuthModule.java
@@ -32,8 +32,8 @@ import javax.security.auth.message.module.ServerAuthModule;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.http.security.Credential;
-import org.eclipse.jetty.http.security.Password;
+import org.eclipse.jetty.util.security.Credential;
+import org.eclipse.jetty.util.security.Password;
import org.eclipse.jetty.security.authentication.LoginCallbackImpl;
import org.eclipse.jetty.security.jaspi.JaspiMessageInfo;
import org.eclipse.jetty.security.jaspi.callback.CredentialValidationCallback;
diff --git a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/BasicAuthModule.java b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/BasicAuthModule.java
index d97c5df7152..50032d46b26 100644
--- a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/BasicAuthModule.java
+++ b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/BasicAuthModule.java
@@ -27,7 +27,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpHeaders;
-import org.eclipse.jetty.http.security.Constraint;
+import org.eclipse.jetty.util.security.Constraint;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
diff --git a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/ClientCertAuthModule.java b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/ClientCertAuthModule.java
index 94300672200..5e637c4dedf 100644
--- a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/ClientCertAuthModule.java
+++ b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/ClientCertAuthModule.java
@@ -25,8 +25,8 @@ import javax.security.auth.message.MessageInfo;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.http.security.Constraint;
-import org.eclipse.jetty.http.security.Password;
+import org.eclipse.jetty.util.security.Constraint;
+import org.eclipse.jetty.util.security.Password;
import org.eclipse.jetty.util.B64Code;
/**
diff --git a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/DigestAuthModule.java b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/DigestAuthModule.java
index 5702ee4892b..847b01b1c63 100644
--- a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/DigestAuthModule.java
+++ b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/DigestAuthModule.java
@@ -28,8 +28,8 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpHeaders;
-import org.eclipse.jetty.http.security.Constraint;
-import org.eclipse.jetty.http.security.Credential;
+import org.eclipse.jetty.util.security.Constraint;
+import org.eclipse.jetty.util.security.Credential;
import org.eclipse.jetty.util.B64Code;
import org.eclipse.jetty.util.QuotedStringTokenizer;
import org.eclipse.jetty.util.StringUtil;
diff --git a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/FormAuthModule.java b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/FormAuthModule.java
index 72fc9b7f55f..be390555742 100644
--- a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/FormAuthModule.java
+++ b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/FormAuthModule.java
@@ -33,8 +33,8 @@ import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
-import org.eclipse.jetty.http.security.Constraint;
-import org.eclipse.jetty.http.security.Password;
+import org.eclipse.jetty.util.security.Constraint;
+import org.eclipse.jetty.util.security.Password;
import org.eclipse.jetty.security.CrossContextPsuedoSession;
import org.eclipse.jetty.security.authentication.DeferredAuthentication;
import org.eclipse.jetty.security.authentication.LoginCallbackImpl;
diff --git a/jetty-jmx/pom.xml b/jetty-jmx/pom.xml
index 3b3f0b177b1..4b9a0dc2a9d 100644
--- a/jetty-jmx/pom.xml
+++ b/jetty-jmx/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty
jetty-project
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
4.0.0
jetty-jmx
diff --git a/jetty-jmx/src/main/config/etc/jetty-jmx.xml b/jetty-jmx/src/main/config/etc/jetty-jmx.xml
index bdce9d42981..b8c38a201d6 100644
--- a/jetty-jmx/src/main/config/etc/jetty-jmx.xml
+++ b/jetty-jmx/src/main/config/etc/jetty-jmx.xml
@@ -9,6 +9,17 @@
+
+
+
+
+
+
diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java
index 5371c8b60dc..d784442d9f4 100644
--- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java
+++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java
@@ -22,11 +22,11 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
+
import javax.management.MBeanServer;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
-import org.eclipse.jetty.util.MultiMap;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.component.AggregateLifeCycle;
import org.eclipse.jetty.util.component.Container;
@@ -41,7 +41,7 @@ import org.eclipse.jetty.util.thread.ShutdownThread;
*/
public class MBeanContainer extends AbstractLifeCycle implements Container.Listener, Dumpable
{
- private final static Logger __log = Log.getLogger(MBeanContainer.class.getName());
+ private final static Logger LOG = Log.getLogger(MBeanContainer.class.getName());
private final MBeanServer _server;
private final WeakHashMap _beans = new WeakHashMap();
@@ -93,7 +93,7 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
}
catch (Exception e)
{
- __log.ignore(e);
+ LOG.ignore(e);
}
}
@@ -134,7 +134,7 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
*/
public synchronized void add(Relationship relationship)
{
- __log.debug("add {}",relationship);
+ LOG.debug("add {}",relationship);
ObjectName parent = _beans.get(relationship.getParent());
if (parent == null)
{
@@ -168,7 +168,7 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
*/
public synchronized void remove(Relationship relationship)
{
- __log.debug("remove {}",relationship);
+ LOG.debug("remove {}",relationship);
ObjectName parent = _beans.get(relationship.getParent());
ObjectName child = _beans.get(relationship.getChild());
@@ -194,7 +194,7 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
*/
public synchronized void removeBean(Object obj)
{
- __log.debug("removeBean {}",obj);
+ LOG.debug("removeBean {}",obj);
ObjectName bean = _beans.remove(obj);
if (bean != null)
@@ -202,7 +202,7 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
List beanRelations= _relations.remove(bean);
if (beanRelations != null)
{
- __log.debug("Unregister {}", beanRelations);
+ LOG.debug("Unregister {}", beanRelations);
List> removeList = new ArrayList(beanRelations);
for (Object r : removeList)
{
@@ -214,15 +214,15 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
try
{
_server.unregisterMBean(bean);
- __log.debug("Unregistered {}", bean);
+ LOG.debug("Unregistered {}", bean);
}
catch (javax.management.InstanceNotFoundException e)
{
- __log.ignore(e);
+ LOG.ignore(e);
}
catch (Exception e)
{
- __log.warn(e);
+ LOG.warn(e);
}
}
}
@@ -234,7 +234,7 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
*/
public synchronized void addBean(Object obj)
{
- __log.debug("addBean {}",obj);
+ LOG.debug("addBean {}",obj);
try
{
if (obj == null || _beans.containsKey(obj))
@@ -298,13 +298,13 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
}
ObjectInstance oinstance = _server.registerMBean(mbean, oname);
- __log.debug("Registered {}", oinstance.getObjectName());
+ LOG.debug("Registered {}", oinstance.getObjectName());
_beans.put(obj, oinstance.getObjectName());
}
catch (Exception e)
{
- __log.warn("bean: " + obj, e);
+ LOG.warn("bean: " + obj, e);
}
}
diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ObjectMBean.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ObjectMBean.java
index 08797aa7264..8b309d5ce67 100644
--- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ObjectMBean.java
+++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ObjectMBean.java
@@ -28,8 +28,6 @@ import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import javax.management.Attribute;
import javax.management.AttributeList;
diff --git a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ConnectorServerTest.java b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ConnectorServerTest.java
index 10ed7d822ac..1818567d25c 100644
--- a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ConnectorServerTest.java
+++ b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ConnectorServerTest.java
@@ -16,8 +16,6 @@
package org.eclipse.jetty.jmx;
-import java.net.MalformedURLException;
-
import javax.management.remote.JMXServiceURL;
import org.junit.Test;
diff --git a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanTest.java b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanTest.java
index 4b1d09f79d8..ebb5f63defb 100644
--- a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanTest.java
+++ b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanTest.java
@@ -13,10 +13,11 @@
package org.eclipse.jetty.jmx;
-import com.acme.Derived;
+import static org.junit.Assert.assertTrue;
+
import org.junit.Test;
-import static org.junit.Assert.assertTrue;
+import com.acme.Derived;
public class ObjectMBeanTest
{
diff --git a/jetty-jndi/pom.xml b/jetty-jndi/pom.xml
index e9b89cdb92c..5eaf6fef291 100644
--- a/jetty-jndi/pom.xml
+++ b/jetty-jndi/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty
jetty-project
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
4.0.0
jetty-jndi
diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/MailSessionReference.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/MailSessionReference.java
index e6ff384f548..210b52d2a0d 100644
--- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/MailSessionReference.java
+++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/MailSessionReference.java
@@ -30,7 +30,7 @@ import javax.naming.Reference;
import javax.naming.StringRefAddr;
import javax.naming.spi.ObjectFactory;
-import org.eclipse.jetty.http.security.Password;
+import org.eclipse.jetty.util.security.Password;
/**
* MailSessionReference
diff --git a/jetty-jsp-2.1/pom.xml b/jetty-jsp-2.1/pom.xml
deleted file mode 100644
index 9f4a419d79f..00000000000
--- a/jetty-jsp-2.1/pom.xml
+++ /dev/null
@@ -1,129 +0,0 @@
-
-
- org.eclipse.jetty
- jetty-project
- 7.5.4-SNAPSHOT
-
- 4.0.0
- jetty-jsp-2.1
- Jetty :: Jetty JSP Additions
- Additions to Jasper implementation from Glassfish
-
- ${project.groupId}.jsp-2.1
-
-
-
-
- org.apache.maven.plugins
- maven-dependency-plugin
-
-
- unpack
- generate-sources
-
- unpack
-
-
-
-
- org.glassfish.web
- jsp-impl
- 2.1.3-b10
- jar
- sources
- true
- target/generated-sources
- **/JDTJavaCompiler.java
-
-
-
-
-
-
-
-
- org.codehaus.mojo
- build-helper-maven-plugin
- 1.7
-
-
- add-source
- generate-sources
-
- add-source
-
-
-
- target/generated-sources
-
-
-
-
-
-
-
- org.apache.felix
- maven-bundle-plugin
- true
-
-
-
- manifest
-
-
-
-
-
-
- org.apache.jasper;version="[2.1,3)";glassfish="split",
- *
-
- org.apache.jasper*;version="${parsedVersion.osgiVersion}"
- org.apache.jasper.glassfish
- <_nouses>true
-
-
-
-
-
- org.apache.maven.plugins
- maven-jar-plugin
-
-
- ${project.build.outputDirectory}/META-INF/MANIFEST.MF
-
-
-
-
- org.codehaus.mojo
- findbugs-maven-plugin
-
- org.eclipse.jetty.jsp.*
-
-
-
-
-
-
- org.glassfish.web
- jsp-impl
- 2.1.3-b10
-
-
- provided
-
-
- javax.servlet
- servlet-api
- provided
-
-
- org.eclipse.jdt.core.compiler
- ecj
- 3.7
- provided
-
-
-
diff --git a/jetty-monitor/pom.xml b/jetty-monitor/pom.xml
index 8298960557d..bfff477df54 100644
--- a/jetty-monitor/pom.xml
+++ b/jetty-monitor/pom.xml
@@ -19,7 +19,7 @@
org.eclipse.jetty
jetty-project
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
4.0.0
jetty-monitor
diff --git a/jetty-nested/pom.xml b/jetty-nested/pom.xml
index 9a625784fcb..40da79b3cfe 100644
--- a/jetty-nested/pom.xml
+++ b/jetty-nested/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.jetty
jetty-project
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
jetty-nested
Jetty :: Nested
diff --git a/jetty-nested/src/main/java/org/eclipse/jetty/nested/NestedConnection.java b/jetty-nested/src/main/java/org/eclipse/jetty/nested/NestedConnection.java
index b377fc6f0bc..0d98785a526 100644
--- a/jetty-nested/src/main/java/org/eclipse/jetty/nested/NestedConnection.java
+++ b/jetty-nested/src/main/java/org/eclipse/jetty/nested/NestedConnection.java
@@ -15,7 +15,6 @@ package org.eclipse.jetty.nested;
import java.io.IOException;
import java.util.Enumeration;
-import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
@@ -24,14 +23,11 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.io.Connection;
-import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.DispatcherType;
-import org.eclipse.jetty.server.HttpConnection;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.util.log.Log;
-public class NestedConnection extends HttpConnection
+public class NestedConnection extends AbstractHttpConnection
{
protected NestedConnection(final NestedConnector connector, final NestedEndPoint endp, final HttpServletRequest outerRequest, HttpServletResponse outerResponse,String nestedIn)
throws IOException
diff --git a/jetty-nested/src/main/java/org/eclipse/jetty/nested/NestedGenerator.java b/jetty-nested/src/main/java/org/eclipse/jetty/nested/NestedGenerator.java
index b9c970207e8..47d74c3d1ee 100644
--- a/jetty-nested/src/main/java/org/eclipse/jetty/nested/NestedGenerator.java
+++ b/jetty-nested/src/main/java/org/eclipse/jetty/nested/NestedGenerator.java
@@ -252,7 +252,7 @@ public class NestedGenerator extends AbstractGenerator
/* ------------------------------------------------------------ */
@Override
- public long flushBuffer() throws IOException
+ public int flushBuffer() throws IOException
{
if (_state == STATE_HEADER)
throw new IllegalStateException("State==HEADER");
diff --git a/jetty-nested/src/main/java/org/eclipse/jetty/nested/NestedParser.java b/jetty-nested/src/main/java/org/eclipse/jetty/nested/NestedParser.java
index 1b6830ffbd4..9bac8831296 100644
--- a/jetty-nested/src/main/java/org/eclipse/jetty/nested/NestedParser.java
+++ b/jetty-nested/src/main/java/org/eclipse/jetty/nested/NestedParser.java
@@ -38,9 +38,9 @@ public class NestedParser implements Parser
return false;
}
- public int parseAvailable() throws IOException
+ public boolean parseAvailable() throws IOException
{
- return 0;
+ return false;
}
public boolean isMoreInBuffer() throws IOException
@@ -53,4 +53,13 @@ public class NestedParser implements Parser
return false;
}
+ public boolean isPersistent()
+ {
+ return false;
+ }
+
+ public void setPersistent(boolean persistent)
+ {
+ }
+
}
diff --git a/jetty-nosql/pom.xml b/jetty-nosql/pom.xml
index 7660293e01b..75b77f019a9 100644
--- a/jetty-nosql/pom.xml
+++ b/jetty-nosql/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty
jetty-project
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
4.0.0
jetty-nosql
diff --git a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml
index 70d3b2c02e1..76e530cde78 100644
--- a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml
+++ b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty.osgi
jetty-osgi-project
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
../pom.xml
4.0.0
diff --git a/jetty-osgi/jetty-osgi-boot-logback/pom.xml b/jetty-osgi/jetty-osgi-boot-logback/pom.xml
index be3565e4f5b..595e77a4b24 100644
--- a/jetty-osgi/jetty-osgi-boot-logback/pom.xml
+++ b/jetty-osgi/jetty-osgi-boot-logback/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty.osgi
jetty-osgi-project
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
../pom.xml
4.0.0
diff --git a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml
index 69f1d4f9178..a0463cc5643 100644
--- a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml
+++ b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty.osgi
jetty-osgi-project
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
../pom.xml
4.0.0
diff --git a/jetty-osgi/jetty-osgi-boot/pom.xml b/jetty-osgi/jetty-osgi-boot/pom.xml
index b063f746195..87a7087125d 100644
--- a/jetty-osgi/jetty-osgi-boot/pom.xml
+++ b/jetty-osgi/jetty-osgi-boot/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty.osgi
jetty-osgi-project
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
../pom.xml
4.0.0
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java
index bb89bfe4889..21d0d6adb7d 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java
@@ -271,7 +271,8 @@ public class ServerInstanceWrapper {
try
{
// Execute a Jetty configuration file
- is = jettyConfiguration.openStream();
+ Resource r = Resource.newResource(jettyConfiguration);
+ is = r.getInputStream();
XmlConfiguration config = new XmlConfiguration(is);
config.getIdMap().putAll(id_map);
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java
index 27068cb1167..ea8fc5192b9 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleDeployerHelper.java
@@ -376,7 +376,8 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
URL contextURL = contributor.getEntry(contextFileRelativePath);
if (contextURL != null)
{
- return registerContext(contributor,contextFileRelativePath,contextURL.openStream(),extraClasspath,overrideBundleInstallLocation,requireTldBundle,handler);
+ Resource r = Resource.newResource(contextURL);
+ return registerContext(contributor,contextFileRelativePath,r.getInputStream(),extraClasspath,overrideBundleInstallLocation,requireTldBundle,handler);
}
throw new IllegalArgumentException("Could not find the context " + "file " + contextFileRelativePath + " for the bundle "
+ contributor.getSymbolicName() + (overrideBundleInstallLocation != null?" using the install location " + overrideBundleInstallLocation:""));
diff --git a/jetty-osgi/jetty-osgi-equinoxtools/pom.xml b/jetty-osgi/jetty-osgi-equinoxtools/pom.xml
index 1c0f1e535a9..fbb16968697 100644
--- a/jetty-osgi/jetty-osgi-equinoxtools/pom.xml
+++ b/jetty-osgi/jetty-osgi-equinoxtools/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty.osgi
jetty-osgi-project
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
../pom.xml
4.0.0
diff --git a/jetty-osgi/jetty-osgi-httpservice/pom.xml b/jetty-osgi/jetty-osgi-httpservice/pom.xml
index 88b815d322b..e389254295d 100644
--- a/jetty-osgi/jetty-osgi-httpservice/pom.xml
+++ b/jetty-osgi/jetty-osgi-httpservice/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty.osgi
jetty-osgi-project
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
../pom.xml
4.0.0
diff --git a/jetty-osgi/pom.xml b/jetty-osgi/pom.xml
index e06101a6774..ae30fdd313e 100644
--- a/jetty-osgi/pom.xml
+++ b/jetty-osgi/pom.xml
@@ -3,7 +3,7 @@
org.eclipse.jetty
jetty-project
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
../pom.xml
org.eclipse.jetty.osgi
diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml
index c4b1a3e9888..f0ae38a1230 100644
--- a/jetty-osgi/test-jetty-osgi/pom.xml
+++ b/jetty-osgi/test-jetty-osgi/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty.osgi
jetty-osgi-project
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
../pom.xml
4.0.0
diff --git a/jetty-overlay-deployer/pom.xml b/jetty-overlay-deployer/pom.xml
index 94f302eb353..75b8349308e 100644
--- a/jetty-overlay-deployer/pom.xml
+++ b/jetty-overlay-deployer/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty
jetty-project
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
4.0.0
jetty-overlay-deployer
diff --git a/jetty-plus/pom.xml b/jetty-plus/pom.xml
index 145dd57640e..391eb9691c7 100644
--- a/jetty-plus/pom.xml
+++ b/jetty-plus/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty
jetty-project
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
4.0.0
jetty-plus
diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/callback/DefaultCallbackHandler.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/callback/DefaultCallbackHandler.java
index 35ed91e5d07..bf679cdc9b2 100644
--- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/callback/DefaultCallbackHandler.java
+++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/callback/DefaultCallbackHandler.java
@@ -21,7 +21,7 @@ import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
-import org.eclipse.jetty.http.security.Password;
+import org.eclipse.jetty.util.security.Password;
import org.eclipse.jetty.server.Request;
diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/AbstractDatabaseLoginModule.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/AbstractDatabaseLoginModule.java
index 1747463e850..77af2d1cce6 100644
--- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/AbstractDatabaseLoginModule.java
+++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/AbstractDatabaseLoginModule.java
@@ -24,7 +24,7 @@ import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
-import org.eclipse.jetty.http.security.Credential;
+import org.eclipse.jetty.util.security.Credential;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/LdapLoginModule.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/LdapLoginModule.java
index 5b1e7e92c39..5f7401724af 100644
--- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/LdapLoginModule.java
+++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/LdapLoginModule.java
@@ -35,7 +35,7 @@ import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginException;
-import org.eclipse.jetty.http.security.Credential;
+import org.eclipse.jetty.util.security.Credential;
import org.eclipse.jetty.plus.jaas.callback.ObjectCallback;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/PropertyFileLoginModule.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/PropertyFileLoginModule.java
index 1e36eb5f5fc..8258d68aa72 100644
--- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/PropertyFileLoginModule.java
+++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/PropertyFileLoginModule.java
@@ -24,7 +24,7 @@ import java.util.Set;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
-import org.eclipse.jetty.http.security.Credential;
+import org.eclipse.jetty.util.security.Credential;
import org.eclipse.jetty.security.PropertyUserStore;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.util.log.Log;
@@ -123,4 +123,4 @@ public class PropertyFileLoginModule extends AbstractLoginModule
return new UserInfo(userName, credential, roles);
}
-}
\ No newline at end of file
+}
diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/UserInfo.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/UserInfo.java
index 01e9e6c8355..861acb20fef 100644
--- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/UserInfo.java
+++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/spi/UserInfo.java
@@ -16,7 +16,7 @@ package org.eclipse.jetty.plus.jaas.spi;
import java.util.ArrayList;
import java.util.List;
-import org.eclipse.jetty.http.security.Credential;
+import org.eclipse.jetty.util.security.Credential;
/**
* UserInfo
diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/security/DataSourceLoginService.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/security/DataSourceLoginService.java
index 48a38bebf42..fc269ccfab2 100644
--- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/security/DataSourceLoginService.java
+++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/security/DataSourceLoginService.java
@@ -27,7 +27,6 @@ import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import javax.sql.DataSource;
-import org.eclipse.jetty.http.security.Password;
import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
import org.eclipse.jetty.security.IdentityService;
import org.eclipse.jetty.security.MappedLoginService;
@@ -35,6 +34,7 @@ import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.security.Password;
/**
diff --git a/jetty-policy/pom.xml b/jetty-policy/pom.xml
index fc4e8a7e8b8..64548024678 100644
--- a/jetty-policy/pom.xml
+++ b/jetty-policy/pom.xml
@@ -3,7 +3,7 @@
org.eclipse.jetty
jetty-project
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
org.eclipse.jetty
jetty-policy
diff --git a/jetty-policy/src/main/java/org/eclipse/jetty/policy/entry/KeystoreEntry.java b/jetty-policy/src/main/java/org/eclipse/jetty/policy/entry/KeystoreEntry.java
index a89b422bea4..b8d7a719ed4 100644
--- a/jetty-policy/src/main/java/org/eclipse/jetty/policy/entry/KeystoreEntry.java
+++ b/jetty-policy/src/main/java/org/eclipse/jetty/policy/entry/KeystoreEntry.java
@@ -21,6 +21,7 @@ import java.security.KeyStore;
import org.eclipse.jetty.policy.PolicyContext;
import org.eclipse.jetty.policy.PolicyException;
+import org.eclipse.jetty.util.resource.Resource;
public class KeystoreEntry extends AbstractEntry
{
@@ -49,7 +50,8 @@ public class KeystoreEntry extends AbstractEntry
keystore = KeyStore.getInstance( type );
URL keyStoreLocation = new URL ( url );
- InputStream istream = keyStoreLocation.openStream();
+ Resource r = Resource.newResource(keyStoreLocation);
+ InputStream istream = r.getInputStream();
keystore.load( istream, null );
diff --git a/jetty-rewrite/pom.xml b/jetty-rewrite/pom.xml
index 5a1f026adc1..cdfe6d1c5b0 100644
--- a/jetty-rewrite/pom.xml
+++ b/jetty-rewrite/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty
jetty-project
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
4.0.0
jetty-rewrite
diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ProxyRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ProxyRule.java
index 99c6877e52b..8e63b8c5a74 100644
--- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ProxyRule.java
+++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ProxyRule.java
@@ -280,7 +280,7 @@ public class ProxyRule extends PatternRule
if (debug != 0)
{
- _log.debug(debug + " " + request.getMethod() + " " + url + " " + request.getProtocol());
+ _log.debug("{} {} {} {}", debug ,request.getMethod(), url, request.getProtocol());
}
boolean hasContent = createHeaders(request,debug,exchange);
@@ -393,7 +393,7 @@ public class ProxyRule extends PatternRule
if (val != null)
{
if (debug != 0)
- _log.debug(debug + " " + hdr + ": " + val);
+ _log.debug("{} {} {}",debug,hdr,val);
exchange.setRequestHeader(hdr,val);
}
@@ -483,5 +483,15 @@ public class ProxyRule extends PatternRule
{
_connectorType = connectorType;
}
+
+ public String getHostHeader()
+ {
+ return _hostHeader;
+ }
+
+ public void setHostHeader(String hostHeader)
+ {
+ _hostHeader = hostHeader;
+ }
}
diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java
index 201d4fadab1..0321859b27b 100644
--- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java
+++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java
@@ -18,8 +18,7 @@ import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.http.PathMap;
-import org.eclipse.jetty.server.HttpConnection;
+import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.LazyList;
import org.eclipse.jetty.util.log.Log;
@@ -224,7 +223,7 @@ public class RuleContainer extends Rule
if (rule.isHandling())
{
LOG.debug("handling {}",rule);
- (request instanceof Request?(Request)request:HttpConnection.getCurrentConnection().getRequest()).setHandled(true);
+ (request instanceof Request?(Request)request:AbstractHttpConnection.getCurrentConnection().getRequest()).setHandled(true);
}
if (rule.isTerminating())
diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/AbstractRuleTestCase.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/AbstractRuleTestCase.java
index 955391dbe52..16575c4dfca 100644
--- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/AbstractRuleTestCase.java
+++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/AbstractRuleTestCase.java
@@ -15,7 +15,7 @@ package org.eclipse.jetty.rewrite.handler;
import org.eclipse.jetty.io.bio.StringEndPoint;
import org.eclipse.jetty.server.BlockingHttpConnection;
import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.HttpConnection;
+import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
@@ -27,7 +27,7 @@ public abstract class AbstractRuleTestCase
protected Server _server = new Server();
protected LocalConnector _connector;
protected StringEndPoint _endpoint = new StringEndPoint();
- protected HttpConnection _connection;
+ protected AbstractHttpConnection _connection;
protected Request _request;
protected Response _response;
protected boolean _isSecure = false;
diff --git a/jetty-rewrite/src/test/resources/org.mortbay.jetty.rewrite.handler/jetty-rewrite.xml b/jetty-rewrite/src/test/resources/org.mortbay.jetty.rewrite.handler/jetty-rewrite.xml
index 83f86b6d3e8..e97f217ff65 100644
--- a/jetty-rewrite/src/test/resources/org.mortbay.jetty.rewrite.handler/jetty-rewrite.xml
+++ b/jetty-rewrite/src/test/resources/org.mortbay.jetty.rewrite.handler/jetty-rewrite.xml
@@ -1,5 +1,5 @@
-
+
@@ -85,7 +85,7 @@
-
-
+
/*
/test
diff --git a/jetty-security/pom.xml b/jetty-security/pom.xml
index f08e4e768a2..397991f6299 100644
--- a/jetty-security/pom.xml
+++ b/jetty-security/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty
jetty-project
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
4.0.0
jetty-security
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java
index 7d65c482484..0f255300c8b 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java
@@ -20,9 +20,8 @@ import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.eclipse.jetty.server.Authentication;
-import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.Authentication.User;
-import org.eclipse.jetty.server.SessionManager;
+import org.eclipse.jetty.server.Server;
/**
* Authenticator Interface
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintMapping.java b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintMapping.java
index 378ff14d575..13361cf1e46 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintMapping.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintMapping.java
@@ -13,7 +13,7 @@
package org.eclipse.jetty.security;
-import org.eclipse.jetty.http.security.Constraint;
+import org.eclipse.jetty.util.security.Constraint;
public class ConstraintMapping
{
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java
index f8d92e8d279..44280872b43 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java
@@ -25,14 +25,14 @@ import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import org.eclipse.jetty.http.PathMap;
-import org.eclipse.jetty.http.security.Constraint;
+import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.util.StringMap;
import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.security.Constraint;
/* ------------------------------------------------------------ */
/**
@@ -351,7 +351,7 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
{
return true;
}
- HttpConnection connection = HttpConnection.getCurrentConnection();
+ AbstractHttpConnection connection = AbstractHttpConnection.getCurrentConnection();
Connector connector = connection.getConnector();
if (dataConstraint == UserDataConstraint.Integral)
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java b/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java
index 0016be50b41..6c243a3a873 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java
@@ -15,7 +15,6 @@ package org.eclipse.jetty.security;
import javax.servlet.ServletContext;
-import org.eclipse.jetty.http.security.Constraint;
import org.eclipse.jetty.security.Authenticator.AuthConfiguration;
import org.eclipse.jetty.security.authentication.BasicAuthenticator;
import org.eclipse.jetty.security.authentication.ClientCertAuthenticator;
@@ -23,6 +22,7 @@ import org.eclipse.jetty.security.authentication.DigestAuthenticator;
import org.eclipse.jetty.security.authentication.FormAuthenticator;
import org.eclipse.jetty.security.authentication.SpnegoAuthenticator;
import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.security.Constraint;
/* ------------------------------------------------------------ */
/**
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java
index 472da9c6654..2b2b7462761 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java
@@ -17,9 +17,6 @@ import java.security.Principal;
import javax.security.auth.Subject;
-import org.eclipse.jetty.http.security.Credential;
-import org.eclipse.jetty.security.MappedLoginService.KnownUser;
-import org.eclipse.jetty.security.MappedLoginService.RolePrincipal;
import org.eclipse.jetty.server.UserIdentity;
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultUserIdentity.java b/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultUserIdentity.java
index cf94075de0f..e9d2b9a7d37 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultUserIdentity.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultUserIdentity.java
@@ -13,7 +13,6 @@
package org.eclipse.jetty.security;
-import java.io.Serializable;
import java.security.Principal;
import javax.security.auth.Subject;
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java
index 12b51f51502..34f7a5cedef 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java
@@ -15,13 +15,13 @@ package org.eclipse.jetty.security;
import java.io.IOException;
-import org.eclipse.jetty.http.security.Credential;
import org.eclipse.jetty.security.PropertyUserStore.UserListener;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.util.Scanner;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.util.security.Credential;
/* ------------------------------------------------------------ */
/**
@@ -135,9 +135,8 @@ public class HashLoginService extends MappedLoginService implements UserListener
if (_propertyUserStore == null)
{
if(LOG.isDebugEnabled())
- {
LOG.debug("doStart: Starting new PropertyUserStore. PropertiesFile: " + _config + " refreshInterval: " + _refreshInterval);
- }
+
_propertyUserStore = new PropertyUserStore();
_propertyUserStore.setRefreshInterval(_refreshInterval);
_propertyUserStore.setConfig(_config);
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java
index 216ae818d9b..e05a000b2e0 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java
@@ -14,9 +14,9 @@
package org.eclipse.jetty.security;
import java.security.Principal;
+
import javax.security.auth.Subject;
-import org.eclipse.jetty.http.security.Credential;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.UserIdentity;
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java
index 03a4786efbb..44e7ef078e1 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java
@@ -23,12 +23,12 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
-import org.eclipse.jetty.http.security.Credential;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.util.security.Credential;
/* ------------------------------------------------------------ */
/**
@@ -137,7 +137,7 @@ public class JDBCLoginService extends MappedLoginService
|| _password == null
|| _cacheTime < 0)
{
- if (LOG.isDebugEnabled()) LOG.debug("UserRealm " + getName() + " has not been properly configured");
+ LOG.warn("UserRealm " + getName() + " has not been properly configured");
}
_cacheTime *= 1000;
_lastHashPurge = 0;
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/MappedLoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/MappedLoginService.java
index 8808be26dae..5ca896fb154 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/MappedLoginService.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/MappedLoginService.java
@@ -23,11 +23,11 @@ import java.util.concurrent.ConcurrentMap;
import javax.security.auth.Subject;
-import org.eclipse.jetty.http.security.Credential;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.security.Credential;
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java b/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java
index b7e64ac123b..d3921bcab0a 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java
@@ -15,7 +15,6 @@ import java.util.Set;
import javax.security.auth.Subject;
-import org.eclipse.jetty.http.security.Credential;
import org.eclipse.jetty.security.MappedLoginService.KnownUser;
import org.eclipse.jetty.security.MappedLoginService.RolePrincipal;
import org.eclipse.jetty.server.UserIdentity;
@@ -25,6 +24,7 @@ import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.util.security.Credential;
/**
* PropertyUserStore
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoLoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoLoginService.java
index f4949b05d40..94321f03ae6 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoLoginService.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoLoginService.java
@@ -15,17 +15,16 @@ package org.eclipse.jetty.security;
//You may elect to redistribute this code under either of these licenses.
//========================================================================
-import java.util.Collections;
import java.util.Properties;
import javax.security.auth.Subject;
-import org.eclipse.jetty.http.security.B64Code;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.util.security.B64Code;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSCredential;
import org.ietf.jgss.GSSException;
@@ -100,7 +99,7 @@ public class SpnegoLoginService extends AbstractLifeCycle implements LoginServic
_targetName = properties.getProperty("targetName");
- LOG.debug("\n\nTarget Name\n\n" + _targetName);
+ LOG.debug("Target Name {}", _targetName);
super.doStart();
}
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserPrincipal.java b/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserPrincipal.java
index bfadf400317..a30f60996f5 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserPrincipal.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserPrincipal.java
@@ -2,7 +2,7 @@ package org.eclipse.jetty.security;
import java.security.Principal;
-import org.eclipse.jetty.http.security.B64Code;
+import org.eclipse.jetty.util.security.B64Code;
public class SpnegoUserPrincipal implements Principal
{
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/UserAuthentication.java b/jetty-security/src/main/java/org/eclipse/jetty/security/UserAuthentication.java
index cef019b14fe..da55e961c47 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/UserAuthentication.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/UserAuthentication.java
@@ -13,9 +13,6 @@
package org.eclipse.jetty.security;
-import java.io.Serializable;
-
-import org.eclipse.jetty.security.authentication.LoginAuthenticator;
import org.eclipse.jetty.server.Authentication;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.server.UserIdentity.Scope;
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java
index 372f9b63ea0..7857b4d46ae 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java
@@ -21,14 +21,14 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpHeaders;
-import org.eclipse.jetty.http.security.Constraint;
import org.eclipse.jetty.security.ServerAuthException;
import org.eclipse.jetty.security.UserAuthentication;
import org.eclipse.jetty.server.Authentication;
-import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.server.Authentication.User;
+import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.util.B64Code;
import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.security.Constraint;
/**
* @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java
index 9efd783b8a0..25220375506 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java
@@ -25,8 +25,6 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.http.security.Constraint;
-import org.eclipse.jetty.http.security.Password;
import org.eclipse.jetty.security.ServerAuthException;
import org.eclipse.jetty.security.UserAuthentication;
import org.eclipse.jetty.server.Authentication;
@@ -35,6 +33,8 @@ import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.util.B64Code;
import org.eclipse.jetty.util.security.CertificateUtils;
import org.eclipse.jetty.util.security.CertificateValidator;
+import org.eclipse.jetty.util.security.Constraint;
+import org.eclipse.jetty.util.security.Password;
/**
* @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java
index 5a2ecf412e8..51833fad789 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java
@@ -28,22 +28,21 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpHeaders;
-import org.eclipse.jetty.http.security.Constraint;
-import org.eclipse.jetty.http.security.Credential;
-import org.eclipse.jetty.security.Authenticator.AuthConfiguration;
import org.eclipse.jetty.security.SecurityHandler;
import org.eclipse.jetty.security.ServerAuthException;
import org.eclipse.jetty.security.UserAuthentication;
import org.eclipse.jetty.server.Authentication;
+import org.eclipse.jetty.server.Authentication.User;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.UserIdentity;
-import org.eclipse.jetty.server.Authentication.User;
import org.eclipse.jetty.util.B64Code;
import org.eclipse.jetty.util.QuotedStringTokenizer;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.security.Constraint;
+import org.eclipse.jetty.util.security.Credential;
/**
* @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $
@@ -87,7 +86,18 @@ public class DigestAuthenticator extends LoginAuthenticator
String mna=configuration.getInitParameter("maxNonceAge");
if (mna!=null)
- _maxNonceAgeMs=Long.valueOf(mna);
+ {
+ synchronized (this)
+ {
+ _maxNonceAgeMs=Long.valueOf(mna);
+ }
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ public synchronized void setMaxNonceAge(long maxNonceAgeInMillis)
+ {
+ _maxNonceAgeMs = maxNonceAgeInMillis;
}
/* ------------------------------------------------------------ */
@@ -117,7 +127,8 @@ public class DigestAuthenticator extends LoginAuthenticator
boolean stale = false;
if (credentials != null)
{
- if (LOG.isDebugEnabled()) LOG.debug("Credentials: " + credentials);
+ if (LOG.isDebugEnabled())
+ LOG.debug("Credentials: " + credentials);
QuotedStringTokenizer tokenizer = new QuotedStringTokenizer(credentials, "=, ", true, false);
final Digest digest = new Digest(request.getMethod());
String last = null;
@@ -234,7 +245,11 @@ public class DigestAuthenticator extends LoginAuthenticator
private int checkNonce(Digest digest, Request request)
{
// firstly let's expire old nonces
- long expired = request.getTimeStamp()-_maxNonceAgeMs;
+ long expired;
+ synchronized (this)
+ {
+ expired = request.getTimeStamp()-_maxNonceAgeMs;
+ }
Nonce nonce=_nonceQueue.peek();
while (nonce!=null && nonce._ts(base_request.getParameters()));
}
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java
index 98cb1968b6d..c730a9bab5c 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java
@@ -24,7 +24,6 @@ import javax.servlet.http.HttpSession;
import org.eclipse.jetty.security.Authenticator;
import org.eclipse.jetty.security.IdentityService;
import org.eclipse.jetty.security.LoginService;
-import org.eclipse.jetty.server.SessionManager;
public abstract class LoginAuthenticator implements Authenticator
{
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java
index 0e28f3d4193..e63e597ccae 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java
@@ -16,20 +16,16 @@ package org.eclipse.jetty.security.authentication;
import java.io.IOException;
import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
import java.io.Serializable;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionActivationListener;
-import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionEvent;
-import org.eclipse.jetty.security.Authenticator;
import org.eclipse.jetty.security.LoginService;
import org.eclipse.jetty.security.SecurityHandler;
-import org.eclipse.jetty.security.UserAuthentication;
import org.eclipse.jetty.server.Authentication;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.server.UserIdentity.Scope;
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator.java
index 8ed9a790a0f..9df7448468a 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator.java
@@ -23,7 +23,6 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpHeaders;
-import org.eclipse.jetty.http.security.Constraint;
import org.eclipse.jetty.security.ServerAuthException;
import org.eclipse.jetty.security.UserAuthentication;
import org.eclipse.jetty.server.Authentication;
@@ -31,6 +30,7 @@ import org.eclipse.jetty.server.Authentication.User;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.security.Constraint;
public class SpnegoAuthenticator extends LoginAuthenticator
{
diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java
index 19eb3099011..47190675b63 100644
--- a/jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java
+++ b/jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java
@@ -27,8 +27,6 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.http.security.Constraint;
-import org.eclipse.jetty.http.security.Password;
import org.eclipse.jetty.security.authentication.BasicAuthenticator;
import org.eclipse.jetty.security.authentication.FormAuthenticator;
import org.eclipse.jetty.server.Connector;
@@ -41,7 +39,8 @@ import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.util.B64Code;
-import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.security.Constraint;
+import org.eclipse.jetty.util.security.Password;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/PropertyUserStoreTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/PropertyUserStoreTest.java
index 68220b8dbca..2e24c178c4d 100644
--- a/jetty-security/src/test/java/org/eclipse/jetty/security/PropertyUserStoreTest.java
+++ b/jetty-security/src/test/java/org/eclipse/jetty/security/PropertyUserStoreTest.java
@@ -9,7 +9,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import junit.framework.Assert;
-import org.eclipse.jetty.http.security.Credential;
+import org.eclipse.jetty.util.security.Credential;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
diff --git a/jetty-server/pom.xml b/jetty-server/pom.xml
index 9cd880908e3..8e71f15966d 100644
--- a/jetty-server/pom.xml
+++ b/jetty-server/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty
jetty-project
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
4.0.0
jetty-server
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
index 199d0e18e26..6f349ca4f8b 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
@@ -48,8 +48,8 @@ import org.eclipse.jetty.util.thread.ThreadPool;
* Base acceptor thread
* Optional reverse proxy headers checking
*
- *
- *
+ *
+ *
*/
public abstract class AbstractConnector extends HttpBuffers implements Connector, Dumpable
{
@@ -181,7 +181,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
*
* Previously, Jetty supported separate idle timeouts and IO operation timeouts, however the expense of changing the value of soTimeout was significant, so
* these timeouts were merged. With the advent of NIO, it may be possible to again differentiate these values (if there is demand).
- *
+ *
* @param maxIdleTime
* The maxIdleTime to set.
*/
@@ -358,7 +358,11 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
/* ------------------------------------------------------------ */
public void join() throws InterruptedException
{
- Thread[] threads = _acceptorThread;
+ Thread[] threads;
+ synchronized(this)
+ {
+ threads= _acceptorThread;
+ }
if (threads != null)
for (int i = 0; i < threads.length; i++)
if (threads[i] != null)
@@ -410,13 +414,13 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
request.setScheme(HttpSchemes.HTTPS);
}
}
-
+
// Retrieving headers from the request
String forwardedHost = getLeftMostFieldValue(httpFields,getForwardedHostHeader());
String forwardedServer = getLeftMostFieldValue(httpFields,getForwardedServerHeader());
String forwardedFor = getLeftMostFieldValue(httpFields,getForwardedForHeader());
String forwardedProto = getLeftMostFieldValue(httpFields,getForwardedProtoHeader());
-
+
if (_hostHeader != null)
{
// Update host header
@@ -458,7 +462,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
request.setRemoteHost(inetAddress == null?forwardedFor:inetAddress.getHostName());
}
-
+
if (forwardedProto != null)
{
request.setScheme(forwardedProto);
@@ -611,7 +615,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
/* ------------------------------------------------------------ */
/**
* Is reverse proxy handling on?
- *
+ *
* @return true if this connector is checking the x-forwarded-for/host/server headers
*/
public boolean isForwarded()
@@ -623,7 +627,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
/**
* Set reverse proxy handling. If set to true, then the X-Forwarded headers (or the headers set in their place) are looked for to set the request protocol,
* host, server and client ip.
- *
+ *
* @param check
* true if this connector is checking the x-forwarded-for/host/server headers
* @set {@link #setForwardedForHeader(String)}
@@ -634,7 +638,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
public void setForwarded(boolean check)
{
if (check)
- LOG.debug(this + " is forwarded");
+ LOG.debug("{} is forwarded",this);
_forwarded = check;
}
@@ -648,7 +652,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
/**
* Set a forced valued for the host header to control what is returned by {@link ServletRequest#getServerName()} and {@link ServletRequest#getServerPort()}.
* This value is only used if {@link #isForwarded()} is true.
- *
+ *
* @param hostHeader
* The value of the host header to force.
*/
@@ -659,7 +663,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
/* ------------------------------------------------------------ */
/*
- *
+ *
* @see #setForwarded(boolean)
*/
public String getForwardedHostHeader()
@@ -722,7 +726,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
/* ------------------------------------------------------------ */
/**
* Get the forwardedProtoHeader.
- *
+ *
* @return the forwardedProtoHeader (default X-Forwarded-For)
* @see #setForwarded(boolean)
*/
@@ -734,7 +738,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
/* ------------------------------------------------------------ */
/**
* Set the forwardedProtoHeader.
- *
+ *
* @param forwardedProtoHeader
* the forwardedProtoHeader to set (default X-Forwarded-For)
* @see #setForwarded(boolean)
@@ -845,10 +849,6 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
// Connector has been stopped
LOG.ignore(x);
}
- catch (ThreadDeath e)
- {
- throw e;
- }
catch (Throwable e)
{
LOG.warn(e);
@@ -1001,7 +1001,8 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
if (on && _statsStartedAt.get() != -1)
return;
- LOG.debug("Statistics on = " + on + " for " + this);
+ if (LOG.isDebugEnabled())
+ LOG.debug("Statistics on = " + on + " for " + this);
statsReset();
_statsStartedAt.set(on?System.currentTimeMillis():-1);
@@ -1039,19 +1040,19 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
/* ------------------------------------------------------------ */
protected void connectionUpgraded(Connection oldConnection, Connection newConnection)
{
- _requestStats.set((oldConnection instanceof HttpConnection)?((HttpConnection)oldConnection).getRequests():0);
+ _requestStats.set((oldConnection instanceof AbstractHttpConnection)?((AbstractHttpConnection)oldConnection).getRequests():0);
}
/* ------------------------------------------------------------ */
protected void connectionClosed(Connection connection)
{
- connection.closed();
+ connection.onClose();
if (_statsStartedAt.get() == -1)
return;
long duration = System.currentTimeMillis() - connection.getTimeStamp();
- int requests = (connection instanceof HttpConnection)?((HttpConnection)connection).getRequests():0;
+ int requests = (connection instanceof AbstractHttpConnection)?((AbstractHttpConnection)connection).getRequests():0;
_requestStats.set(requests);
_connectionStats.decrement();
_connectionDurationStats.set(duration);
@@ -1070,7 +1071,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
/**
* Set the priority offset of the acceptor threads. The priority is adjusted by this amount (default 0) to either favour the acceptance of new threads and
* newly active connections or to favour the handling of already dispatched connections.
- *
+ *
* @param offset
* the amount to alter the priority of the acceptor threads.
*/
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java
similarity index 90%
rename from jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java
rename to jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java
index 3f1d327d75b..6869768901f 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java
@@ -1,5 +1,5 @@
// ========================================================================
-// Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
+// Copyright (c) 2004-2011 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
@@ -22,7 +22,6 @@ import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.continuation.ContinuationThrowable;
-import org.eclipse.jetty.http.AbstractGenerator;
import org.eclipse.jetty.http.EncodedHttpURI;
import org.eclipse.jetty.http.Generator;
import org.eclipse.jetty.http.HttpBuffers;
@@ -40,9 +39,9 @@ import org.eclipse.jetty.http.HttpVersions;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.http.Parser;
import org.eclipse.jetty.io.AbstractConnection;
-import org.eclipse.jetty.io.AsyncEndPoint;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.BufferCache.CachedBuffer;
+import org.eclipse.jetty.io.Buffers;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.EofException;
@@ -56,7 +55,6 @@ import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
-import org.eclipse.jetty.util.thread.Timeout;
/**
*
A HttpConnection represents the connection of a HTTP client to the server
@@ -89,12 +87,12 @@ import org.eclipse.jetty.util.thread.Timeout;
*
*
*/
-public abstract class HttpConnection extends AbstractConnection
+public abstract class AbstractHttpConnection extends AbstractConnection
{
- private static final Logger LOG = Log.getLogger(HttpConnection.class);
+ private static final Logger LOG = Log.getLogger(AbstractHttpConnection.class);
private static final int UNKNOWN = -2;
- private static final ThreadLocal __currentConnection = new ThreadLocal();
+ private static final ThreadLocal __currentConnection = new ThreadLocal();
private int _requests;
@@ -128,13 +126,13 @@ public abstract class HttpConnection extends AbstractConnection
private boolean _delayedHandling=false;
/* ------------------------------------------------------------ */
- public static HttpConnection getCurrentConnection()
+ public static AbstractHttpConnection getCurrentConnection()
{
return __currentConnection.get();
}
/* ------------------------------------------------------------ */
- protected static void setCurrentConnection(HttpConnection connection)
+ protected static void setCurrentConnection(AbstractHttpConnection connection)
{
__currentConnection.set(connection);
}
@@ -143,13 +141,13 @@ public abstract class HttpConnection extends AbstractConnection
/** Constructor
*
*/
- public HttpConnection(Connector connector, EndPoint endpoint, Server server)
+ public AbstractHttpConnection(Connector connector, EndPoint endpoint, Server server)
{
super(endpoint);
_uri = StringUtil.__UTF8.equals(URIUtil.__CHARSET)?new HttpURI():new EncodedHttpURI(URIUtil.__CHARSET);
_connector = connector;
HttpBuffers ab = (HttpBuffers)_connector;
- _parser = new HttpParser(ab.getRequestBuffers(), endpoint, new RequestHandler());
+ _parser = newHttpParser(ab.getRequestBuffers(), endpoint, new RequestHandler());
_requestFields = new HttpFields();
_responseFields = new HttpFields(server.getMaxCookieVersion());
_request = new Request(this);
@@ -160,11 +158,11 @@ public abstract class HttpConnection extends AbstractConnection
}
/* ------------------------------------------------------------ */
- protected HttpConnection(Connector connector, EndPoint endpoint, Server server,
+ protected AbstractHttpConnection(Connector connector, EndPoint endpoint, Server server,
Parser parser, Generator generator, Request request)
{
super(endpoint);
-
+
_uri = URIUtil.__CHARSET.equals(StringUtil.__UTF8)?new HttpURI():new EncodedHttpURI(URIUtil.__CHARSET);
_connector = connector;
_parser = parser;
@@ -177,6 +175,11 @@ public abstract class HttpConnection extends AbstractConnection
_server = server;
}
+ protected HttpParser newHttpParser(Buffers requestBuffers, EndPoint endpoint, HttpParser.EventHandler requestHandler)
+ {
+ return new HttpParser(requestBuffers, endpoint, requestHandler);
+ }
+
/* ------------------------------------------------------------ */
/**
* @return the parser used by this connection
@@ -194,13 +197,13 @@ public abstract class HttpConnection extends AbstractConnection
{
return _requests;
}
-
+
/* ------------------------------------------------------------ */
public Server getServer()
{
return _server;
}
-
+
/* ------------------------------------------------------------ */
/**
* @return Returns the associatedObject.
@@ -327,7 +330,7 @@ public abstract class HttpConnection extends AbstractConnection
}
if (_in == null)
- _in = new HttpInput(HttpConnection.this);
+ _in = new HttpInput(AbstractHttpConnection.this);
return _in;
}
@@ -353,7 +356,27 @@ public abstract class HttpConnection extends AbstractConnection
if (_writer==null)
{
_writer=new OutputWriter();
- _printWriter=new UncheckedPrintWriter(_writer);
+ if (_server.isUncheckedPrintWriter())
+ _printWriter=new UncheckedPrintWriter(_writer);
+ else
+ _printWriter = new PrintWriter(_writer)
+ {
+ public void close()
+ {
+ synchronized (lock)
+ {
+ try
+ {
+ out.close();
+ }
+ catch (IOException e)
+ {
+ setError();
+ }
+ }
+ }
+ };
+
}
_writer.setCharacterEncoding(encoding);
return _printWriter;
@@ -366,30 +389,16 @@ public abstract class HttpConnection extends AbstractConnection
}
/* ------------------------------------------------------------ */
- public void scheduleTimeout(Timeout.Task task, long timeoutMs)
+ public void reset()
{
- throw new UnsupportedOperationException();
- }
-
- /* ------------------------------------------------------------ */
- public void cancelTimeout(Timeout.Task task)
- {
- throw new UnsupportedOperationException();
- }
-
- /* ------------------------------------------------------------ */
- public void reset(boolean returnBuffers)
- {
- _parser.reset();
- if (returnBuffers)
- _parser.returnBuffers();
+ _parser.reset();
+ _parser.returnBuffers(); // TODO maybe only on unhandle
_requestFields.clear();
_request.recycle();
-
- _generator.reset(returnBuffers); // TODO maybe only release when low on resources
+ _generator.reset();
+ _generator.returnBuffers();// TODO maybe only on unhandle
_responseFields.clear();
_response.recycle();
-
_uri.clear();
}
@@ -471,9 +480,6 @@ public abstract class HttpConnection extends AbstractConnection
}
catch (Throwable e)
{
- if (e instanceof ThreadDeath)
- throw (ThreadDeath)e;
-
LOG.warn(String.valueOf(_uri),e);
error=true;
_request.setHandled(true);
@@ -557,10 +563,10 @@ public abstract class HttpConnection extends AbstractConnection
}
catch(RuntimeException e)
{
- LOG.warn("header full: "+e);
+ LOG.warn("header full: " + e);
_response.reset();
- _generator.reset(true);
+ _generator.reset();
_generator.setResponse(HttpStatus.INTERNAL_SERVER_ERROR_500,null);
_generator.completeHeader(_responseFields,Generator.LAST);
_generator.complete();
@@ -592,7 +598,7 @@ public abstract class HttpConnection extends AbstractConnection
LOG.debug(e);
_response.reset();
- _generator.reset(true);
+ _generator.reset();
_generator.setResponse(HttpStatus.INTERNAL_SERVER_ERROR_500,null);
_generator.completeHeader(_responseFields,Generator.LAST);
_generator.complete();
@@ -659,11 +665,11 @@ public abstract class HttpConnection extends AbstractConnection
}
/* ------------------------------------------------------------ */
- public void closed()
+ public void onClose()
{
LOG.debug("closed {}",this);
}
-
+
/* ------------------------------------------------------------ */
public boolean isExpecting100Continues()
{
@@ -686,6 +692,16 @@ public abstract class HttpConnection extends AbstractConnection
return _connector.getMaxIdleTime();
}
+ /* ------------------------------------------------------------ */
+ public String toString()
+ {
+ return String.format("%s,g=%s,p=%s,r=%d",
+ super.toString(),
+ _generator,
+ _parser,
+ _requests);
+ }
+
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
@@ -702,7 +718,7 @@ public abstract class HttpConnection extends AbstractConnection
public void startRequest(Buffer method, Buffer uri, Buffer version) throws IOException
{
uri=uri.asImmutableBuffer();
-
+
_host = false;
_expect = false;
_expect100Continue=false;
@@ -725,7 +741,8 @@ public abstract class HttpConnection extends AbstractConnection
case HttpMethods.HEAD_ORDINAL:
_head=true;
- // fall through
+ _uri.parse(uri.array(), uri.getIndex(), uri.length());
+ break;
default:
_uri.parse(uri.array(), uri.getIndex(), uri.length());
@@ -817,46 +834,6 @@ public abstract class HttpConnection extends AbstractConnection
value = MimeTypes.CACHE.lookup(value);
_charset=MimeTypes.getCharsetFromContentType(value);
break;
-
- case HttpHeaders.CONNECTION_ORDINAL:
- //looks rather clumsy, but the idea is to optimize for a single valued header
- switch(HttpHeaderValues.CACHE.getOrdinal(value))
- {
- case -1:
- {
- String[] values = value.toString().split(",");
- for (int i=0;values!=null && i _continuationListeners;
/* ------------------------------------------------------------ */
@@ -90,7 +90,7 @@ public class AsyncContinuation implements AsyncContext, Continuation
}
/* ------------------------------------------------------------ */
- protected void setConnection(final HttpConnection connection)
+ protected void setConnection(final AbstractHttpConnection connection)
{
synchronized(this)
{
@@ -183,6 +183,26 @@ public class AsyncContinuation implements AsyncContext, Continuation
}
}
}
+
+ /* ------------------------------------------------------------ */
+ /* (non-Javadoc)
+ * @see javax.servlet.ServletRequest#isSuspended()
+ */
+ public boolean isSuspending()
+ {
+ synchronized(this)
+ {
+ switch(_state)
+ {
+ case __ASYNCSTARTED:
+ case __ASYNCWAIT:
+ return true;
+
+ default:
+ return false;
+ }
+ }
+ }
/* ------------------------------------------------------------ */
@Override
@@ -539,7 +559,7 @@ public class AsyncContinuation implements AsyncContext, Continuation
EndPoint endp=_connection.getEndPoint();
if (!endp.isBlocking())
{
- ((AsyncEndPoint)endp).dispatch();
+ ((AsyncEndPoint)endp).asyncDispatch();
}
}
@@ -576,7 +596,7 @@ public class AsyncContinuation implements AsyncContext, Continuation
}
else
{
- _connection.scheduleTimeout(_event,_timeoutMs);
+ ((AsyncEndPoint)endp).scheduleTimeout(_event,_timeoutMs);
}
}
}
@@ -597,7 +617,9 @@ public class AsyncContinuation implements AsyncContext, Continuation
{
final AsyncEventState event=_event;
if (event!=null)
- _connection.cancelTimeout(event);
+ {
+ ((AsyncEndPoint)endp).cancelTimeout(event);
+ }
}
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncHttpConnection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncHttpConnection.java
index 4d72d8feb19..9d79c6cd78f 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncHttpConnection.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncHttpConnection.java
@@ -1,3 +1,16 @@
+// ========================================================================
+// Copyright (c) 2006-2011 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+
package org.eclipse.jetty.server;
import java.io.IOException;
@@ -7,21 +20,29 @@ import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.io.AsyncEndPoint;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.nio.AsyncConnection;
import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
-public class AsyncHttpConnection extends HttpConnection
+
+/* ------------------------------------------------------------ */
+/** Asychronous Server HTTP connection
+ *
+ */
+public class AsyncHttpConnection extends AbstractHttpConnection implements AsyncConnection
{
private final static int NO_PROGRESS_INFO = Integer.getInteger("org.mortbay.jetty.NO_PROGRESS_INFO",100);
private final static int NO_PROGRESS_CLOSE = Integer.getInteger("org.mortbay.jetty.NO_PROGRESS_CLOSE",200);
private static final Logger LOG = Log.getLogger(AsyncHttpConnection.class);
private int _total_no_progress;
+ private final AsyncEndPoint _asyncEndp;
public AsyncHttpConnection(Connector connector, EndPoint endpoint, Server server)
{
super(connector,endpoint,server);
+ _asyncEndp=(AsyncEndPoint)endpoint;
}
public Connection handle() throws IOException
@@ -30,39 +51,34 @@ public class AsyncHttpConnection extends HttpConnection
boolean some_progress=false;
boolean progress=true;
- // Loop while more in buffer
try
{
setCurrentConnection(this);
- boolean more_in_buffer =false;
-
- while (_endp.isOpen() && (more_in_buffer || progress) && connection==this)
+ // While progress and the connection has not changed
+ while (progress && connection==this)
{
progress=false;
try
{
-
// Handle resumed request
if (_request._async.isAsync() && !_request._async.isComplete())
handleRequest();
-
// else Parse more input
- else if (!_parser.isComplete() && _parser.parseAvailable()>0)
+ else if (!_parser.isComplete() && _parser.parseAvailable())
progress=true;
// Generate more output
- if (_generator.isCommitted() && !_generator.isComplete() && _generator.flushBuffer()>0)
+ if (_generator.isCommitted() && !_generator.isComplete() && !_endp.isOutputShutdown())
+ if (_generator.flushBuffer()>0)
+ progress=true;
+
+ // Flush output
+ _endp.flush();
+
+ // Has any IO been done by the endpoint itself since last loop
+ if (_asyncEndp.hasProgressed())
progress=true;
-
- // Flush output from buffering endpoint
- if (_endp.isBufferingOutput())
- _endp.flush();
-
- // Special case close handling.
- // If we were dispatched and have made no progress, but io is shutdown, then close
- if (!progress && !some_progress && (_endp.isInputShutdown()||_endp.isOutputShutdown()))
- _endp.close();
}
catch (HttpException e)
{
@@ -72,91 +88,81 @@ public class AsyncHttpConnection extends HttpConnection
LOG.debug("fields="+_requestFields);
LOG.debug(e);
}
+ progress=true;
_generator.sendError(e.getStatus(), e.getReason(), null, true);
- _parser.reset();
- _endp.close();
}
finally
{
- // Do we need to complete a half close?
- if (_endp.isInputShutdown() && (_parser.isIdle() || _parser.isComplete()))
+ some_progress|=progress;
+ // Is this request/response round complete and are fully flushed?
+ if (_parser.isComplete() && _generator.isComplete())
{
- LOG.debug("complete half close {}",this);
- more_in_buffer=false;
- _endp.close();
- reset(true);
- }
+ // Reset the parser/generator
+ progress=true;
- // else Is this request/response round complete?
- else if (_parser.isComplete() && _generator.isComplete() && !_endp.isBufferingOutput())
- {
// look for a switched connection instance?
if (_response.getStatus()==HttpStatus.SWITCHING_PROTOCOLS_101)
{
Connection switched=(Connection)_request.getAttribute("org.eclipse.jetty.io.Connection");
if (switched!=null)
- {
- _parser.reset();
- _generator.reset(true);
connection=switched;
- }
}
- // Reset the parser/generator
- // keep the buffers as we will cycle
- progress=true;
- reset(false);
- more_in_buffer = _parser.isMoreInBuffer() || _endp.isBufferingInput();
- }
- // else Are we suspended?
- else if (_request.isAsyncStarted())
- {
- LOG.debug("suspended {}",this);
- more_in_buffer=false;
- progress=false;
- }
- else
- more_in_buffer = _parser.isMoreInBuffer() || _endp.isBufferingInput();
+ reset();
- some_progress|=progress|((SelectChannelEndPoint)_endp).isProgressing();
+ // TODO Is this still required?
+ if (!_generator.isPersistent() && !_endp.isOutputShutdown())
+ {
+ LOG.warn("Safety net oshut!!! IF YOU SEE THIS, PLEASE RAISE BUGZILLA");
+ _endp.shutdownOutput();
+ }
+ }
+ else if (_request.getAsyncContinuation().isAsyncStarted())
+ {
+ // The request is suspended, so even though progress has been made, break the while loop
+ LOG.debug("suspended {}",this);
+ // TODO: breaking inside finally blocks is bad: rethink how we should exit from here
+ break;
+ }
}
}
}
finally
{
setCurrentConnection(null);
- _parser.returnBuffers();
- _generator.returnBuffers();
-
- // Check if we are write blocked
- if (_generator.isCommitted() && !_generator.isComplete() && _endp.isOpen() && !_endp.isOutputShutdown())
- ((AsyncEndPoint)_endp).scheduleWrite(); // TODO. This should not be required
-
- if (some_progress)
+ if (!_request.isAsyncStarted())
{
- _total_no_progress=0;
+ _parser.returnBuffers();
+ _generator.returnBuffers();
}
+
+ // Safety net to catch spinning
+ if (some_progress)
+ _total_no_progress=0;
else
{
- int totalNoProgress=++_total_no_progress;
-
- if (NO_PROGRESS_INFO>0 && totalNoProgress==NO_PROGRESS_INFO && (NO_PROGRESS_CLOSE<=0 || totalNoProgress0 && _total_no_progress%NO_PROGRESS_INFO==0 && (NO_PROGRESS_CLOSE<=0 || _total_no_progress< NO_PROGRESS_CLOSE))
+ LOG.info("EndPoint making no progress: "+_total_no_progress+" "+_endp+" "+this);
+ if (NO_PROGRESS_CLOSE>0 && _total_no_progress==NO_PROGRESS_CLOSE)
{
- LOG.info("EndPoint making no progress: {} {}", totalNoProgress, _endp);
- }
-
- if (NO_PROGRESS_CLOSE>0 && totalNoProgress==NO_PROGRESS_CLOSE)
- {
- LOG.warn("Closing EndPoint making no progress: {} {}", totalNoProgress, _endp);
+ LOG.warn("Closing EndPoint making no progress: "+_total_no_progress+" "+_endp+" "+this);
if (_endp instanceof SelectChannelEndPoint)
- {
- System.err.println(((SelectChannelEndPoint)_endp).getSelectManager().dump());
((SelectChannelEndPoint)_endp).getChannel().close();
- }
}
}
}
return connection;
}
+ public void onInputShutdown() throws IOException
+ {
+ // If we don't have a committed response and we are not suspended
+ if (_generator.isIdle() && !_request.getAsyncContinuation().isSuspended())
+ {
+ // then no more can happen, so close.
+ _endp.close();
+ }
+ }
+
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/BlockingHttpConnection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/BlockingHttpConnection.java
index 975f942389e..ec15289f914 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/BlockingHttpConnection.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/BlockingHttpConnection.java
@@ -1,3 +1,15 @@
+// ========================================================================
+// Copyright (c) 2006-2011 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
package org.eclipse.jetty.server;
import java.io.IOException;
@@ -6,66 +18,62 @@ import org.eclipse.jetty.http.Generator;
import org.eclipse.jetty.http.HttpException;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.Parser;
-import org.eclipse.jetty.io.AsyncEndPoint;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
-public class BlockingHttpConnection extends HttpConnection
+
+/* ------------------------------------------------------------ */
+/** Blocking Server HTTP Connection
+ */
+public class BlockingHttpConnection extends AbstractHttpConnection
{
private static final Logger LOG = Log.getLogger(BlockingHttpConnection.class);
- private volatile boolean _handling;
-
public BlockingHttpConnection(Connector connector, EndPoint endpoint, Server server)
{
super(connector,endpoint,server);
}
-
public BlockingHttpConnection(Connector connector, EndPoint endpoint, Server server, Parser parser, Generator generator, Request request)
{
super(connector,endpoint,server,parser,generator,request);
}
+ @Override
+ protected void handleRequest() throws IOException
+ {
+ super.handleRequest();
+ }
public Connection handle() throws IOException
{
Connection connection = this;
- // Loop while more in buffer
- boolean more_in_buffer =true; // assume true until proven otherwise
-
try
{
setCurrentConnection(this);
- while (more_in_buffer && _endp.isOpen())
+ // do while the endpoint is open
+ // AND the connection has not changed
+ while (_endp.isOpen() && connection==this)
{
try
{
// If we are not ended then parse available
- if (!_parser.isComplete())
+ if (!_parser.isComplete() && !_endp.isInputShutdown())
_parser.parseAvailable();
// Do we have more generating to do?
// Loop here because some writes may take multiple steps and
// we need to flush them all before potentially blocking in the
// next loop.
- while (_generator.isCommitted() && !_generator.isComplete())
- {
- long written=_generator.flushBuffer();
- if (written<=0)
- break;
- if (_endp.isBufferingOutput())
- _endp.flush();
- }
+ if (_generator.isCommitted() && !_generator.isComplete() && !_endp.isOutputShutdown())
+ _generator.flushBuffer();
// Flush buffers
- if (_endp.isBufferingOutput())
- _endp.flush();
-
+ _endp.flush();
}
catch (HttpException e)
{
@@ -81,59 +89,37 @@ public class BlockingHttpConnection extends HttpConnection
}
finally
{
- more_in_buffer = _parser.isMoreInBuffer() || _endp.isBufferingInput();
-
- // Is this request/response round complete?
- if (_parser.isComplete() && _generator.isComplete() && !_endp.isBufferingOutput())
+ // Is this request/response round complete and are fully flushed?
+ if (_parser.isComplete() && _generator.isComplete())
{
+ // Reset the parser/generator
+ reset();
+
// look for a switched connection instance?
- Connection switched=(_response.getStatus()==HttpStatus.SWITCHING_PROTOCOLS_101)
- ?(Connection)_request.getAttribute("org.eclipse.jetty.io.Connection"):null;
-
- // have we switched?
- if (switched!=null)
+ if (_response.getStatus()==HttpStatus.SWITCHING_PROTOCOLS_101)
{
- _parser.reset();
- _generator.reset(true);
- connection=switched;
+ Connection switched=(Connection)_request.getAttribute("org.eclipse.jetty.io.Connection");
+ if (switched!=null)
+ connection=switched;
}
- else
- {
- // No switch, so cleanup and reset
- if (!_generator.isPersistent() || _endp.isInputShutdown())
- {
- _parser.reset();
- more_in_buffer=false;
- _endp.close();
- }
- if (more_in_buffer)
- {
- reset(false);
- more_in_buffer = _parser.isMoreInBuffer() || _endp.isBufferingInput();
- }
- else
- reset(true);
+ // TODO Is this required?
+ if (!_generator.isPersistent() && !_endp.isOutputShutdown())
+ {
+ LOG.warn("Safety net oshut!!! Please open a bugzilla");
+ _endp.shutdownOutput();
}
}
- else if (_parser.isIdle() && _endp.isInputShutdown())
- {
- more_in_buffer=false;
- _endp.close();
- }
-
- if (_request.isAsyncStarted())
- throw new IllegalStateException();
}
}
+
+ return connection;
}
finally
{
- _parser.returnBuffers();
setCurrentConnection(null);
- _handling=false;
+ _parser.returnBuffers();
+ _generator.returnBuffers();
}
- return connection;
}
-
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java
index ddad84d6aa3..95c30b15139 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java
@@ -135,14 +135,14 @@ public interface Connector extends LifeCycle
/* ------------------------------------------------------------ */
/**
* @return The port to use when redirecting a request if a data constraint of integral is
- * required. See {@link org.eclipse.jetty.http.security.Constraint#getDataConstraint()}
+ * required. See {@link org.eclipse.jetty.util.security.Constraint#getDataConstraint()}
*/
int getIntegralPort();
/* ------------------------------------------------------------ */
/**
* @return The schema to use when redirecting a request if a data constraint of integral is
- * required. See {@link org.eclipse.jetty.http.security.Constraint#getDataConstraint()}
+ * required. See {@link org.eclipse.jetty.util.security.Constraint#getDataConstraint()}
*/
String getIntegralScheme();
@@ -156,7 +156,7 @@ public interface Connector extends LifeCycle
/* ------------------------------------------------------------ */
/**
* @return The port to use when redirecting a request if a data constraint of confidential is
- * required. See {@link org.eclipse.jetty.http.security.Constraint#getDataConstraint()}
+ * required. See {@link org.eclipse.jetty.util.security.Constraint#getDataConstraint()}
*/
int getConfidentialPort();
@@ -164,7 +164,7 @@ public interface Connector extends LifeCycle
/* ------------------------------------------------------------ */
/**
* @return The schema to use when redirecting a request if a data constraint of confidential is
- * required. See {@link org.eclipse.jetty.http.security.Constraint#getDataConstraint()}
+ * required. See {@link org.eclipse.jetty.util.security.Constraint#getDataConstraint()}
*/
String getConfidentialScheme();
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java
index 5422cb2662c..99c9ec33127 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java
@@ -130,7 +130,7 @@ public class Dispatcher implements RequestDispatcher
*/
public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException
{
- Request baseRequest=(request instanceof Request)?((Request)request):HttpConnection.getCurrentConnection().getRequest();
+ Request baseRequest=(request instanceof Request)?((Request)request):AbstractHttpConnection.getCurrentConnection().getRequest();
request.removeAttribute(__JSP_FILE); // TODO remove when glassfish 1044 is fixed
if (!(request instanceof HttpServletRequest))
@@ -211,7 +211,7 @@ public class Dispatcher implements RequestDispatcher
*/
protected void forward(ServletRequest request, ServletResponse response, DispatcherType dispatch) throws ServletException, IOException
{
- Request baseRequest=(request instanceof Request)?((Request)request):HttpConnection.getCurrentConnection().getRequest();
+ Request baseRequest=(request instanceof Request)?((Request)request):AbstractHttpConnection.getCurrentConnection().getRequest();
Response base_response=baseRequest.getResponse();
response.resetBuffer();
base_response.fwdReset();
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Handler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Handler.java
index 519c8730c54..cf16c0b14a7 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Handler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Handler.java
@@ -47,10 +47,10 @@ public interface Handler extends LifeCycle, Destroyable
* @param target The target of the request - either a URI or a name.
* @param baseRequest The original unwrapped request object.
* @param request The request either as the {@link Request}
- * object or a wrapper of that request. The {@link HttpConnection#getCurrentConnection()}
+ * object or a wrapper of that request. The {@link AbstractHttpConnection#getCurrentConnection()}
* method can be used access the Request object if required.
* @param response The response as the {@link Response}
- * object or a wrapper of that request. The {@link HttpConnection#getCurrentConnection()}
+ * object or a wrapper of that request. The {@link AbstractHttpConnection#getCurrentConnection()}
* method can be used access the Response object if required.
* @throws IOException
* @throws ServletException
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java
index 670fa95c81a..abaec917d7e 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java
@@ -22,11 +22,11 @@ import org.eclipse.jetty.io.Buffer;
public class HttpInput extends ServletInputStream
{
- protected final HttpConnection _connection;
+ protected final AbstractHttpConnection _connection;
protected final HttpParser _parser;
/* ------------------------------------------------------------ */
- public HttpInput(HttpConnection connection)
+ public HttpInput(AbstractHttpConnection connection)
{
_connection=connection;
_parser=(HttpParser)connection.getParser();
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
index 6d595877851..7f5d2628b4d 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
@@ -36,7 +36,7 @@ import org.eclipse.jetty.util.ByteArrayOutputStream2;
*/
public class HttpOutput extends ServletOutputStream
{
- protected final HttpConnection _connection;
+ protected final AbstractHttpConnection _connection;
protected final AbstractGenerator _generator;
private boolean _closed;
@@ -47,7 +47,7 @@ public class HttpOutput extends ServletOutputStream
ByteArrayOutputStream2 _bytes;
/* ------------------------------------------------------------ */
- public HttpOutput(HttpConnection connection)
+ public HttpOutput(AbstractHttpConnection connection)
{
_connection=connection;
_generator=(AbstractGenerator)connection.getGenerator();
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java
index d4849acb122..149b1bfbc19 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java
@@ -110,13 +110,14 @@ public class LocalConnector extends AbstractConnector
@Override
public void setConnection(Connection connection)
{
- connectionUpgraded(getConnection(),connection);
+ if (getConnection()!=null && connection!=getConnection())
+ connectionUpgraded(getConnection(),connection);
super.setConnection(connection);
}
};
endPoint.setGrowOutput(true);
- HttpConnection connection = new BlockingHttpConnection(LocalConnector.this, endPoint, getServer());
+ AbstractHttpConnection connection = new BlockingHttpConnection(LocalConnector.this, endPoint, getServer());
endPoint.setConnection(connection);
connectionOpened(connection);
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/NCSARequestLog.java b/jetty-server/src/main/java/org/eclipse/jetty/server/NCSARequestLog.java
index 4382d46cc8d..7a8e8215ca4 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/NCSARequestLog.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/NCSARequestLog.java
@@ -629,7 +629,7 @@ public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
*/
@Override
- protected void doStart() throws Exception
+ protected synchronized void doStart() throws Exception
{
if (_logDateFormat != null)
{
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
index 38f3b460d23..84ec0e24495 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
@@ -96,7 +96,7 @@ import org.eclipse.jetty.util.log.Logger;
* against the servlet URL patterns and {@link Request#setServletPath(String)} called as a result.
*
*
- * A request instance is created for each {@link HttpConnection} accepted by the server
+ * A request instance is created for each {@link AbstractHttpConnection} accepted by the server
* and recycled for each HTTP request received via that connection. An effort is made
* to avoid reparsing headers and cookies that are likely to be the same for
* requests from the same connection.
@@ -116,7 +116,7 @@ public class Request implements HttpServletRequest
if (request instanceof Request)
return (Request) request;
- return HttpConnection.getCurrentConnection().getRequest();
+ return AbstractHttpConnection.getCurrentConnection().getRequest();
}
protected final AsyncContinuation _async = new AsyncContinuation();
private boolean _asyncSupported=true;
@@ -124,7 +124,7 @@ public class Request implements HttpServletRequest
private Authentication _authentication;
private MultiMap _baseParameters;
private String _characterEncoding;
- protected HttpConnection _connection;
+ protected AbstractHttpConnection _connection;
private ContextHandler.Context _context;
private boolean _newContext;
private String _contextPath;
@@ -170,7 +170,7 @@ public class Request implements HttpServletRequest
}
/* ------------------------------------------------------------ */
- public Request(HttpConnection connection)
+ public Request(AbstractHttpConnection connection)
{
setConnection(connection);
}
@@ -382,7 +382,7 @@ public class Request implements HttpServletRequest
/**
* @return Returns the connection.
*/
- public HttpConnection getConnection()
+ public AbstractHttpConnection getConnection()
{
return _connection;
}
@@ -988,6 +988,9 @@ public class Request implements HttpServletRequest
// Return already determined host
if (_serverName != null)
return _serverName;
+
+ if (_uri == null)
+ throw new IllegalStateException("No uri");
// Return host from absolute URI
_serverName = _uri.getHost();
@@ -1466,7 +1469,7 @@ public class Request implements HttpServletRequest
{
try
{
- ((HttpConnection.Output)getServletResponse().getOutputStream()).sendContent(value);
+ ((AbstractHttpConnection.Output)getServletResponse().getOutputStream()).sendContent(value);
}
catch (IOException e)
{
@@ -1483,7 +1486,7 @@ public class Request implements HttpServletRequest
NIOBuffer buffer = byteBuffer.isDirect()
?new DirectNIOBuffer(byteBuffer,true)
:new IndirectNIOBuffer(byteBuffer,true);
- ((HttpConnection.Output)getServletResponse().getOutputStream()).sendResponse(buffer);
+ ((AbstractHttpConnection.Output)getServletResponse().getOutputStream()).sendResponse(buffer);
}
}
catch (IOException e)
@@ -1579,7 +1582,7 @@ public class Request implements HttpServletRequest
/* ------------------------------------------------------------ */
//final so we can safely call this from constructor
- protected final void setConnection(HttpConnection connection)
+ protected final void setConnection(AbstractHttpConnection connection)
{
_connection=connection;
_async.setConnection(connection);
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java
index fb6196a2087..d5fa8321d62 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java
@@ -53,6 +53,7 @@ public class Response implements HttpServletResponse
{
private static final Logger LOG = Log.getLogger(Response.class);
+
public static final int
NONE=0,
STREAM=1,
@@ -65,7 +66,13 @@ public class Response implements HttpServletResponse
*/
public final static String SET_INCLUDE_HEADER_PREFIX = "org.eclipse.jetty.server.include.";
- private final HttpConnection _connection;
+ /**
+ * If this string is found within the comment of a cookie added with {@link #addCookie(Cookie)}, then the cookie
+ * will be set as HTTP ONLY.
+ */
+ public final static String HTTP_ONLY_COMMENT="__HTTP_ONLY__";
+
+ private final AbstractHttpConnection _connection;
private int _status=SC_OK;
private String _reason;
private Locale _locale;
@@ -81,7 +88,7 @@ public class Response implements HttpServletResponse
/**
*
*/
- public Response(HttpConnection connection)
+ public Response(AbstractHttpConnection connection)
{
_connection=connection;
}
@@ -120,14 +127,28 @@ public class Response implements HttpServletResponse
*/
public void addCookie(Cookie cookie)
{
+ String comment=cookie.getComment();
+ boolean http_only=false;
+
+ if (comment!=null)
+ {
+ int i=comment.indexOf(HTTP_ONLY_COMMENT);
+ if (i>=0)
+ {
+ http_only=true;
+ comment=comment.substring(i,i+HTTP_ONLY_COMMENT.length()).trim();
+ if (comment.length()==0)
+ comment=null;
+ }
+ }
_connection.getResponseFields().addSetCookie(cookie.getName(),
cookie.getValue(),
cookie.getDomain(),
cookie.getPath(),
cookie.getMaxAge(),
- cookie.getComment(),
+ comment,
cookie.getSecure(),
- false,//cookie.isHttpOnly(),
+ http_only,// || cookie.isHttpOnly(),
cookie.getVersion());
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java
index 10cfd69efa3..98221fc2a65 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java
@@ -76,6 +76,7 @@ public class Server extends HandlerWrapper implements Attributes
private int _maxCookieVersion=1;
private boolean _dumpAfterStart=false;
private boolean _dumpBeforeStop=false;
+ private boolean _uncheckedPrintWriter=false;
/* ------------------------------------------------------------ */
@@ -333,7 +334,7 @@ public class Server extends HandlerWrapper implements Attributes
* or after the entire request has been received (for short requests of known length), or
* on the dispatch of an async request.
*/
- public void handle(HttpConnection connection) throws IOException, ServletException
+ public void handle(AbstractHttpConnection connection) throws IOException, ServletException
{
final String target=connection.getRequest().getPathInfo();
final Request request=connection.getRequest();
@@ -355,7 +356,7 @@ public class Server extends HandlerWrapper implements Attributes
* or after the entire request has been received (for short requests of known length), or
* on the dispatch of an async request.
*/
- public void handleAsync(HttpConnection connection) throws IOException, ServletException
+ public void handleAsync(AbstractHttpConnection connection) throws IOException, ServletException
{
final AsyncContinuation async = connection.getRequest().getAsyncContinuation();
final AsyncContinuation.AsyncEventState state = async.getAsyncEventState();
@@ -614,6 +615,20 @@ public class Server extends HandlerWrapper implements Attributes
dumpThis(out);
dump(out,indent,TypeUtil.asList(getHandlers()),getBeans(),TypeUtil.asList(_connectors));
}
+
+
+ /* ------------------------------------------------------------ */
+ public boolean isUncheckedPrintWriter()
+ {
+ return _uncheckedPrintWriter;
+ }
+
+ /* ------------------------------------------------------------ */
+ public void setUncheckedPrintWriter(boolean unchecked)
+ {
+ _uncheckedPrintWriter=unchecked;
+ }
+
/* ------------------------------------------------------------ */
/* A handler that can be gracefully shutdown.
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/bio/SocketConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/bio/SocketConnector.java
index 9bff3cfa9ac..28efa1bef72 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/bio/SocketConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/bio/SocketConnector.java
@@ -19,7 +19,6 @@ import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.Set;
import org.eclipse.jetty.http.HttpException;
@@ -30,9 +29,10 @@ import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.io.bio.SocketEndPoint;
import org.eclipse.jetty.server.AbstractConnector;
+import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.BlockingHttpConnection;
-import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.util.component.AggregateLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -156,21 +156,30 @@ public class SocketConnector extends AbstractConnector
protected void doStop() throws Exception
{
super.doStop();
- Set set=null;
-
+ Set set = new HashSet();
synchronized(_connections)
{
- set= new HashSet(_connections);
+ set.addAll(_connections);
}
-
- Iterator iter=set.iterator();
- while(iter.hasNext())
+ for (EndPoint endPoint : set)
{
- ConnectorEndPoint connection = (ConnectorEndPoint)iter.next();
+ ConnectorEndPoint connection = (ConnectorEndPoint)endPoint;
connection.close();
}
}
+ @Override
+ public void dump(Appendable out, String indent) throws IOException
+ {
+ super.dump(out, indent);
+ Set connections = new HashSet();
+ synchronized (_connections)
+ {
+ connections.addAll(_connections);
+ }
+ AggregateLifeCycle.dump(out, indent, connections);
+ }
+
/* ------------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------------- */
@@ -193,7 +202,7 @@ public class SocketConnector extends AbstractConnector
public void setConnection(Connection connection)
{
- if (_connection!=connection)
+ if (_connection!=connection && _connection!=null)
connectionUpgraded(_connection,connection);
_connection=connection;
}
@@ -219,8 +228,8 @@ public class SocketConnector extends AbstractConnector
@Override
public void close() throws IOException
{
- if (_connection instanceof HttpConnection)
- ((HttpConnection)_connection).getRequest().getAsyncContinuation().cancel();
+ if (_connection instanceof AbstractHttpConnection)
+ ((AbstractHttpConnection)_connection).getRequest().getAsyncContinuation().cancel();
super.close();
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ConnectHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ConnectHandler.java
index 47c086b0170..9ddd15bb252 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ConnectHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ConnectHandler.java
@@ -10,21 +10,24 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.http.HttpParser;
+import org.eclipse.jetty.io.AsyncEndPoint;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.ConnectedEndPoint;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.nio.AsyncConnection;
import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
import org.eclipse.jetty.io.nio.SelectorManager;
+import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.HostMap;
@@ -32,7 +35,6 @@ import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.ThreadPool;
/**
@@ -231,7 +233,7 @@ public class ConnectHandler extends HandlerWrapper
// 1. when this unread data is written and the server replies before the clientToProxy
// connection is installed (it is only installed after returning from this method)
// 2. when the client sends data before this unread data has been written.
- HttpConnection httpConnection = HttpConnection.getCurrentConnection();
+ AbstractHttpConnection httpConnection = AbstractHttpConnection.getCurrentConnection();
Buffer headerBuffer = ((HttpParser)httpConnection.getParser()).getHeaderBuffer();
Buffer bodyBuffer = ((HttpParser)httpConnection.getParser()).getBodyBuffer();
int length = headerBuffer == null ? 0 : headerBuffer.length();
@@ -271,7 +273,7 @@ public class ConnectHandler extends HandlerWrapper
private ClientToProxyConnection prepareConnections(ConcurrentMap context, SocketChannel channel, Buffer buffer)
{
- HttpConnection httpConnection = HttpConnection.getCurrentConnection();
+ AbstractHttpConnection httpConnection = AbstractHttpConnection.getCurrentConnection();
ProxyToServerConnection proxyToServer = newProxyToServerConnection(context, buffer);
ClientToProxyConnection clientToProxy = newClientToProxyConnection(context, channel, httpConnection.getEndPoint(), httpConnection.getTimeStamp());
clientToProxy.setConnection(proxyToServer);
@@ -421,17 +423,18 @@ public class ConnectHandler extends HandlerWrapper
private class Manager extends SelectorManager
{
@Override
- protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey selectionKey) throws IOException
+ protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key) throws IOException
{
- SelectChannelEndPoint endp = new SelectChannelEndPoint(channel, selectSet, selectionKey);
+ SelectChannelEndPoint endp = new SelectChannelEndPoint(channel, selectSet, key, channel.socket().getSoTimeout());
+ endp.setConnection(selectSet.getManager().newConnection(channel,endp, key.attachment()));
endp.setMaxIdleTime(_writeTimeout);
return endp;
}
@Override
- protected Connection newConnection(SocketChannel channel, SelectChannelEndPoint endpoint)
+ public AsyncConnection newConnection(SocketChannel channel, AsyncEndPoint endpoint, Object attachment)
{
- ProxyToServerConnection proxyToServer = (ProxyToServerConnection)endpoint.getSelectionKey().attachment();
+ ProxyToServerConnection proxyToServer = (ProxyToServerConnection)attachment;
proxyToServer.setTimeStamp(System.currentTimeMillis());
proxyToServer.setEndPoint(endpoint);
return proxyToServer;
@@ -461,7 +464,9 @@ public class ConnectHandler extends HandlerWrapper
}
}
- public class ProxyToServerConnection implements Connection
+
+
+ public class ProxyToServerConnection implements AsyncConnection
{
private final CountDownLatch _ready = new CountDownLatch(1);
private final Buffer _buffer = new IndirectNIOBuffer(1024);
@@ -469,7 +474,7 @@ public class ConnectHandler extends HandlerWrapper
private volatile Buffer _data;
private volatile ClientToProxyConnection _toClient;
private volatile long _timestamp;
- private volatile SelectChannelEndPoint _endPoint;
+ private volatile AsyncEndPoint _endPoint;
public ProxyToServerConnection(ConcurrentMap context, Buffer data)
{
@@ -541,6 +546,11 @@ public class ConnectHandler extends HandlerWrapper
}
}
+ public void onInputShutdown() throws IOException
+ {
+ // TODO
+ }
+
private void writeData() throws IOException
{
// This method is called from handle() and closeServer()
@@ -581,7 +591,7 @@ public class ConnectHandler extends HandlerWrapper
_timestamp = timestamp;
}
- public void setEndPoint(SelectChannelEndPoint endpoint)
+ public void setEndPoint(AsyncEndPoint endpoint)
{
_endPoint = endpoint;
}
@@ -596,7 +606,7 @@ public class ConnectHandler extends HandlerWrapper
return false;
}
- public void closed()
+ public void onClose()
{
}
@@ -657,7 +667,7 @@ public class ConnectHandler extends HandlerWrapper
_endPoint.shutdownOutput();
}
- public void idleExpired()
+ public void onIdleExpired(long idleForMs)
{
try
{
@@ -671,7 +681,7 @@ public class ConnectHandler extends HandlerWrapper
}
}
- public class ClientToProxyConnection implements Connection
+ public class ClientToProxyConnection implements AsyncConnection
{
private final Buffer _buffer = new IndirectNIOBuffer(1024);
private final ConcurrentMap _context;
@@ -758,6 +768,11 @@ public class ConnectHandler extends HandlerWrapper
_logger.debug("{}: end reading from client", this);
}
}
+
+ public void onInputShutdown() throws IOException
+ {
+ // TODO
+ }
public long getTimeStamp()
{
@@ -774,7 +789,7 @@ public class ConnectHandler extends HandlerWrapper
return false;
}
- public void closed()
+ public void onClose()
{
}
@@ -819,7 +834,7 @@ public class ConnectHandler extends HandlerWrapper
_endPoint.shutdownOutput();
}
- public void idleExpired()
+ public void onIdleExpired(long idleForMs)
{
try
{
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
index 46554a844bc..8af31771943 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
@@ -48,11 +48,11 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpException;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Dispatcher;
import org.eclipse.jetty.server.DispatcherType;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HandlerContainer;
-import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.Attributes;
@@ -65,7 +65,6 @@ import org.eclipse.jetty.util.component.AggregateLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
/* ------------------------------------------------------------ */
@@ -264,6 +263,85 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
}
+ /* ------------------------------------------------------------ */
+ /** Either set virtual hosts or add to an existing set of virtual hosts.
+ *
+ * @param virtualHosts
+ * Array of virtual hosts that this context responds to. A null host name or null/empty array means any hostname is acceptable. Host names may be
+ * String representation of IP addresses. Host names may start with '*.' to wildcard one level of names.
+ */
+ public void addVirtualHosts(String[] virtualHosts)
+ {
+ if (virtualHosts == null) // since this is add, we don't null the old ones
+ {
+ return;
+ }
+ else
+ {
+ List currentVirtualHosts = null;
+ if (_vhosts != null)
+ {
+ currentVirtualHosts = new ArrayList(Arrays.asList(_vhosts));
+ }
+ else
+ {
+ currentVirtualHosts = new ArrayList();
+ }
+
+ for (int i = 0; i < virtualHosts.length; i++)
+ {
+ String normVhost = normalizeHostname(virtualHosts[i]);
+ if (!currentVirtualHosts.contains(normVhost))
+ {
+ currentVirtualHosts.add(normVhost);
+ }
+ }
+ _vhosts = currentVirtualHosts.toArray(new String[0]);
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Removes an array of virtual host entries, if this removes all entries the _vhosts will be set to null
+ *
+ * @param virtualHosts
+ * Array of virtual hosts that this context responds to. A null host name or null/empty array means any hostname is acceptable. Host names may be
+ * String representation of IP addresses. Host names may start with '*.' to wildcard one level of names.
+ */
+ public void removeVirtualHosts(String[] virtualHosts)
+ {
+ if (virtualHosts == null)
+ {
+ return; // do nothing
+ }
+ else if ( _vhosts == null || _vhosts.length == 0)
+ {
+ return; // do nothing
+ }
+ else
+ {
+ List existingVirtualHosts = new ArrayList(Arrays.asList(_vhosts));
+
+ for (int i = 0; i < virtualHosts.length; i++)
+ {
+ String toRemoveVirtualHost = normalizeHostname(virtualHosts[i]);
+ if (existingVirtualHosts.contains(toRemoveVirtualHost))
+ {
+ existingVirtualHosts.remove(toRemoveVirtualHost);
+ }
+ }
+
+ if (existingVirtualHosts.isEmpty())
+ {
+ _vhosts = null; // if we ended up removing them all, just null out _vhosts
+ }
+ else
+ {
+ _vhosts = existingVirtualHosts.toArray(new String[0]);
+ }
+ }
+ }
+
/* ------------------------------------------------------------ */
/**
* Get the virtual hosts for the context. Only requests that have a matching host header or fully qualified URL will be passed to that context with a
@@ -498,7 +576,10 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
*/
public boolean isShutdown()
{
- return !_shutdown;
+ synchronized (this)
+ {
+ return !_shutdown;
+ }
}
/* ------------------------------------------------------------ */
@@ -524,7 +605,10 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
*/
public boolean isAvailable()
{
- return _available;
+ synchronized (this)
+ {
+ return _available;
+ }
}
/* ------------------------------------------------------------ */
@@ -588,7 +672,10 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
// defers the calling of super.doStart()
startContext();
- _availability = _shutdown?__SHUTDOWN:_available?__AVAILABLE:__UNAVAILABLE;
+ synchronized(this)
+ {
+ _availability = _shutdown?__SHUTDOWN:_available?__AVAILABLE:__UNAVAILABLE;
+ }
}
finally
{
@@ -755,7 +842,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
// Check the connector
if (_connectors != null && _connectors.size() > 0)
{
- String connector = HttpConnection.getCurrentConnection().getConnector().getName();
+ String connector = AbstractHttpConnection.getCurrentConnection().getConnector().getName();
if (connector == null || !_connectors.contains(connector))
return false;
}
@@ -793,7 +880,8 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
@Override
public void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
- LOG.debug("scope {} @ {}",baseRequest.getContextPath() + "|" + baseRequest.getServletPath() + "|" + baseRequest.getPathInfo(),this);
+ if (LOG.isDebugEnabled())
+ LOG.debug("scope {}|{}|{} @ {}",baseRequest.getContextPath(),baseRequest.getServletPath(),baseRequest.getPathInfo(),this);
Context old_context = null;
String old_context_path = null;
@@ -865,7 +953,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
if (LOG.isDebugEnabled())
- LOG.debug("context={} @ {}",baseRequest.getContextPath() + "|" + baseRequest.getServletPath() + "|" + baseRequest.getPathInfo(),this);
+ LOG.debug("context={}|{}|{} @ {}",baseRequest.getContextPath(),baseRequest.getServletPath(), baseRequest.getPathInfo(),this);
// start manual inline of nextScope(target,baseRequest,request,response);
if (never())
@@ -1699,7 +1787,8 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
URL url = getResource(path);
if (url == null)
return null;
- return url.openStream();
+ Resource r = Resource.newResource(url);
+ return r.getInputStream();
}
catch (Exception e)
{
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java
index 5f424466636..6ac3dcc2ff2 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java
@@ -29,9 +29,9 @@ import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.ByteArrayISO8859Writer;
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.Logger;
+import org.eclipse.jetty.util.resource.Resource;
/* ------------------------------------------------------------ */
@@ -61,7 +61,10 @@ public class DefaultHandler extends AbstractHandler
{
URL fav = this.getClass().getClassLoader().getResource("org/eclipse/jetty/favicon.ico");
if (fav!=null)
- _favicon=IO.readBytes(fav.openStream());
+ {
+ Resource r = Resource.newResource(fav);
+ _favicon=IO.readBytes(r.getInputStream());
+ }
}
catch(Exception e)
{
@@ -110,10 +113,6 @@ public class DefaultHandler extends AbstractHandler
response.setContentType(MimeTypes.TEXT_HTML);
ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer(1500);
-
- String uri=request.getRequestURI();
- uri=StringUtil.replace(uri,"<","<");
- uri=StringUtil.replace(uri,">",">");
writer.write("\n\nError 404 - Not Found");
writer.write(" \n\nError 404 - Not Found. \n");
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java
index 6a422e9be84..b43e34b9cef 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java
@@ -23,7 +23,7 @@ import org.eclipse.jetty.http.HttpHeaders;
import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.MimeTypes;
-import org.eclipse.jetty.server.HttpConnection;
+import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.ByteArrayISO8859Writer;
@@ -45,7 +45,7 @@ public class ErrorHandler extends AbstractHandler
*/
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
{
- HttpConnection connection = HttpConnection.getCurrentConnection();
+ AbstractHttpConnection connection = AbstractHttpConnection.getCurrentConnection();
connection.getRequest().setHandled(true);
String method = request.getMethod();
if(!method.equals(HttpMethods.GET) && !method.equals(HttpMethods.POST) && !method.equals(HttpMethods.HEAD))
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/GzipHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/GzipHandler.java
index 29a9a833932..81198f5299d 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/GzipHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/GzipHandler.java
@@ -281,9 +281,9 @@ public class GzipHandler extends HandlerWrapper
return new GzipResponseWrapper(request, response)
{
{
- setMimeTypes(GzipHandler.this._mimeTypes);
- setBufferSize(GzipHandler.this._bufferSize);
- setMinGzipSize(GzipHandler.this._minGzipSize);
+ super.setMimeTypes(GzipHandler.this._mimeTypes);
+ super.setBufferSize(GzipHandler.this._bufferSize);
+ super.setMinGzipSize(GzipHandler.this._minGzipSize);
}
@Override
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerWrapper.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerWrapper.java
index 2d597ed5c30..de8c0e4a2e0 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerWrapper.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerWrapper.java
@@ -14,6 +14,7 @@
package org.eclipse.jetty.server.handler;
import java.io.IOException;
+
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/IPAccessHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/IPAccessHandler.java
index 060e3288323..4e6e50b52c6 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/IPAccessHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/IPAccessHandler.java
@@ -25,7 +25,7 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.PathMap;
import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.server.HttpConnection;
+import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.IPAddressMap;
import org.eclipse.jetty.util.log.Log;
@@ -179,7 +179,7 @@ public class IPAccessHandler extends HandlerWrapper
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
// Get the real remote IP (not the one set by the forwarded headers (which may be forged))
- HttpConnection connection = baseRequest.getConnection();
+ AbstractHttpConnection connection = baseRequest.getConnection();
if (connection!=null)
{
EndPoint endp=connection.getEndPoint();
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/MovedContextHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/MovedContextHandler.java
index 8650b80c9a1..6ff990c9c04 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/MovedContextHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/MovedContextHandler.java
@@ -100,12 +100,6 @@ public class MovedContextHandler extends ContextHandler
{
if (_newContextURL==null)
return;
-
- String url = _newContextURL;
- if (!_discardPathInfo && request.getPathInfo()!=null)
- url=URIUtil.addPaths(url, request.getPathInfo());
- if (!_discardQuery && request.getQueryString()!=null)
- url+="?"+request.getQueryString();
String path=_newContextURL;
if (!_discardPathInfo && request.getPathInfo()!=null)
@@ -117,7 +111,9 @@ public class MovedContextHandler extends ContextHandler
if (!_discardQuery && request.getQueryString()!=null)
{
location.append('?');
- location.append(request.getQueryString());
+ String q=request.getQueryString();
+ q=q.replaceAll("\r\n?&=","!");
+ location.append(q);
}
response.setHeader(HttpHeaders.LOCATION,location.toString());
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java
index 04a6ff9566e..f4978c67494 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java
@@ -29,8 +29,8 @@ import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.WriterOutputStream;
+import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Dispatcher;
-import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.handler.ContextHandler.Context;
@@ -51,7 +51,7 @@ import org.eclipse.jetty.util.resource.Resource;
*
* @org.apache.xbean.XBean
*/
-public class ResourceHandler extends AbstractHandler
+public class ResourceHandler extends HandlerWrapper
{
private static final Logger LOG = Log.getLogger(ResourceHandler.class);
@@ -309,7 +309,6 @@ public class ResourceHandler extends AbstractHandler
}
else
{
- included = Boolean.FALSE;
servletPath = request.getServletPath();
pathInfo = request.getPathInfo();
}
@@ -359,6 +358,8 @@ public class ResourceHandler extends AbstractHandler
{
if(!HttpMethods.HEAD.equals(request.getMethod()))
{
+ //try another handler
+ super.handle(target, baseRequest, request, response);
return;
}
skipContentBody = true;
@@ -369,12 +370,18 @@ public class ResourceHandler extends AbstractHandler
if (resource==null || !resource.exists())
{
if (target.endsWith("/jetty-dir.css"))
- {
- response.setContentType("text/css");
+ {
resource = getStylesheet();
+ if (resource==null)
+ return;
+ response.setContentType("text/css");
}
else
+ {
+ //no resource - try other handlers
+ super.handle(target, baseRequest, request, response);
return;
+ }
}
if (!_aliases && resource.getAlias()!=null)
@@ -432,10 +439,10 @@ public class ResourceHandler extends AbstractHandler
catch(IllegalStateException e) {out = new WriterOutputStream(response.getWriter());}
// See if a short direct method can be used?
- if (out instanceof HttpConnection.Output)
+ if (out instanceof AbstractHttpConnection.Output)
{
// TODO file mapped buffers
- ((HttpConnection.Output)out).sendContent(resource.getInputStream());
+ ((AbstractHttpConnection.Output)out).sendContent(resource.getInputStream());
}
else
{
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ShutdownHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ShutdownHandler.java
index 701d774b557..aa4edeb7f61 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ShutdownHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ShutdownHandler.java
@@ -68,6 +68,8 @@ public class ShutdownHandler extends AbstractHandler
private final Server _server;
private boolean _exitJvm = false;
+
+
/**
* Creates a listener that lets the server be shut down remotely (but only from localhost).
@@ -110,14 +112,24 @@ public class ShutdownHandler extends AbstractHandler
LOG.info("Shutting down by request from " + getRemoteAddr(request));
- try
+ new Thread()
{
- shutdownServer();
- }
- catch (Exception e)
- {
- throw new RuntimeException("Shutting down server",e);
- }
+ public void run ()
+ {
+ try
+ {
+ shutdownServer();
+ }
+ catch (InterruptedException e)
+ {
+ LOG.ignore(e);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Shutting down server",e);
+ }
+ }
+ }.start();
}
private boolean requestFromLocalhost(HttpServletRequest request)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/BlockingChannelConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/BlockingChannelConnector.java
index 69639a9d631..98716285b71 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/BlockingChannelConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/BlockingChannelConnector.java
@@ -4,13 +4,13 @@
// 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.server.nio;
import java.io.IOException;
@@ -29,7 +29,6 @@ import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.io.nio.ChannelEndPoint;
import org.eclipse.jetty.server.BlockingHttpConnection;
-import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.ConcurrentHashSet;
import org.eclipse.jetty.util.log.Log;
@@ -40,25 +39,25 @@ import org.eclipse.jetty.util.log.Logger;
/** Blocking NIO connector.
* This connector uses efficient NIO buffers with a traditional blocking thread model.
* Direct NIO buffers are used and a thread is allocated per connections.
- *
+ *
* This connector is best used when there are a few very active connections.
- *
+ *
* @org.apache.xbean.XBean element="blockingNioConnector" description="Creates a blocking NIO based socket connector"
- *
- *
+ *
+ *
*
*/
-public class BlockingChannelConnector extends AbstractNIOConnector
+public class BlockingChannelConnector extends AbstractNIOConnector
{
private static final Logger LOG = Log.getLogger(BlockingChannelConnector.class);
private transient ServerSocketChannel _acceptChannel;
private final Set _endpoints = new ConcurrentHashSet();
-
-
+
+
/* ------------------------------------------------------------ */
/** Constructor.
- *
+ *
*/
public BlockingChannelConnector()
{
@@ -104,12 +103,12 @@ public class BlockingChannelConnector extends AbstractNIOConnector
}
}
}
-
+
});
-
+
}
-
+
/* ------------------------------------------------------------ */
public void open() throws IOException
{
@@ -129,12 +128,12 @@ public class BlockingChannelConnector extends AbstractNIOConnector
_acceptChannel.close();
_acceptChannel=null;
}
-
+
/* ------------------------------------------------------------ */
@Override
public void accept(int acceptorID)
throws IOException, InterruptedException
- {
+ {
SocketChannel channel = _acceptChannel.accept();
channel.configureBlocking(true);
Socket socket=channel.socket();
@@ -143,7 +142,7 @@ public class BlockingChannelConnector extends AbstractNIOConnector
BlockingChannelEndPoint connection=new BlockingChannelEndPoint(channel);
connection.dispatch();
}
-
+
/* ------------------------------------------------------------------------------- */
@Override
public void customize(EndPoint endpoint, Request request)
@@ -162,7 +161,7 @@ public class BlockingChannelConnector extends AbstractNIOConnector
return -1;
return _acceptChannel.socket().getLocalPort();
}
-
+
/* ------------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------------- */
@@ -171,14 +170,14 @@ public class BlockingChannelConnector extends AbstractNIOConnector
private Connection _connection;
private int _timeout;
private volatile long _idleTimestamp;
-
- BlockingChannelEndPoint(ByteChannel channel)
+
+ BlockingChannelEndPoint(ByteChannel channel)
throws IOException
{
super(channel,BlockingChannelConnector.this._maxIdleTime);
_connection = new BlockingHttpConnection(BlockingChannelConnector.this,this,getServer());
}
-
+
/* ------------------------------------------------------------ */
/** Get the connection.
* @return the connection
@@ -187,7 +186,7 @@ public class BlockingChannelConnector extends AbstractNIOConnector
{
return _connection;
}
-
+
/* ------------------------------------------------------------ */
public void setConnection(Connection connection)
{
@@ -208,24 +207,24 @@ public class BlockingChannelConnector extends AbstractNIOConnector
{
try
{
- close();
+ super.close();
}
catch (IOException e)
{
LOG.ignore(e);
}
}
-
+
/* ------------------------------------------------------------ */
void dispatch() throws IOException
{
if (!getThreadPool().dispatch(this))
{
LOG.warn("dispatch failed for {}",_connection);
- BlockingChannelEndPoint.this.close();
+ super.close();
}
}
-
+
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.io.nio.ChannelEndPoint#fill(org.eclipse.jetty.io.Buffer)
@@ -289,9 +288,9 @@ public class BlockingChannelConnector extends AbstractNIOConnector
_timeout=getMaxIdleTime();
}
}
-
+
_connection = _connection.handle();
-
+
}
}
catch (EofException e)
@@ -303,27 +302,27 @@ public class BlockingChannelConnector extends AbstractNIOConnector
catch (HttpException e)
{
LOG.debug("BAD", e);
- try{BlockingChannelEndPoint.this.close();}
+ try{super.close();}
catch(IOException e2){LOG.ignore(e2);}
}
catch(Throwable e)
{
LOG.warn("handle failed",e);
- try{BlockingChannelEndPoint.this.close();}
+ try{super.close();}
catch(IOException e2){LOG.ignore(e2);}
}
finally
{
connectionClosed(_connection);
_endpoints.remove(this);
-
+
// wait for client to close, but if not, close ourselves.
try
{
if (!_socket.isClosed())
{
long timestamp=System.currentTimeMillis();
- int max_idle=getMaxIdleTime();
+ int max_idle=getMaxIdleTime();
_socket.setSoTimeout(getMaxIdleTime());
int c=0;
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/NetworkTrafficSelectChannelConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/NetworkTrafficSelectChannelConnector.java
index efea044745b..072de4cf778 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/NetworkTrafficSelectChannelConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/NetworkTrafficSelectChannelConnector.java
@@ -54,6 +54,7 @@ public class NetworkTrafficSelectChannelConnector extends SelectChannelConnector
protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectorManager.SelectSet selectSet, SelectionKey key) throws IOException
{
NetworkTrafficSelectChannelEndPoint endPoint = new NetworkTrafficSelectChannelEndPoint(channel, selectSet, key, _maxIdleTime, listeners);
+ endPoint.setConnection(selectSet.getManager().newConnection(channel,endPoint, key.attachment()));
endPoint.notifyOpened();
return endPoint;
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java
index b6c73f478a5..998dc76638d 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java
@@ -22,22 +22,20 @@ import java.nio.channels.SocketChannel;
import java.util.Arrays;
import org.eclipse.jetty.continuation.Continuation;
+import org.eclipse.jetty.io.AsyncEndPoint;
import org.eclipse.jetty.io.ConnectedEndPoint;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.nio.AsyncConnection;
import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
import org.eclipse.jetty.io.nio.SelectorManager;
import org.eclipse.jetty.io.nio.SelectorManager.SelectSet;
import org.eclipse.jetty.server.AsyncHttpConnection;
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.component.AggregateLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.ThreadPool;
-import org.eclipse.jetty.util.thread.Timeout.Task;
/* ------------------------------------------------------------------------------- */
/**
@@ -91,10 +89,15 @@ public class SelectChannelConnector extends AbstractNIOConnector
@Override
public void accept(int acceptorID) throws IOException
{
- ServerSocketChannel server = _acceptChannel;
- if (server!=null && server.isOpen())
+ ServerSocketChannel server;
+ synchronized(this)
{
- SocketChannel channel = _acceptChannel.accept();
+ server = _acceptChannel;
+ }
+
+ if (server!=null && server.isOpen() && _manager.isStarted())
+ {
+ SocketChannel channel = server.accept();
channel.configureBlocking(false);
Socket socket = channel.socket();
configure(socket);
@@ -118,9 +121,9 @@ public class SelectChannelConnector extends AbstractNIOConnector
@Override
public void customize(EndPoint endpoint, Request request) throws IOException
{
- SelectChannelEndPoint cep = ((SelectChannelEndPoint)endpoint);
- cep.cancelIdle();
- request.setTimeStamp(cep.getSelectSet().getNow());
+ AsyncEndPoint aEndp = ((AsyncEndPoint)endpoint);
+ aEndp.setCheckForIdle(false);
+ request.setTimeStamp(System.currentTimeMillis());
endpoint.setMaxIdleTime(_maxIdleTime);
super.customize(endpoint, request);
}
@@ -129,7 +132,8 @@ public class SelectChannelConnector extends AbstractNIOConnector
@Override
public void persist(EndPoint endpoint) throws IOException
{
- ((SelectChannelEndPoint)endpoint).scheduleIdle();
+ AsyncEndPoint aEndp = ((AsyncEndPoint)endpoint);
+ aEndp.setCheckForIdle(true);
super.persist(endpoint);
}
@@ -138,9 +142,9 @@ public class SelectChannelConnector extends AbstractNIOConnector
{
return _manager;
}
-
+
/* ------------------------------------------------------------ */
- public Object getConnection()
+ public synchronized Object getConnection()
{
return _acceptChannel;
}
@@ -277,7 +281,9 @@ public class SelectChannelConnector extends AbstractNIOConnector
/* ------------------------------------------------------------ */
protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key) throws IOException
{
- return new SelectChannelEndPoint(channel,selectSet,key, SelectChannelConnector.this._maxIdleTime);
+ SelectChannelEndPoint endp= new SelectChannelEndPoint(channel,selectSet,key, SelectChannelConnector.this._maxIdleTime);
+ endp.setConnection(selectSet.getManager().newConnection(channel,endp, key.attachment()));
+ return endp;
}
/* ------------------------------------------------------------------------------- */
@@ -287,48 +293,24 @@ public class SelectChannelConnector extends AbstractNIOConnector
}
/* ------------------------------------------------------------------------------- */
- protected Connection newConnection(SocketChannel channel,final SelectChannelEndPoint endpoint)
+ protected AsyncConnection newConnection(SocketChannel channel,final AsyncEndPoint endpoint)
{
- return new SelectChannelHttpConnection(SelectChannelConnector.this,endpoint,getServer(),endpoint);
+ return new AsyncHttpConnection(SelectChannelConnector.this,endpoint,getServer());
}
/* ------------------------------------------------------------ */
public void dump(Appendable out, String indent) throws IOException
{
- out.append(String.valueOf(this)).append("\n");
- ServerSocketChannel channel=_acceptChannel;
+ super.dump(out, indent);
+ ServerSocketChannel channel;
+ synchronized (this)
+ {
+ channel=_acceptChannel;
+ }
if (channel==null)
- AggregateLifeCycle.dump(out,indent,Arrays.asList(new Object[]{null,"CLOSED",_manager}));
+ AggregateLifeCycle.dump(out,indent,Arrays.asList(null,"CLOSED",_manager));
else
- AggregateLifeCycle.dump(out,indent,Arrays.asList(new Object[]{_acceptChannel,_acceptChannel.isOpen()?"OPEN":"CLOSED",_manager}));
- }
-
- /* ------------------------------------------------------------ */
- /* ------------------------------------------------------------ */
- /* ------------------------------------------------------------ */
- private class SelectChannelHttpConnection extends AsyncHttpConnection
- {
- private final SelectChannelEndPoint _endpoint;
-
- private SelectChannelHttpConnection(Connector connector, EndPoint endpoint, Server server, SelectChannelEndPoint endpoint2)
- {
- super(connector,endpoint,server);
- _endpoint = endpoint2;
- }
-
- /* ------------------------------------------------------------ */
- @Override
- public void cancelTimeout(Task task)
- {
- _endpoint.getSelectSet().cancelTimeout(task);
- }
-
- /* ------------------------------------------------------------ */
- @Override
- public void scheduleTimeout(Task task, long timeoutMs)
- {
- _endpoint.getSelectSet().scheduleTimeout(task,timeoutMs);
- }
+ AggregateLifeCycle.dump(out,indent,Arrays.asList(channel,channel.isOpen()?"OPEN":"CLOSED",_manager));
}
/* ------------------------------------------------------------ */
@@ -365,7 +347,7 @@ public class SelectChannelConnector extends AbstractNIOConnector
}
@Override
- protected Connection newConnection(SocketChannel channel,SelectChannelEndPoint endpoint)
+ public AsyncConnection newConnection(SocketChannel channel,AsyncEndPoint endpoint, Object attachment)
{
return SelectChannelConnector.this.newConnection(channel,endpoint);
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSession.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSession.java
index 8712f766a59..73a4b6f81b8 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSession.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSession.java
@@ -30,7 +30,7 @@ import org.eclipse.jetty.util.log.Logger;
@SuppressWarnings("deprecation")
public abstract class AbstractSession implements AbstractSessionManager.SessionIf
{
- final static Logger __log = SessionHandler.__log;
+ final static Logger LOG = SessionHandler.LOG;
private final AbstractSessionManager _manager;
private final String _clusterId; // ID unique within cluster
@@ -63,7 +63,8 @@ public abstract class AbstractSession implements AbstractSessionManager.SessionI
_lastAccessed=_created;
_requests=1;
_maxIdleMs=_manager._dftMaxIdleSecs>0?_manager._dftMaxIdleSecs*1000:-1;
- __log.debug("new session & id "+_nodeId+" "+_clusterId);
+ if (LOG.isDebugEnabled())
+ LOG.debug("new session & id "+_nodeId+" "+_clusterId);
}
/* ------------------------------------------------------------- */
@@ -76,7 +77,8 @@ public abstract class AbstractSession implements AbstractSessionManager.SessionI
_accessed=accessed;
_lastAccessed=accessed;
_requests=1;
- __log.debug("new session "+_nodeId+" "+_clusterId);
+ if (LOG.isDebugEnabled())
+ LOG.debug("new session "+_nodeId+" "+_clusterId);
}
/* ------------------------------------------------------------- */
@@ -300,7 +302,7 @@ public abstract class AbstractSession implements AbstractSessionManager.SessionI
{
try
{
- __log.debug("invalidate ",_clusterId);
+ LOG.debug("invalidate {}",_clusterId);
if (isValid())
clearAttributes();
}
@@ -455,7 +457,10 @@ public abstract class AbstractSession implements AbstractSessionManager.SessionI
/* ------------------------------------------------------------- */
protected void cookieSet()
{
- _cookieSet=_accessed;
+ synchronized (this)
+ {
+ _cookieSet=_accessed;
+ }
}
/* ------------------------------------------------------------ */
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionIdManager.java
index d0c53610c5b..d93fc79c694 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionIdManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionIdManager.java
@@ -78,7 +78,7 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme
}
/* ------------------------------------------------------------ */
- public void setRandom(Random random)
+ public synchronized void setRandom(Random random)
{
_random=random;
_weakRandom=false;
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionManager.java
index 60d1f3de713..b6c1a381668 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionManager.java
@@ -56,7 +56,7 @@ import org.eclipse.jetty.util.statistic.SampleStatistic;
@SuppressWarnings("deprecation")
public abstract class AbstractSessionManager extends AbstractLifeCycle implements SessionManager
{
- final static Logger __log = SessionHandler.__log;
+ final static Logger __log = SessionHandler.LOG;
/* ------------------------------------------------------------ */
public final static int __distantFuture=60*60*24*7*52*20;
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java
index c015eb283f0..3b59213b516 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java
@@ -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.server.session;
@@ -42,12 +42,12 @@ import org.eclipse.jetty.util.log.Logger;
*
* This manager will create it's own Timer instance to scavenge threads, unless it discovers a shared Timer instance
* set as the "org.eclipse.jetty.server.session.timer" attribute of the ContextHandler.
- *
+ *
*/
public class HashSessionManager extends AbstractSessionManager
{
- final static Logger __log = SessionHandler.__log;
-
+ final static Logger __log = SessionHandler.LOG;
+
protected final ConcurrentMap _sessions=new ConcurrentHashMap();
private static int __id;
private Timer _timer;
@@ -60,7 +60,7 @@ public class HashSessionManager extends AbstractSessionManager
File _storeDir;
private boolean _lazyLoad=false;
private volatile boolean _sessionsLoaded=false;
-
+
/* ------------------------------------------------------------ */
public HashSessionManager()
{
@@ -85,7 +85,7 @@ public class HashSessionManager extends AbstractSessionManager
_timerStop=true;
_timer=new Timer("HashSessionScavenger-"+__id++, true);
}
-
+
setScavengePeriod(getScavengePeriod());
if (_storeDir!=null)
@@ -96,7 +96,7 @@ public class HashSessionManager extends AbstractSessionManager
if (!_lazyLoad)
restoreSessions();
}
-
+
setSavePeriod(getSavePeriod());
}
@@ -106,7 +106,7 @@ public class HashSessionManager extends AbstractSessionManager
*/
@Override
public void doStop() throws Exception
- {
+ {
// stop the scavengers
synchronized(this)
{
@@ -120,16 +120,16 @@ public class HashSessionManager extends AbstractSessionManager
_timer.cancel();
_timer=null;
}
-
- // This will callback invalidate sessions - where we decide if we will save
+
+ // This will callback invalidate sessions - where we decide if we will save
super.doStop();
-
+
_sessions.clear();
}
/* ------------------------------------------------------------ */
- /**
+ /**
* @return the period in seconds at which a check is made for sessions to be invalidated.
*/
public int getScavengePeriod()
@@ -153,7 +153,7 @@ public class HashSessionManager extends AbstractSessionManager
/* ------------------------------------------------------------ */
/**
- * @return seconds Idle period after which a session is saved
+ * @return seconds Idle period after which a session is saved
*/
public int getIdleSavePeriod()
{
@@ -162,15 +162,15 @@ public class HashSessionManager extends AbstractSessionManager
return _idleSavePeriodMs / 1000;
}
-
+
/* ------------------------------------------------------------ */
/**
- * Configures the period in seconds after which a session is deemed idle and saved
- * to save on session memory.
- *
- * The session is persisted, the values attribute map is cleared and the session set to idled.
- *
- * @param seconds Idle period after which a session is saved
+ * Configures the period in seconds after which a session is deemed idle and saved
+ * to save on session memory.
+ *
+ * The session is persisted, the values attribute map is cleared and the session set to idled.
+ *
+ * @param seconds Idle period after which a session is saved
*/
public void setIdleSavePeriod(int seconds)
{
@@ -196,7 +196,7 @@ public class HashSessionManager extends AbstractSessionManager
if (period < 0)
period=0;
_savePeriodMs=period;
-
+
if (_timer!=null)
{
synchronized (this)
@@ -218,7 +218,7 @@ public class HashSessionManager extends AbstractSessionManager
{
__log.warn(e);
}
- }
+ }
};
_timer.schedule(_saveTask,_savePeriodMs,_savePeriodMs);
}
@@ -234,10 +234,10 @@ public class HashSessionManager extends AbstractSessionManager
{
if (_savePeriodMs<=0)
return 0;
-
+
return _savePeriodMs/1000;
}
-
+
/* ------------------------------------------------------------ */
/**
* @param seconds the period in seconds at which a check is made for sessions to be invalidated.
@@ -267,13 +267,13 @@ public class HashSessionManager extends AbstractSessionManager
public void run()
{
scavenge();
- }
+ }
};
_timer.schedule(_task,_scavengePeriodMs,_scavengePeriodMs);
}
}
}
-
+
/* -------------------------------------------------------------- */
/**
* Find sessions that have timed out and invalidate them. This runs in the
@@ -284,14 +284,14 @@ public class HashSessionManager extends AbstractSessionManager
//don't attempt to scavenge if we are shutting down
if (isStopping() || isStopped())
return;
-
+
Thread thread=Thread.currentThread();
ClassLoader old_loader=thread.getContextClassLoader();
try
{
if (_loader!=null)
thread.setContextClassLoader(_loader);
-
+
// For each session
long now=System.currentTimeMillis();
for (Iterator i=_sessions.values().iterator(); i.hasNext();)
@@ -305,23 +305,20 @@ public class HashSessionManager extends AbstractSessionManager
}
else if (_idleSavePeriodMs>0&&session.getAccessed()+_idleSavePeriodMs sessions=_sessions;
if (sessions==null)
return null;
-
+
HashedSession session = sessions.get(idInCluster);
if (session == null && _lazyLoad)
@@ -359,7 +356,7 @@ public class HashSessionManager extends AbstractSessionManager
if (_idleSavePeriodMs!=0)
session.deIdle();
-
+
return session;
}
@@ -387,7 +384,7 @@ public class HashSessionManager extends AbstractSessionManager
for (HashedSession session : sessions)
session.invalidate();
}
-
+
// check that no new sessions were created while we were iterating
sessions=new ArrayList(_sessions.values());
}
@@ -399,13 +396,13 @@ public class HashSessionManager extends AbstractSessionManager
{
return new HashedSession(this, request);
}
-
+
/* ------------------------------------------------------------ */
protected AbstractSession newSession(long created, long accessed, String clusterId)
{
return new HashedSession(this, created,accessed, clusterId);
}
-
+
/* ------------------------------------------------------------ */
@Override
protected boolean removeSession(String clusterId)
@@ -430,7 +427,7 @@ public class HashSessionManager extends AbstractSessionManager
{
_lazyLoad = lazyLoad;
}
-
+
/* ------------------------------------------------------------ */
public boolean isLazyLoad()
{
@@ -441,7 +438,7 @@ public class HashSessionManager extends AbstractSessionManager
public void restoreSessions () throws Exception
{
_sessionsLoaded = true;
-
+
if (_storeDir==null || !_storeDir.exists())
{
return;
@@ -468,9 +465,9 @@ public class HashSessionManager extends AbstractSessionManager
File file = new File(_storeDir,idInCuster);
if (file.exists())
{
- FileInputStream in = new FileInputStream(file);
+ FileInputStream in = new FileInputStream(file);
HashedSession session = restoreSession(in, null);
- in.close();
+ in.close();
addSession(session, false);
session.didActivate();
file.delete();
@@ -483,7 +480,7 @@ public class HashSessionManager extends AbstractSessionManager
}
return null;
}
-
+
/* ------------------------------------------------------------ */
public void saveSessions(boolean reactivate) throws Exception
{
@@ -491,7 +488,7 @@ public class HashSessionManager extends AbstractSessionManager
{
return;
}
-
+
if (!_storeDir.canWrite())
{
__log.warn ("Unable to save Sessions: Session persistence storage directory "+_storeDir.getAbsolutePath()+ " is not writeable");
@@ -506,7 +503,7 @@ public class HashSessionManager extends AbstractSessionManager
public HashedSession restoreSession (InputStream is, HashedSession session) throws Exception
{
/*
- * Take care of this class's fields first by calling
+ * Take care of this class's fields first by calling
* defaultReadObject
*/
DataInputStream in = new DataInputStream(is);
@@ -515,7 +512,7 @@ public class HashSessionManager extends AbstractSessionManager
long created = in.readLong();
long accessed = in.readLong();
int requests = in.readInt();
-
+
if (session == null)
session = (HashedSession)newSession(created, accessed, clusterId);
session.setRequests(requests);
@@ -536,7 +533,7 @@ public class HashSessionManager extends AbstractSessionManager
return session;
}
-
+
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
protected class ClassLoadingObjectInputStream extends ObjectInputStream
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashedSession.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashedSession.java
index fd60ea8addc..acfc47f5f3f 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashedSession.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashedSession.java
@@ -162,11 +162,8 @@ public class HashedSession extends AbstractSession
// Access now to prevent race with idling period
access(System.currentTimeMillis());
-
if (LOG.isDebugEnabled())
- {
LOG.debug("Deidling " + super.getId());
- }
FileInputStream fis = null;
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java
index f9a01d68131..5280023e7d1 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java
@@ -53,7 +53,7 @@ import org.eclipse.jetty.util.log.Logger;
*/
public class JDBCSessionIdManager extends AbstractSessionIdManager
{
- final static Logger LOG = SessionHandler.__log;
+ final static Logger LOG = SessionHandler.LOG;
protected final HashSet _sessionIds = new HashSet();
protected Server _server;
@@ -108,7 +108,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
throws SQLException
{
_dbName = dbMeta.getDatabaseProductName().toLowerCase();
- LOG.debug ("Using database "+_dbName);
+ LOG.debug ("Using database {}",_dbName);
_isLower = dbMeta.storesLowerCaseIdentifiers();
_isUpper = dbMeta.storesUpperCaseIdentifiers();
}
@@ -255,7 +255,8 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
if ((System.currentTimeMillis()%2) == 0)
_scavengeIntervalMs += tenPercent;
- if (LOG.isDebugEnabled()) LOG.debug("Scavenging every "+_scavengeIntervalMs+" ms");
+ if (LOG.isDebugEnabled())
+ LOG.debug("Scavenging every "+_scavengeIntervalMs+" ms");
if (_timer!=null && (period!=old_period || _task==null))
{
synchronized (this)
@@ -434,7 +435,8 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
initializeDatabase();
prepareTables();
super.doStart();
- if (LOG.isDebugEnabled()) LOG.debug("Scavenging interval = "+getScavengeInterval()+" sec");
+ if (LOG.isDebugEnabled())
+ LOG.debug("Scavenging interval = "+getScavengeInterval()+" sec");
_timer=new Timer("JDBCSessionScavenger", true);
setScavengeInterval(getScavengeInterval());
}
@@ -684,7 +686,8 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
List expiredSessionIds = new ArrayList();
try
{
- if (LOG.isDebugEnabled()) LOG.debug("Scavenge sweep started at "+System.currentTimeMillis());
+ if (LOG.isDebugEnabled())
+ LOG.debug("Scavenge sweep started at "+System.currentTimeMillis());
if (_lastScavengeTime > 0)
{
connection = getConnection();
@@ -693,7 +696,8 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
PreparedStatement statement = connection.prepareStatement(_selectExpiredSessions);
long lowerBound = (_lastScavengeTime - _scavengeIntervalMs);
long upperBound = _lastScavengeTime;
- if (LOG.isDebugEnabled()) LOG.debug (" Searching for sessions expired between "+lowerBound + " and "+upperBound);
+ if (LOG.isDebugEnabled())
+ LOG.debug (" Searching for sessions expired between "+lowerBound + " and "+upperBound);
statement.setLong(1, lowerBound);
statement.setLong(2, upperBound);
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java
index 0c15fb0df62..bcf443eb8d4 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java
@@ -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.
// ========================================================================
@@ -44,9 +44,9 @@ import org.eclipse.jetty.util.log.Logger;
* JDBCSessionManager
*
* SessionManager that persists sessions to a database to enable clustering.
- *
+ *
* Session data is persisted to the JettySessions table:
- *
+ *
* rowId (unique in cluster: webapp name/path + virtualhost + sessionId)
* contextPath (of the context owning the session)
* sessionId (unique in a context)
@@ -58,7 +58,7 @@ import org.eclipse.jetty.util.log.Logger;
* lastSavedTime (last time in milliseconds session access times were saved)
* expiryTime (time in milliseconds that the session is due to expire)
* map (attribute map)
- *
+ *
* As an optimization, to prevent thrashing the database, we do not persist
* the accessTime and lastAccessTime every time the session is accessed. Rather,
* we write it out every so often. The frequency is controlled by the saveIntervalSec
@@ -67,18 +67,18 @@ import org.eclipse.jetty.util.log.Logger;
public class JDBCSessionManager extends AbstractSessionManager
{
private static final Logger LOG = Log.getLogger(JDBCSessionManager.class);
-
- protected String __insertSession;
- protected String __deleteSession;
- protected String __selectSession;
- protected String __updateSession;
- protected String __updateSessionNode;
+
+ protected String __insertSession;
+ protected String __deleteSession;
+ protected String __selectSession;
+ protected String __updateSession;
+ protected String __updateSessionNode;
protected String __updateSessionAccessTime;
protected String __sessionTableRowId;
-
+
private ConcurrentHashMap _sessions;
protected long _saveIntervalSec = 60; //only persist changes to session access times every 60 secs
-
+
/**
* SessionData
*
@@ -108,7 +108,7 @@ public class JDBCSessionManager extends AbstractSessionManager
_attributes = new HashMap();
_lastNode = getSessionIdManager().getWorkerName();
}
-
+
public SessionData (String sessionId,Map attributes)
{
_id=sessionId;
@@ -127,23 +127,23 @@ public class JDBCSessionManager extends AbstractSessionManager
{
return _created;
}
-
+
protected synchronized void setCreated (long ms)
{
_created = ms;
}
-
+
public synchronized long getAccessed ()
{
return _accessed;
}
-
+
protected synchronized void setAccessed (long ms)
{
_accessed = ms;
}
-
-
+
+
public synchronized void setMaxIdleMs (long ms)
{
_maxIdleMs = ms;
@@ -173,77 +173,77 @@ public class JDBCSessionManager extends AbstractSessionManager
{
return _cookieSet;
}
-
+
public synchronized void setRowId (String rowId)
{
_rowId=rowId;
}
-
+
protected synchronized String getRowId()
{
return _rowId;
}
-
+
protected synchronized Map getAttributeMap ()
{
return _attributes;
}
-
+
protected synchronized void setAttributeMap (Map map)
{
_attributes = map;
- }
-
+ }
+
public synchronized void setLastNode (String node)
{
_lastNode=node;
}
-
+
public synchronized String getLastNode ()
{
return _lastNode;
}
-
+
public synchronized void setCanonicalContext(String str)
{
_canonicalContext=str;
}
-
+
public synchronized String getCanonicalContext ()
{
return _canonicalContext;
}
-
+
public synchronized long getLastSaved ()
{
return _lastSaved;
}
-
+
public synchronized void setLastSaved (long time)
{
_lastSaved=time;
}
-
+
public synchronized void setExpiryTime (long time)
{
- _expiryTime=time;
+ _expiryTime=time;
}
-
+
public synchronized long getExpiryTime ()
{
return _expiryTime;
}
-
+
public synchronized void setVirtualHost (String vhost)
{
_virtualHost=vhost;
}
-
+
public synchronized String getVirtualHost ()
{
return _virtualHost;
}
-
+
@Override
public String toString ()
{
@@ -254,8 +254,8 @@ public class JDBCSessionManager extends AbstractSessionManager
}
}
-
-
+
+
/**
* Session
*
@@ -269,12 +269,12 @@ public class JDBCSessionManager extends AbstractSessionManager
/**
* Session from a request.
- *
+ *
* @param request
*/
protected Session (HttpServletRequest request)
{
- super(JDBCSessionManager.this,request);
+ super(JDBCSessionManager.this,request);
_data = new SessionData(getClusterId(),_jdbcAttributes);
if (_dftMaxIdleSecs>0)
_data.setMaxIdleMs(_dftMaxIdleSecs*1000);
@@ -297,7 +297,7 @@ public class JDBCSessionManager extends AbstractSessionManager
_jdbcAttributes.putAll(_data.getAttributeMap());
_data.setAttributeMap(_jdbcAttributes);
}
-
+
@Override
public void setAttribute (String name, Object value)
{
@@ -308,20 +308,20 @@ public class JDBCSessionManager extends AbstractSessionManager
@Override
public void removeAttribute (String name)
{
- super.removeAttribute(name);
+ super.removeAttribute(name);
_dirty=true;
}
-
+
@Override
protected void cookieSet()
{
_data.setCookieSet(_data.getAccessed());
}
- /**
+ /**
* Entry to session.
* Called by SessionHandler on inbound request and the session already exists in this node's memory.
- *
+ *
* @see org.eclipse.jetty.server.session.AbstractSession#access(long)
*/
@Override
@@ -339,7 +339,7 @@ public class JDBCSessionManager extends AbstractSessionManager
return false;
}
- /**
+ /**
* Exit from session
* @see org.eclipse.jetty.server.session.AbstractSession#complete()
*/
@@ -350,7 +350,7 @@ public class JDBCSessionManager extends AbstractSessionManager
try
{
if (_dirty)
- {
+ {
//The session attributes have changed, write to the db, ensuring
//http passivation/activation listeners called
willPassivate();
@@ -358,7 +358,7 @@ public class JDBCSessionManager extends AbstractSessionManager
didActivate();
}
else if ((_data._accessed - _data._lastSaved) >= (getSaveInterval() * 1000))
- {
+ {
updateSessionAccessTime(_data);
}
}
@@ -371,18 +371,19 @@ public class JDBCSessionManager extends AbstractSessionManager
_dirty=false;
}
}
-
+
@Override
protected void timeout() throws IllegalStateException
{
- if (LOG.isDebugEnabled()) LOG.debug("Timing out session id="+getClusterId());
+ if (LOG.isDebugEnabled())
+ LOG.debug("Timing out session id="+getClusterId());
super.timeout();
}
}
-
-
-
-
+
+
+
+
/**
* ClassLoadingObjectInputStream
*
@@ -413,46 +414,46 @@ public class JDBCSessionManager extends AbstractSessionManager
}
}
}
-
-
+
+
/**
* Set the time in seconds which is the interval between
* saving the session access time to the database.
- *
+ *
* This is an optimization that prevents the database from
* being overloaded when a session is accessed very frequently.
- *
+ *
* On session exit, if the session attributes have NOT changed,
* the time at which we last saved the accessed
* time is compared to the current accessed time. If the interval
* is at least saveIntervalSecs, then the access time will be
* persisted to the database.
- *
+ *
* If any session attribute does change, then the attributes and
* the accessed time are persisted.
- *
+ *
* @param sec
*/
public void setSaveInterval (long sec)
{
_saveIntervalSec=sec;
}
-
+
public long getSaveInterval ()
{
return _saveIntervalSec;
}
-
-
+
+
/**
* A method that can be implemented in subclasses to support
* distributed caching of sessions. This method will be
* called whenever the session is written to the database
* because the session data has changed.
- *
+ *
* This could be used eg with a JMS backplane to notify nodes
* that the session has changed and to delete the session from
* the node's cache, and re-read it from the database.
@@ -460,46 +461,46 @@ public class JDBCSessionManager extends AbstractSessionManager
*/
public void cacheInvalidate (Session session)
{
-
+
}
-
-
- /**
+
+
+ /**
* A session has been requested by it's id on this node.
- *
+ *
* Load the session by id AND context path from the database.
* Multiple contexts may share the same session id (due to dispatching)
* but they CANNOT share the same contents.
- *
+ *
* Check if last node id is my node id, if so, then the session we have
* in memory cannot be stale. If another node used the session last, then
* we need to refresh from the db.
- *
- * NOTE: this method will go to the database, so if you only want to check
+ *
+ * NOTE: this method will go to the database, so if you only want to check
* for the existence of a Session in memory, use _sessions.get(id) instead.
- *
+ *
* @see org.eclipse.jetty.server.session.AbstractSessionManager#getSession(java.lang.String)
*/
@Override
public Session getSession(String idInCluster)
{
Session session = (Session)_sessions.get(idInCluster);
-
+
synchronized (this)
- {
+ {
try
- {
- //check if we need to reload the session -
+ {
+ //check if we need to reload the session -
//as an optimization, don't reload on every access
- //to reduce the load on the database. This introduces a window of
+ //to reduce the load on the database. This introduces a window of
//possibility that the node may decide that the session is local to it,
//when the session has actually been live on another node, and then
//re-migrated to this node. This should be an extremely rare occurrence,
- //as load-balancers are generally well-behaved and consistently send
- //sessions to the same node, changing only iff that node fails.
+ //as load-balancers are generally well-behaved and consistently send
+ //sessions to the same node, changing only iff that node fails.
SessionData data = null;
long now = System.currentTimeMillis();
- if (LOG.isDebugEnabled())
+ if (LOG.isDebugEnabled())
{
if (session==null)
LOG.debug("getSession("+idInCluster+"): not in session map,"+
@@ -515,9 +516,9 @@ public class JDBCSessionManager extends AbstractSessionManager
" thisNode="+getSessionIdManager().getWorkerName()+
" difference="+(now - session._data._lastSaved));
}
-
+
if (session==null || ((now - session._data._lastSaved) >= (_saveIntervalSec * 1000)))
- {
+ {
LOG.debug("getSession("+idInCluster+"): no session in session map or stale session. Reloading session data from db.");
data = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context));
}
@@ -528,10 +529,10 @@ public class JDBCSessionManager extends AbstractSessionManager
}
else
{
- LOG.debug("getSession("+idInCluster+"): session in session map");
+ LOG.debug("getSession("+idInCluster+"): session in session map");
data = session._data;
}
-
+
if (data != null)
{
if (!data.getLastNode().equals(getSessionIdManager().getWorkerName()) || session==null)
@@ -551,7 +552,7 @@ public class JDBCSessionManager extends AbstractSessionManager
}
else
if (LOG.isDebugEnabled()) LOG.debug("getSession("+idInCluster+"): Session has expired");
-
+
}
else
if (LOG.isDebugEnabled()) LOG.debug("getSession("+idInCluster+"): Session not stale "+session._data);
@@ -563,7 +564,7 @@ public class JDBCSessionManager extends AbstractSessionManager
session=null;
if (LOG.isDebugEnabled()) LOG.debug("getSession("+idInCluster+"): No session in database matching id="+idInCluster);
}
-
+
return session;
}
catch (Exception e)
@@ -573,10 +574,10 @@ public class JDBCSessionManager extends AbstractSessionManager
}
}
}
-
- /**
+
+ /**
* Get the number of sessions.
- *
+ *
* @see org.eclipse.jetty.server.session.AbstractSessionManager#getSessions()
*/
@Override
@@ -591,9 +592,9 @@ public class JDBCSessionManager extends AbstractSessionManager
}
- /**
+ /**
* Start the session manager.
- *
+ *
* @see org.eclipse.jetty.server.session.AbstractSessionManager#doStart()
*/
@Override
@@ -601,17 +602,17 @@ public class JDBCSessionManager extends AbstractSessionManager
{
if (_sessionIdManager==null)
throw new IllegalStateException("No session id manager defined");
-
+
prepareTables();
-
+
_sessions = new ConcurrentHashMap();
super.doStart();
}
-
-
- /**
+
+
+ /**
* Stop the session manager.
- *
+ *
* @see org.eclipse.jetty.server.session.AbstractSessionManager#doStop()
*/
@Override
@@ -619,10 +620,10 @@ public class JDBCSessionManager extends AbstractSessionManager
{
_sessions.clear();
_sessions = null;
-
+
super.doStop();
- }
-
+ }
+
@Override
protected void invalidateSessions()
{
@@ -634,10 +635,10 @@ public class JDBCSessionManager extends AbstractSessionManager
//any other nodes
}
-
+
/**
* Invalidate a session.
- *
+ *
* @param idInCluster
*/
protected void invalidateSession (String idInCluster)
@@ -647,24 +648,24 @@ public class JDBCSessionManager extends AbstractSessionManager
{
session = (Session)_sessions.get(idInCluster);
}
-
+
if (session != null)
{
session.invalidate();
}
}
-
- /**
+
+ /**
* Delete an existing session, both from the in-memory map and
* the database.
- *
+ *
* @see org.eclipse.jetty.server.session.AbstractSessionManager#removeSession(java.lang.String)
*/
@Override
protected boolean removeSession(String idInCluster)
{
synchronized (this)
- {
+ {
Session session = (Session)_sessions.remove(idInCluster);
try
{
@@ -680,9 +681,9 @@ public class JDBCSessionManager extends AbstractSessionManager
}
- /**
+ /**
* Add a newly created session to our in-memory list for this node and persist it.
- *
+ *
* @see org.eclipse.jetty.server.session.AbstractSessionManager#addSession(org.eclipse.jetty.server.session.AbstractSession)
*/
@Override
@@ -695,7 +696,7 @@ public class JDBCSessionManager extends AbstractSessionManager
{
_sessions.put(session.getClusterId(), session);
}
-
+
//TODO or delay the store until exit out of session? If we crash before we store it
//then session data will be lost.
try
@@ -711,9 +712,9 @@ public class JDBCSessionManager extends AbstractSessionManager
}
- /**
+ /**
* Make a new Session.
- *
+ *
* @see org.eclipse.jetty.server.session.AbstractSessionManager#newSession(javax.servlet.http.HttpServletRequest)
*/
@Override
@@ -721,9 +722,9 @@ public class JDBCSessionManager extends AbstractSessionManager
{
return new Session(request);
}
-
+
/* ------------------------------------------------------------ */
- /** Remove session from manager
+ /** Remove session from manager
* @param session The session to remove
* @param invalidate True if {@link HttpSessionListener#sessionDestroyed(HttpSessionEvent)} and
* {@link SessionIdManager#invalidateAll(String)} should be called.
@@ -733,7 +734,7 @@ public class JDBCSessionManager extends AbstractSessionManager
{
// Remove session from context and global maps
boolean removed = false;
-
+
synchronized (this)
{
//take this session out of the map of sessions for this context
@@ -748,10 +749,10 @@ public class JDBCSessionManager extends AbstractSessionManager
{
// Remove session from all context and global id maps
_sessionIdManager.removeSession(session);
-
+
if (invalidate)
_sessionIdManager.invalidateAll(session.getClusterId());
-
+
if (invalidate && !_sessionListeners.isEmpty())
{
HttpSessionEvent event=new HttpSessionEvent(session);
@@ -764,16 +765,16 @@ public class JDBCSessionManager extends AbstractSessionManager
}
}
}
-
-
+
+
/**
* Expire any Sessions we have in memory matching the list of
* expired Session ids.
- *
+ *
* @param sessionIds
*/
protected void expire (List> sessionIds)
- {
+ {
//don't attempt to scavenge if we are shutting down
if (isStopping() || isStopped())
return;
@@ -788,8 +789,9 @@ public class JDBCSessionManager extends AbstractSessionManager
while (itor.hasNext())
{
String sessionId = (String)itor.next();
- if (LOG.isDebugEnabled()) LOG.debug("Expiring session id "+sessionId);
-
+ if (LOG.isDebugEnabled())
+ LOG.debug("Expiring session id "+sessionId);
+
Session session = (Session)_sessions.get(sessionId);
if (session != null)
{
@@ -798,28 +800,26 @@ public class JDBCSessionManager extends AbstractSessionManager
}
else
{
- if (LOG.isDebugEnabled()) LOG.debug("Unrecognized session id="+sessionId);
+ if (LOG.isDebugEnabled())
+ LOG.debug("Unrecognized session id="+sessionId);
}
}
}
catch (Throwable t)
{
- if (t instanceof ThreadDeath)
- throw ((ThreadDeath)t);
- else
- LOG.warn("Problem expiring sessions", t);
+ LOG.warn("Problem expiring sessions", t);
}
finally
{
thread.setContextClassLoader(old_loader);
}
}
-
-
+
+
protected void prepareTables ()
{
__sessionTableRowId = ((JDBCSessionIdManager)_sessionIdManager)._sessionTableRowId;
-
+
__insertSession = "insert into "+((JDBCSessionIdManager)_sessionIdManager)._sessionTable+
" ("+__sessionTableRowId+", sessionId, contextPath, virtualHost, lastNode, accessTime, lastAccessTime, createTime, cookieTime, lastSavedTime, expiryTime, map) "+
" values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
@@ -839,7 +839,7 @@ public class JDBCSessionManager extends AbstractSessionManager
__updateSessionAccessTime = "update "+((JDBCSessionIdManager)_sessionIdManager)._sessionTable+
" set lastNode = ?, accessTime = ?, lastAccessTime = ?, lastSavedTime = ?, expiryTime = ? where "+__sessionTableRowId+" = ?";
}
-
+
/**
* Load a session from the database
* @param id
@@ -860,7 +860,7 @@ public class JDBCSessionManager extends AbstractSessionManager
Connection connection=null;
PreparedStatement statement = null;
try
- {
+ {
connection = getConnection();
statement = connection.prepareStatement(__selectSession);
statement.setString(1, id);
@@ -903,24 +903,24 @@ public class JDBCSessionManager extends AbstractSessionManager
try { connection.close();}
catch(Exception e) { LOG.warn(e); }
}
- }
+ }
}
};
-
+
if (_context==null)
load.run();
else
_context.getContextHandler().handle(load);
-
+
if (_exception.get()!=null)
throw _exception.get();
-
+
return _reference.get();
}
-
+
/**
* Insert a session into the database.
- *
+ *
* @param data
* @throws Exception
*/
@@ -929,14 +929,14 @@ public class JDBCSessionManager extends AbstractSessionManager
{
if (data==null)
return;
-
- //put into the database
+
+ //put into the database
Connection connection = getConnection();
PreparedStatement statement = null;
try
- {
+ {
String rowId = calculateRowId(data);
-
+
long now = System.currentTimeMillis();
connection.setAutoCommit(true);
statement = connection.prepareStatement(__insertSession);
@@ -951,34 +951,34 @@ public class JDBCSessionManager extends AbstractSessionManager
statement.setLong(9, data.getCookieSet());//time cookie was set
statement.setLong(10, now); //last saved time
statement.setLong(11, data.getExpiryTime());
-
+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(data.getAttributeMap());
byte[] bytes = baos.toByteArray();
-
+
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
statement.setBinaryStream(12, bais, bytes.length);//attribute map as blob
-
+
statement.executeUpdate();
data.setRowId(rowId); //set it on the in-memory data as well as in db
data.setLastSaved(now);
-
+
if (LOG.isDebugEnabled())
LOG.debug("Stored session "+data);
- }
+ }
finally
{
if (connection!=null)
connection.close();
}
}
-
-
+
+
/**
* Update data on an existing persisted session.
- *
+ *
* @param data
* @throws Exception
*/
@@ -987,30 +987,30 @@ public class JDBCSessionManager extends AbstractSessionManager
{
if (data==null)
return;
-
+
Connection connection = getConnection();
PreparedStatement statement = null;
try
- {
+ {
long now = System.currentTimeMillis();
connection.setAutoCommit(true);
- statement = connection.prepareStatement(__updateSession);
+ statement = connection.prepareStatement(__updateSession);
statement.setString(1, getSessionIdManager().getWorkerName());//my node id
statement.setLong(2, data.getAccessed());//accessTime
statement.setLong(3, data.getLastAccessed()); //lastAccessTime
statement.setLong(4, now); //last saved time
statement.setLong(5, data.getExpiryTime());
-
+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(data.getAttributeMap());
byte[] bytes = baos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-
- statement.setBinaryStream(6, bais, bytes.length);//attribute map as blob
+
+ statement.setBinaryStream(6, bais, bytes.length);//attribute map as blob
statement.setString(7, data.getRowId()); //rowId
statement.executeUpdate();
-
+
data.setLastSaved(now);
if (LOG.isDebugEnabled())
LOG.debug("Updated session "+data);
@@ -1021,11 +1021,11 @@ public class JDBCSessionManager extends AbstractSessionManager
connection.close();
}
}
-
-
+
+
/**
* Update the node on which the session was last seen to be my node.
- *
+ *
* @param data
* @throws Exception
*/
@@ -1036,7 +1036,7 @@ public class JDBCSessionManager extends AbstractSessionManager
Connection connection = getConnection();
PreparedStatement statement = null;
try
- {
+ {
connection.setAutoCommit(true);
statement = connection.prepareStatement(__updateSessionNode);
statement.setString(1, nodeId);
@@ -1052,10 +1052,10 @@ public class JDBCSessionManager extends AbstractSessionManager
connection.close();
}
}
-
+
/**
* Persist the time the session was last accessed.
- *
+ *
* @param data
* @throws Exception
*/
@@ -1065,7 +1065,7 @@ public class JDBCSessionManager extends AbstractSessionManager
Connection connection = getConnection();
PreparedStatement statement = null;
try
- {
+ {
long now = System.currentTimeMillis();
connection.setAutoCommit(true);
statement = connection.prepareStatement(__updateSessionAccessTime);
@@ -1087,14 +1087,14 @@ public class JDBCSessionManager extends AbstractSessionManager
connection.close();
}
}
-
-
-
-
+
+
+
+
/**
* Delete a session from the database. Should only be called
* when the session has been invalidated.
- *
+ *
* @param data
* @throws Exception
*/
@@ -1116,11 +1116,11 @@ public class JDBCSessionManager extends AbstractSessionManager
{
if (connection!=null)
connection.close();
- }
+ }
}
-
-
-
+
+
+
/**
* Get a connection from the driver.
* @return
@@ -1128,13 +1128,13 @@ public class JDBCSessionManager extends AbstractSessionManager
*/
private Connection getConnection ()
throws SQLException
- {
+ {
return ((JDBCSessionIdManager)getSessionIdManager()).getConnection();
}
/**
* Calculate a unique id for this session across the cluster.
- *
+ *
* Unique id is composed of: contextpath_virtualhost0_sessionid
* @param data
* @return
@@ -1146,31 +1146,31 @@ public class JDBCSessionManager extends AbstractSessionManager
rowId = rowId+"_"+data.getId();
return rowId;
}
-
+
/**
* Get the first virtual host for the context.
- *
+ *
* Used to help identify the exact session/contextPath.
- *
+ *
* @return 0.0.0.0 if no virtual host is defined
*/
private String getVirtualHost (ContextHandler.Context context)
{
String vhost = "0.0.0.0";
-
+
if (context==null)
return vhost;
-
+
String [] vhosts = context.getContextHandler().getVirtualHosts();
if (vhosts==null || vhosts.length==0 || vhosts[0]==null)
return vhost;
-
+
return vhosts[0];
}
-
+
/**
* Make an acceptable file name from a context path.
- *
+ *
* @param path
* @return
*/
@@ -1178,7 +1178,7 @@ public class JDBCSessionManager extends AbstractSessionManager
{
if (path==null)
return "";
-
+
return path.replace('/', '_').replace('.','_').replace('\\','_');
}
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java
index 2e951710c73..a18a6e7553b 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java
@@ -36,7 +36,7 @@ import org.eclipse.jetty.util.log.Logger;
*/
public class SessionHandler extends ScopedHandler
{
- final static Logger __log = Log.getLogger("org.eclipse.jetty.server.session");
+ final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
/* -------------------------------------------------------------- */
private SessionManager _sessionManager;
@@ -175,10 +175,10 @@ public class SessionHandler extends ScopedHandler
}
}
- if(__log.isDebugEnabled())
+ if(LOG.isDebugEnabled())
{
- __log.debug("sessionManager="+_sessionManager);
- __log.debug("session="+session);
+ LOG.debug("sessionManager="+_sessionManager);
+ LOG.debug("session="+session);
}
// start manual inline of nextScope(target,baseRequest,request,response);
@@ -264,7 +264,8 @@ public class SessionHandler extends ScopedHandler
{
requested_session_id=cookies[i].getValue();
requested_session_id_from_cookie = true;
- if(__log.isDebugEnabled())__log.debug("Got Session ID "+requested_session_id+" from cookie");
+ if(LOG.isDebugEnabled())
+ LOG.debug("Got Session ID {} from cookie",requested_session_id);
session=sessionManager.getHttpSession(requested_session_id);
if (session!=null && sessionManager.isValid(session))
@@ -297,8 +298,8 @@ public class SessionHandler extends ScopedHandler
requested_session_id = uri.substring(s,i);
requested_session_id_from_cookie = false;
session=sessionManager.getHttpSession(requested_session_id);
- if(__log.isDebugEnabled())
- __log.debug("Got Session ID "+requested_session_id+" from URL");
+ if(LOG.isDebugEnabled())
+ LOG.debug("Got Session ID {} from URL",requested_session_id);
}
}
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslConnector.java
index 1bf6b4680cf..fb04d57d61c 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslConnector.java
@@ -9,8 +9,8 @@ import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManagerFactory;
-import org.eclipse.jetty.http.ssl.SslContextFactory;
import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
/* ------------------------------------------------------------ */
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java
index 50162605839..1986e7bc08d 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java
@@ -14,30 +14,26 @@
package org.eclipse.jetty.server.ssl;
import java.io.IOException;
-import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
-import java.util.Arrays;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
-import org.eclipse.jetty.http.HttpParser;
import org.eclipse.jetty.http.HttpSchemes;
-import org.eclipse.jetty.http.ssl.SslContextFactory;
+import org.eclipse.jetty.io.AsyncEndPoint;
import org.eclipse.jetty.io.Buffers;
import org.eclipse.jetty.io.Buffers.Type;
import org.eclipse.jetty.io.BuffersFactory;
-import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.RuntimeIOException;
import org.eclipse.jetty.io.bio.SocketEndPoint;
-import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
-import org.eclipse.jetty.io.nio.SelectorManager.SelectSet;
-import org.eclipse.jetty.io.nio.SslSelectChannelEndPoint;
-import org.eclipse.jetty.server.HttpConnection;
+import org.eclipse.jetty.io.nio.AsyncConnection;
+import org.eclipse.jetty.io.nio.SslConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
/* ------------------------------------------------------------ */
/**
@@ -54,6 +50,7 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements
public SslSelectChannelConnector()
{
this(new SslContextFactory(SslContextFactory.DEFAULT_KEYSTORE_PATH));
+ setSoLingerTime(30000);
}
/* ------------------------------------------------------------ */
@@ -61,6 +58,7 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements
{
_sslContextFactory = sslContextFactory;
setUseDirectBuffers(false);
+ setSoLingerTime(30000);
}
/* ------------------------------------------------------------ */
@@ -95,10 +93,10 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements
request.setScheme(HttpSchemes.HTTPS);
super.customize(endpoint,request);
- SslSelectChannelEndPoint sslHttpChannelEndpoint=(SslSelectChannelEndPoint)endpoint;
- SSLEngine sslEngine=sslHttpChannelEndpoint.getSSLEngine();
+ SslConnection.SslEndPoint sslEndpoint=(SslConnection.SslEndPoint)endpoint;
+ SSLEngine sslEngine=sslEndpoint.getSslEngine();
SSLSession sslSession=sslEngine.getSession();
-
+
SslCertificates.customize(sslSession,endpoint,request);
}
@@ -539,21 +537,31 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements
/* ------------------------------------------------------------------------------- */
@Override
- protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key) throws IOException
+ protected AsyncConnection newConnection(SocketChannel channel, AsyncEndPoint endpoint)
{
- SSLEngine engine = createSSLEngine(channel);
- SslSelectChannelEndPoint endp = new SslSelectChannelEndPoint(_sslBuffers,channel,selectSet,key,engine, SslSelectChannelConnector.this._maxIdleTime);
- endp.setAllowRenegotiate(_sslContextFactory.isAllowRenegotiate());
- return endp;
+ try
+ {
+ SSLEngine engine = createSSLEngine(channel);
+ SslConnection connection = newSslConnection(endpoint, engine);
+ AsyncConnection delegate = newPlainConnection(channel, connection.getSslEndPoint());
+ connection.getSslEndPoint().setConnection(delegate);
+ connection.setAllowRenegotiate(_sslContextFactory.isAllowRenegotiate());
+ return connection;
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeIOException(e);
+ }
}
- /* ------------------------------------------------------------------------------- */
- @Override
- protected Connection newConnection(SocketChannel channel, SelectChannelEndPoint endpoint)
+ protected AsyncConnection newPlainConnection(SocketChannel channel, AsyncEndPoint endPoint)
{
- HttpConnection connection=(HttpConnection)super.newConnection(channel,endpoint);
- ((HttpParser)connection.getParser()).setForceContentBuffer(true);
- return connection;
+ return super.newConnection(channel, endPoint);
+ }
+
+ protected SslConnection newSslConnection(AsyncEndPoint endpoint, SSLEngine engine)
+ {
+ return new SslConnection(engine, endpoint);
}
/* ------------------------------------------------------------ */
@@ -576,7 +584,7 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements
{
engine = _sslContextFactory.newSslEngine();
}
-
+
engine.setUseClientMode(false);
return engine;
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSocketConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSocketConnector.java
index 85785b79f50..f18981cce7b 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSocketConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSocketConnector.java
@@ -16,6 +16,7 @@ package org.eclipse.jetty.server.ssl;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
+
import javax.net.ssl.HandshakeCompletedEvent;
import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.SSLContext;
@@ -25,7 +26,6 @@ import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import org.eclipse.jetty.http.HttpSchemes;
-import org.eclipse.jetty.http.ssl.SslContextFactory;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.RuntimeIOException;
import org.eclipse.jetty.io.bio.SocketEndPoint;
@@ -33,6 +33,7 @@ import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.bio.SocketConnector;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
/* ------------------------------------------------------------ */
/**
@@ -63,6 +64,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
public SslSocketConnector()
{
this(new SslContextFactory(SslContextFactory.DEFAULT_KEYSTORE_PATH));
+ setSoLingerTime(30000);
}
/* ------------------------------------------------------------ */
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractConnectorTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractConnectorTest.java
index f006313c14a..7c35f79d147 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractConnectorTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractConnectorTest.java
@@ -13,6 +13,9 @@
package org.eclipse.jetty.server;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
@@ -20,6 +23,7 @@ import java.io.PrintWriter;
import java.net.Socket;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
+
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -35,9 +39,6 @@ import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
public class AbstractConnectorTest
{
private static final Logger LOG = Log.getLogger(AbstractConnectorTest.class);
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncUploadTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncRequestReadTest.java
similarity index 65%
rename from jetty-server/src/test/java/org/eclipse/jetty/server/AsyncUploadTest.java
rename to jetty-server/src/test/java/org/eclipse/jetty/server/AsyncRequestReadTest.java
index d970ca15bdd..e63f875a9ef 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncUploadTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncRequestReadTest.java
@@ -22,6 +22,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Arrays;
+import java.util.concurrent.Exchanger;
import java.util.concurrent.TimeUnit;
import javax.servlet.ServletException;
@@ -33,6 +34,7 @@ import org.eclipse.jetty.continuation.ContinuationSupport;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.StringUtil;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -40,17 +42,18 @@ import org.junit.Test;
/**
* @version $Revision: 889 $ $Date: 2009-09-14 14:52:16 +1000 (Mon, 14 Sep 2009) $
*/
-public class AsyncUploadTest
+public class AsyncRequestReadTest
{
private static Server server;
private static Connector connector;
- private static int total;
+ private final static Exchanger __total=new Exchanger();
@BeforeClass
public static void startServer() throws Exception
{
server = new Server();
connector = new SelectChannelConnector();
+ connector.setMaxIdleTime(10000);
server.addConnector(connector);
server.setHandler(new EmptyHandler());
server.start();
@@ -62,7 +65,7 @@ public class AsyncUploadTest
server.stop();
server.join();
}
-
+
@Test
public void test() throws Exception
{
@@ -71,14 +74,17 @@ public class AsyncUploadTest
byte[] content = new byte[16*4096];
Arrays.fill(content, (byte)120);
- long start = System.nanoTime();
OutputStream out = socket.getOutputStream();
- out.write("POST / HTTP/1.1\r\n".getBytes());
- out.write("Host: localhost\r\n".getBytes());
- out.write(("Content-Length: "+content.length+"\r\n").getBytes());
- out.write("Content-Type: bytes\r\n".getBytes());
- out.write("Connection: close\r\n".getBytes());
- out.write("\r\n".getBytes());
+ String header=
+ "POST / HTTP/1.1\r\n"+
+ "Host: localhost\r\n"+
+ "Content-Length: "+content.length+"\r\n"+
+ "Content-Type: bytes\r\n"+
+ "Connection: close\r\n"+
+ "\r\n";
+ byte[] h=header.getBytes(StringUtil.__ISO_8859_1);
+
+ out.write(h);
out.flush();
out.write(content,0,4*4096);
@@ -91,14 +97,63 @@ public class AsyncUploadTest
InputStream in = socket.getInputStream();
String response = IO.toString(in);
- // System.err.println(response);
assertTrue(response.indexOf("200 OK")>0);
- long end = System.nanoTime();
- System.err.println("upload time: " + TimeUnit.NANOSECONDS.toMillis(end - start));
+ long total=__total.exchange(0L,30,TimeUnit.SECONDS);
assertEquals(content.length, total);
}
+
+ @Test
+ public void tests() throws Exception
+ {
+ runTest(64,4,4,20);
+ runTest(256,16,16,50);
+ runTest(256,1,128,10);
+ runTest(128*1024,1,64,10);
+ runTest(256*1024,5321,10,100);
+ runTest(512*1024,32*1024,10,10);
+ }
+
+
+ public void runTest(int contentSize, int chunkSize, int chunks, int delayMS) throws Exception
+ {
+ String tst=contentSize+","+chunkSize+","+chunks+","+delayMS;
+ //System.err.println(tst);
+
+ final Socket socket = new Socket("localhost",connector.getLocalPort());
+ byte[] content = new byte[contentSize];
+ Arrays.fill(content, (byte)120);
+
+ OutputStream out = socket.getOutputStream();
+ out.write("POST / HTTP/1.1\r\n".getBytes());
+ out.write("Host: localhost\r\n".getBytes());
+ out.write(("Content-Length: "+content.length+"\r\n").getBytes());
+ out.write("Content-Type: bytes\r\n".getBytes());
+ out.write("Connection: close\r\n".getBytes());
+ out.write("\r\n".getBytes());
+ out.flush();
+
+ int offset=0;
+ for (int i=0;i0);
+
+ long total=__total.exchange(0L,30,TimeUnit.SECONDS);
+ assertEquals(tst,content.length, total);
+ }
+
+
private static class EmptyHandler extends AbstractHandler
{
public void handle(String path, final Request request, HttpServletRequest httpRequest, final HttpServletResponse httpResponse) throws IOException, ServletException
@@ -112,15 +167,14 @@ public class AsyncUploadTest
@Override
public void run()
{
+ long total=0;
try
{
- Thread.sleep(100);
InputStream in = request.getInputStream();
byte[] b = new byte[4*4096];
int read;
while((read =in.read(b))>=0)
total += read;
- System.err.println("Read "+ total);
}
catch(Exception e)
{
@@ -131,6 +185,14 @@ public class AsyncUploadTest
{
httpResponse.setStatus(200);
continuation.complete();
+ try
+ {
+ __total.exchange(total);
+ }
+ catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
}
}
}.start();
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/BusySelectChannelServerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/BusySelectChannelServerTest.java
deleted file mode 100644
index 1f6c6852a8f..00000000000
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/BusySelectChannelServerTest.java
+++ /dev/null
@@ -1,155 +0,0 @@
-// ========================================================================
-// Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-
-package org.eclipse.jetty.server;
-import java.io.IOException;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.SocketChannel;
-
-import org.eclipse.jetty.io.Buffer;
-import org.eclipse.jetty.io.View;
-import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
-import org.eclipse.jetty.io.nio.NIOBuffer;
-import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
-import org.eclipse.jetty.io.nio.SelectorManager.SelectSet;
-import org.eclipse.jetty.server.nio.SelectChannelConnector;
-import org.junit.BeforeClass;
-
-/**
- * HttpServer Tester.
- */
-public class BusySelectChannelServerTest extends HttpServerTestBase
-{
- @BeforeClass
- public static void init() throws Exception
- {
- SelectChannelConnector connector=new SelectChannelConnector()
- {
- @Override
- protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key) throws IOException
- {
- return new SelectChannelEndPoint(channel,selectSet,key, _maxIdleTime)
- {
- int write;
- int read;
-
- /* ------------------------------------------------------------ */
- /* (non-Javadoc)
- * @see org.eclipse.io.nio.SelectChannelEndPoint#flush(org.eclipse.io.Buffer, org.eclipse.io.Buffer, org.eclipse.io.Buffer)
- */
- @Override
- public int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException
- {
- int x=write++&0xff;
- if (x<8)
- {
- clearWritable();
- return 0;
- }
- if (x<32)
- return flush(header);
- return super.flush(header,buffer,trailer);
- }
-
- /* ------------------------------------------------------------ */
- /* (non-Javadoc)
- * @see org.eclipse.io.nio.SelectChannelEndPoint#flush(org.eclipse.io.Buffer)
- */
- @Override
- public int flush(Buffer buffer) throws IOException
- {
- int x=write++&0xff;
- if (x<8)
- {
- clearWritable();
- return 0;
- }
- if (x<32)
- {
- View v = new View(buffer);
- v.setPutIndex(v.getIndex()+1);
- int l=super.flush(v);
- if (l>0)
- buffer.skip(l);
- clearWritable();
- return l;
- }
- return super.flush(buffer);
- }
-
- /* ------------------------------------------------------------ */
- /* (non-Javadoc)
- * @see org.eclipse.io.nio.ChannelEndPoint#fill(org.eclipse.io.Buffer)
- */
- @Override
- public int fill(Buffer buffer) throws IOException
- {
- int x=read++&0xff;
- if (x<8)
- return 0;
-
- if (x<16 && buffer.space()>=1)
- {
- NIOBuffer one = new IndirectNIOBuffer(1);
- int l=super.fill(one);
- if (l>0)
- buffer.put(one.peek(0));
- return l;
- }
-
- if (x<24 && buffer.space()>=2)
- {
- NIOBuffer two = new IndirectNIOBuffer(2);
- int l=super.fill(two);
- if (l>0)
- buffer.put(two.peek(0));
- if (l>1)
- buffer.put(two.peek(1));
- return l;
- }
-
- if (x<64 && buffer.space()>=3)
- {
- NIOBuffer three = new IndirectNIOBuffer(3);
- int l=super.fill(three);
- if (l>0)
- buffer.put(three.peek(0));
- if (l>1)
- buffer.put(three.peek(1));
- if (l>2)
- buffer.put(three.peek(2));
- return l;
- }
-
- return super.fill(buffer);
- }
- };
- }
- };
- connector.setAcceptors(1);
- startServer(connector);
- }
-
- @Override
- public void testAvailable() throws Exception
- {
- }
-
- @Override
- public void testBlockingWhileWritingResponseContent() throws Exception
- {
- // TODO work out why this one fails
- }
-
-
-}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectorTimeoutTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectorTimeoutTest.java
index 26caaa934b5..7b2e2b5650e 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectorTimeoutTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectorTimeoutTest.java
@@ -54,8 +54,6 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
OutputStream os=client.getOutputStream();
InputStream is=client.getInputStream();
- String content="Wibble";
- byte[] contentB=content.getBytes("utf-8");
os.write((
"GET / HTTP/1.0\r\n"+
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
@@ -64,7 +62,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
os.flush();
long start = System.currentTimeMillis();
- String in = IO.toString(is);
+ IO.toString(is);
Thread.sleep(300);
assertEquals(-1, is.read());
@@ -97,7 +95,7 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
os.flush();
long start = System.currentTimeMillis();
- String in = IO.toString(is);
+ IO.toString(is);
Thread.sleep(300);
assertEquals(-1, is.read());
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/DumpHandler.java b/jetty-server/src/test/java/org/eclipse/jetty/server/DumpHandler.java
index adaf8751b28..301c352899a 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/DumpHandler.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/DumpHandler.java
@@ -151,8 +151,7 @@ public class DumpHandler extends AbstractHandler
String val=request.getParameter("CookieVal");
val=val.replaceAll("[ \n\r=<>]","?");
Cookie cookie=
- new Cookie(cookie_name.trim(),
- request.getParameter("CookieVal"));
+ new Cookie(cookie_name.trim(),val);
if ("Clear Cookie".equals(cookie_action))
cookie.setMaxAge(0);
response.addCookie(cookie);
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/EncodedHttpURITest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/EncodedHttpURITest.java
index f5afdb662be..b73c3fdbc5c 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/EncodedHttpURITest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/EncodedHttpURITest.java
@@ -28,7 +28,7 @@ public class EncodedHttpURITest
{
String url = "http://www.foo.com/ma\u00F1ana";
byte[] asISO = url.getBytes("ISO-8859-1");
- String str = new String(asISO, "ISO-8859-1");
+ new String(asISO, "ISO-8859-1");
//use a non UTF-8 charset as the encoding and url-escape as per
//http://www.w3.org/TR/html40/appendix/notes.html#non-ascii-chars
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpConnectionTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpConnectionTest.java
index 50e175dae19..67207366582 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpConnectionTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpConnectionTest.java
@@ -33,7 +33,6 @@ import org.eclipse.jetty.http.HttpHeaders;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.log.StdErrLog;
import org.junit.After;
import org.junit.Before;
@@ -124,7 +123,7 @@ public class HttpConnectionTest
int offset=0;
offset = checkContains(response,offset,"HTTP/1.1 200");
- offset = checkContains(response,offset,"/R1");
+ checkContains(response,offset,"/R1");
}
@Test
@@ -155,7 +154,7 @@ public class HttpConnectionTest
{
try
{
- ((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(true);
+ ((StdErrLog)Log.getLogger(AbstractHttpConnection.class)).setHideStacks(true);
String response;
@@ -186,7 +185,7 @@ public class HttpConnectionTest
}
finally
{
- ((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(false);
+ ((StdErrLog)Log.getLogger(AbstractHttpConnection.class)).setHideStacks(false);
}
}
@@ -336,7 +335,7 @@ public class HttpConnectionTest
Logger logger=null;
try
{
- ((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(true);
+ ((StdErrLog)Log.getLogger(AbstractHttpConnection.class)).setHideStacks(true);
response=connector.getResponses(requests);
offset = checkContains(response,offset,"HTTP/1.1 500");
offset = checkContains(response,offset,"Connection: close");
@@ -344,7 +343,7 @@ public class HttpConnectionTest
}
finally
{
- ((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(false);
+ ((StdErrLog)Log.getLogger(AbstractHttpConnection.class)).setHideStacks(false);
}
}
@@ -366,7 +365,7 @@ public class HttpConnectionTest
"5;\015\012"+
"12345\015\012"+
"0;\015\012\015\012");
- offset = checkContains(response,offset,"Connection: close");
+ checkContains(response,offset,"Connection: close");
}
catch (Exception e)
{
@@ -395,7 +394,7 @@ public class HttpConnectionTest
"Cookie: "+cookie+"\n"+
"\015\012"
);
- offset = checkContains(response, offset, "HTTP/1.1 413");
+ checkContains(response, offset, "HTTP/1.1 413");
}
catch(Exception e)
{
@@ -424,14 +423,14 @@ public class HttpConnectionTest
request.append("\015\012");
response = connector.getResponses(request.toString());
- offset = checkContains(response, offset, "HTTP/1.1 413");
+ checkContains(response, offset, "HTTP/1.1 413");
}
@Test
public void testOversizedResponse() throws Exception
{
- String str = "thisisastringthatshouldreachover1kbytes";
- for (int i=0;i<400;i++)
+ String str = "thisisastringthatshouldreachover1kbytes-";
+ for (int i=0;i<500;i++)
str+="xxxxxxxxxxxx";
final String longstr = str;
@@ -470,7 +469,7 @@ public class HttpConnectionTest
"\015\012"
);
- offset = checkContains(response, offset, "HTTP/1.1 500");
+ checkContains(response, offset, "HTTP/1.1 500");
}
catch(Exception e)
{
@@ -549,7 +548,7 @@ public class HttpConnectionTest
response=connector.getResponses("CONNECT www.webtide.com:8080 HTTP/1.1\n"+
"Host: myproxy:8888\015\012"+
"\015\012");
- offset = checkContains(response,offset,"HTTP/1.1 200");
+ checkContains(response,offset,"HTTP/1.1 200");
}
catch (Exception e)
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java
index 683bf5f5126..661fcde9a65 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java
@@ -57,7 +57,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
private static final String REQUEST1=REQUEST1_HEADER+REQUEST1_CONTENT.getBytes().length+"\n\n"+REQUEST1_CONTENT;
/** The expected response. */
- private static final String RESPONSE1="HTTP/1.1 200 OK\n"+"Connection: close\n"+"Server: Jetty("+Server.getVersion()+")\n"+"\n"+"Hello world\n";
+ private static final String RESPONSE1="HTTP/1.1 200 OK\n"+"Content-Length: 13\n"+"Server: Jetty("+Server.getVersion()+")\n"+"\n"+"Hello world\n";
// Break the request up into three pieces, splitting the header.
private static final String FRAGMENT1=REQUEST1.substring(0,16);
@@ -65,12 +65,12 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
private static final String FRAGMENT3=REQUEST1.substring(34);
/** Second test request. */
- private static final String REQUEST2_HEADER=
+ protected static final String REQUEST2_HEADER=
"POST / HTTP/1.0\n"+
"Host: localhost\n"+
"Content-Type: text/xml;charset=ISO-8859-1\n"+
"Content-Length: ";
- private static final String REQUEST2_CONTENT=
+ protected static final String REQUEST2_CONTENT=
"\n"+
"\n"+
@@ -80,10 +80,10 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
" \n"+
" \n"+
" ";
- private static final String REQUEST2=REQUEST2_HEADER+REQUEST2_CONTENT.getBytes().length+"\n\n"+REQUEST2_CONTENT;
+ protected static final String REQUEST2=REQUEST2_HEADER+REQUEST2_CONTENT.getBytes().length+"\n\n"+REQUEST2_CONTENT;
/** The second expected response. */
- private static final String RESPONSE2_CONTENT=
+ protected static final String RESPONSE2_CONTENT=
"\n"+
"\n"+
@@ -93,7 +93,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
" \n"+
" \n"
+" \n";
- private static final String RESPONSE2=
+ protected static final String RESPONSE2=
"HTTP/1.1 200 OK\n"+
"Content-Type: text/xml;charset=ISO-8859-1\n"+
"Content-Length: "+RESPONSE2_CONTENT.getBytes().length+"\n"+
@@ -143,19 +143,24 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
{
OutputStream os=client.getOutputStream();
- os.write(("GET /R2 HTTP/1.1\015\012"+"Host: localhost\015\012"+"Transfer-Encoding: chunked\015\012"+"Content-Type: text/plain\015\012"
- +"Connection: close\015\012"+"\015\012").getBytes());
+ os.write(("GET /R2 HTTP/1.1\015\012"+
+ "Host: localhost\015\012"+
+ "Transfer-Encoding: chunked\015\012"+
+ "Content-Type: text/plain\015\012"+
+ "Connection: close\015\012"+
+ "\015\012").getBytes());
os.flush();
Thread.sleep(PAUSE);
os.write(("5\015\012").getBytes());
os.flush();
Thread.sleep(PAUSE);
- os.write(("ABCDE\015\012"+"0;\015\012\015\012").getBytes());
+ os.write(("ABCDE\015\012"+
+ "0;\015\012\015\012").getBytes());
os.flush();
// Read the response.
String response=readResponse(client);
- assertTrue(true); // nothing checked yet.
+ assertTrue (response.indexOf("200")>0);
}
finally
{
@@ -221,6 +226,12 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
// Check the response
assertEquals("response "+i,RESPONSE2,response);
}
+ catch(IOException e)
+ {
+ e.printStackTrace();
+ _server.dumpStdErr();
+ throw e;
+ }
finally
{
client.close();
@@ -545,8 +556,8 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
// read and check the times are < 999ms
String[] times=in.readLine().split(",");
-
- // Assert.assertTrue(Integer.valueOf(t).intValue()<999);
+ for (String t: times)
+ Assert.assertTrue(Integer.valueOf(t).intValue()<999);
// read the EOF chunk
@@ -576,7 +587,8 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
// read and check the times are < 999ms
times=in.readLine().split(",");
- //Assert.assertTrue(t,Integer.valueOf(t).intValue()<999);
+ for (String t: times)
+ Assert.assertTrue(t,Integer.valueOf(t).intValue()<999);
// check close
Assert.assertTrue(in.readLine()==null);
@@ -729,6 +741,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
IO.copy(is,bout);
byte[] b=bout.toByteArray();
+ System.err.println("OUTPUT: "+new String(b));
int i=0;
while (b[i]!='Z')
i++;
@@ -926,7 +939,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
Socket client=newSocket(HOST,_connector.getLocalPort());
try
{
- ((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(true);
+ ((StdErrLog)Log.getLogger(AbstractHttpConnection.class)).setHideStacks(true);
OutputStream os=client.getOutputStream();
InputStream is=client.getInputStream();
@@ -954,7 +967,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
}
finally
{
- ((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(false);
+ ((StdErrLog)Log.getLogger(AbstractHttpConnection.class)).setHideStacks(false);
if (!client.isClosed())
client.close();
@@ -1049,7 +1062,6 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
AvailableHandler ah=new AvailableHandler();
configureServer(ah);
- long start=System.currentTimeMillis();
Socket client=newSocket(HOST,_connector.getLocalPort());
try
{
@@ -1136,15 +1148,15 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
* @return The response string.
* @throws IOException in case of I/O problems
*/
- private static String readResponse(Socket client) throws IOException
+ protected static String readResponse(Socket client) throws IOException
{
BufferedReader br=null;
+ StringBuilder sb=new StringBuilder();
try
{
br=new BufferedReader(new InputStreamReader(client.getInputStream()));
- StringBuilder sb=new StringBuilder();
String line;
while ((line=br.readLine())!=null)
@@ -1155,6 +1167,11 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
return sb.toString();
}
+ catch(IOException e)
+ {
+ System.err.println(e+" while reading '"+sb+"'");
+ throw e;
+ }
finally
{
if (br!=null)
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestFixture.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestFixture.java
index 268491098ef..09e1970c3e9 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestFixture.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestFixture.java
@@ -26,7 +26,7 @@ import org.junit.AfterClass;
public class HttpServerTestFixture
{ // Useful constants
protected static final long PAUSE=10L;
- protected static final int LOOPS=Stress.isEnabled()?250:25;
+ protected static final int LOOPS=Stress.isEnabled()?250:50;
protected static final String HOST="localhost";
protected static Server _server;
@@ -36,7 +36,7 @@ public class HttpServerTestFixture
protected Socket newSocket(String host,int port) throws Exception
{
Socket socket = new Socket(host,port);
- socket.setSoTimeout(30000);
+ socket.setSoTimeout(10000);
socket.setTcpNoDelay(true);
socket.setSoLinger(false,0);
return socket;
@@ -189,7 +189,7 @@ public class HttpServerTestFixture
}
// Create a trust manager that does not validate certificate chains
- public static TrustManager[] __trustAllCerts = new TrustManager[] {
+ public final static TrustManager[] __trustAllCerts = new TrustManager[] {
new X509TrustManager(){
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
@@ -203,7 +203,7 @@ public class HttpServerTestFixture
}
};
- public static HostnameVerifier __hostnameverifier = new HostnameVerifier()
+ public final static HostnameVerifier __hostnameverifier = new HostnameVerifier()
{
public boolean verify(String hostname, SSLSession session)
{
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpURITest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpURITest.java
index 3ab42194a01..d75235d40e0 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpURITest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpURITest.java
@@ -27,9 +27,7 @@ import junit.framework.Assert;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.util.MultiMap;
-import org.eclipse.jetty.util.URIUtil;
import org.junit.Test;
-import org.omg.Dynamic.Parameter;
public class HttpURITest
{
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpWriterTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpWriterTest.java
index 73828e81bf1..3d21c413757 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpWriterTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpWriterTest.java
@@ -52,7 +52,7 @@ public class HttpWriterTest
}
@Override
- public long flushBuffer() throws IOException
+ public int flushBuffer() throws IOException
{
return 0;
}
@@ -76,7 +76,7 @@ public class HttpWriterTest
};
- HttpConnection connection = new HttpConnection(null,endp,new Server(),null,generator,null)
+ AbstractHttpConnection connection = new AbstractHttpConnection(null,endp,new Server(),null,generator,null)
{
@Override
public Connection handle() throws IOException
@@ -169,7 +169,7 @@ public class HttpWriterTest
hb.setResponse(200,"OK");
- HttpConnection connection = new HttpConnection(null,endp,new Server(),null,hb,null)
+ AbstractHttpConnection connection = new AbstractHttpConnection(null,endp,new Server(),null,hb,null)
{
@Override
public Connection handle() throws IOException
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncContextTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/LocalAsyncContextTest.java
similarity index 94%
rename from jetty-server/src/test/java/org/eclipse/jetty/server/AsyncContextTest.java
rename to jetty-server/src/test/java/org/eclipse/jetty/server/LocalAsyncContextTest.java
index c0b85eb0a2c..e5b13f6dc52 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncContextTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/LocalAsyncContextTest.java
@@ -31,16 +31,16 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-public class AsyncContextTest
+public class LocalAsyncContextTest
{
protected Server _server = new Server();
protected SuspendHandler _handler = new SuspendHandler();
- protected LocalConnector _connector;
+ protected Connector _connector;
@Before
public void init() throws Exception
{
- _connector = new LocalConnector();
+ _connector = initConnector();
_server.setConnectors(new Connector[]{ _connector });
SessionHandler session = new SessionHandler();
@@ -49,6 +49,11 @@ public class AsyncContextTest
_server.setHandler(session);
_server.start();
}
+
+ protected Connector initConnector()
+ {
+ return new LocalConnector();
+ }
@After
public void destroy() throws Exception
@@ -129,14 +134,21 @@ public class AsyncContextTest
private synchronized String process(String content) throws Exception
{
- String request = "GET / HTTP/1.1\r\n" + "Host: localhost\r\n";
+ String request = "GET / HTTP/1.1\r\n" +
+ "Host: localhost\r\n"+
+ "Connection: close\r\n";
if (content==null)
request+="\r\n";
else
- request+="Content-Length: "+content.length()+"\r\n" + "\r\n" + content;
+ request+="Content-Length: "+content.length()+"\r\n" +"\r\n" + content;
- return _connector.getResponses(request);
+ return getResponse(request);
+ }
+
+ protected String getResponse(String request) throws Exception
+ {
+ return ((LocalConnector)_connector).getResponses(request);
}
private static class SuspendHandler extends HandlerWrapper
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/NetworkTrafficListenerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/NetworkTrafficListenerTest.java
index 551fac58f05..56e8e66b68b 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/NetworkTrafficListenerTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/NetworkTrafficListenerTest.java
@@ -13,6 +13,9 @@
package org.eclipse.jetty.server;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -21,6 +24,7 @@ import java.net.Socket;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
+
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
@@ -33,9 +37,6 @@ import org.eclipse.jetty.server.nio.NetworkTrafficSelectChannelConnector;
import org.junit.After;
import org.junit.Test;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
public class NetworkTrafficListenerTest
{
private static final byte END_OF_CONTENT = '~';
@@ -94,10 +95,10 @@ public class NetworkTrafficListenerTest
// Connect to the server
Socket socket = new Socket("localhost", port);
- assertTrue(openedLatch.await(1, TimeUnit.SECONDS));
-
+ assertTrue(openedLatch.await(10, TimeUnit.SECONDS));
+
socket.close();
- assertTrue(closedLatch.await(1, TimeUnit.SECONDS));
+ assertTrue(closedLatch.await(10, TimeUnit.SECONDS));
}
@Test
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/RFC2616Test.java b/jetty-server/src/test/java/org/eclipse/jetty/server/RFC2616Test.java
index 5492ac5a437..d072621a772 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/RFC2616Test.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/RFC2616Test.java
@@ -29,8 +29,6 @@ import java.util.List;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.StdErrLog;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -723,7 +721,7 @@ public class RFC2616Test
"GET /R2 HTTP/1.0\n"+"Host: localhost\n"+"Connection: close\n"+"\n"+
"GET /R3 HTTP/1.0\n"+"Host: localhost\n"+"Connection: close\n"+"\n");
-
+
offset=checkContains(response,offset,"HTTP/1.1 200 OK\015\012","19.6.2 Keep-alive 1")+1;
offset=checkContains(response,offset,"Connection: keep-alive","19.6.2 Keep-alive 1")+1;
@@ -732,7 +730,6 @@ public class RFC2616Test
offset=checkContains(response,offset,"/R1","19.6.2 Keep-alive 1")+1;
offset=checkContains(response,offset,"HTTP/1.1 200 OK\015\012","19.6.2 Keep-alive 2")+11;
- offset=checkContains(response,offset,"Connection: close","19.6.2 Keep-alive close")+1;
offset=checkContains(response,offset,"/R2","19.6.2 Keep-alive close")+3;
assertEquals("19.6.2 closed",-1,response.indexOf("/R3"));
@@ -756,7 +753,6 @@ public class RFC2616Test
offset=checkContains(response,offset,"ABCDEFGHIJ","19.6.2 Keep-alive 1")+1;
offset=checkContains(response,offset,"HTTP/1.1 200 OK\015\012","19.6.2 Keep-alive 2")+11;
- offset=checkContains(response,offset,"Connection: close","19.6.2 Keep-alive close")+1;
offset=checkContains(response,offset,"/R2","19.6.2 Keep-alive close")+3;
assertEquals("19.6.2 closed",-1,response.indexOf("/R3"));
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java
index a71cc28090d..71cfdcd236f 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java
@@ -492,13 +492,12 @@ public class RequestTest
"\n"
);
assertTrue(response.indexOf("200")>0);
- assertTrue(response.indexOf("Connection: close")>0);
assertTrue(response.indexOf("Hello World")>0);
response=_connector.getResponses(
"GET / HTTP/1.0\n"+
"Host: whatever\n"+
- "Connection: Other, keep-alive\n"+
+ "Connection: Other,,keep-alive\n"+
"\n"
);
assertTrue(response.indexOf("200")>0);
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java
index ecc45ee835e..6f2b1172f44 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java
@@ -29,6 +29,7 @@ import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSessionContext;
@@ -80,7 +81,7 @@ public class ResponseTest
@Test
public void testContentType() throws Exception
{
- HttpConnection connection = new TestHttpConnection(connector,new ByteArrayEndPoint(), connector.getServer());
+ AbstractHttpConnection connection = new TestHttpConnection(connector,new ByteArrayEndPoint(), connector.getServer());
Response response = connection.getResponse();
assertEquals(null,response.getContentType());
@@ -134,7 +135,7 @@ public class ResponseTest
public void testLocale() throws Exception
{
- HttpConnection connection = new TestHttpConnection(connector,new ByteArrayEndPoint(), connector.getServer());
+ AbstractHttpConnection connection = new TestHttpConnection(connector,new ByteArrayEndPoint(), connector.getServer());
Request request = connection.getRequest();
Response response = connection.getResponse();
ContextHandler context = new ContextHandler();
@@ -158,9 +159,8 @@ public class ResponseTest
@Test
public void testContentTypeCharacterEncoding() throws Exception
{
- HttpConnection connection = new TestHttpConnection(connector,new ByteArrayEndPoint(), connector.getServer());
+ AbstractHttpConnection connection = new TestHttpConnection(connector,new ByteArrayEndPoint(), connector.getServer());
- Request request = connection.getRequest();
Response response = connection.getResponse();
@@ -332,7 +332,7 @@ public class ResponseTest
public void testEncodeRedirect()
throws Exception
{
- HttpConnection connection=new TestHttpConnection(connector,new ByteArrayEndPoint(), connector.getServer());
+ AbstractHttpConnection connection=new TestHttpConnection(connector,new ByteArrayEndPoint(), connector.getServer());
Response response = new Response(connection);
Request request = connection.getRequest();
request.setServerName("myhost");
@@ -397,7 +397,7 @@ public class ResponseTest
for (int i=1;i= 0)
- break;
- }
-
- handleCount.set(0);
-
- // Send TCP FIN without SSL close alert
- socket.close();
-
- // Sleep for a while to detect eventual spin looping
- TimeUnit.SECONDS.sleep(1);
-
- Assert.assertTrue("handle() invocations", handleCount.get()<=1);
- Assert.assertTrue("endpoint not closed", endPointClosed.get());
- }
-
- @Test
- public void testTruncationAttackBeforeReading() throws Exception
- {
- Socket socket = new Socket("localhost", connector.getLocalPort());
- SSLSocket sslSocket = (SSLSocket)sslContext.getSocketFactory().createSocket(socket, socket.getInetAddress().getHostName(), socket.getPort(), true);
- sslSocket.setUseClientMode(true);
- final CountDownLatch handshakeLatch = new CountDownLatch(1);
- sslSocket.addHandshakeCompletedListener(new HandshakeCompletedListener()
- {
- public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent)
- {
- handshakeLatch.countDown();
- }
- });
- sslSocket.startHandshake();
-
- Assert.assertTrue(handshakeLatch.await(1, TimeUnit.SECONDS));
-
- String request = "" +
- "GET / HTTP/1.1\r\n" +
- "Host: localhost:" + connector.getLocalPort() + "\r\n" +
- "\r\n";
- sslSocket.getOutputStream().write(request.getBytes("UTF-8"));
-
- // Do not read the response, just close the underlying socket
-
- handleCount.set(0);
-
- // Send TCP FIN without SSL close alert
- socket.close();
-
- // Sleep for a while to detect eventual spin looping
- TimeUnit.SECONDS.sleep(1);
-
- Assert.assertEquals("handle() invocations", 1, handleCount.get());
- Assert.assertTrue("endpoint not closed", endPointClosed.get());
- }
-
- @Test
- public void testTruncationAttackAfterHandshake() throws Exception
- {
- Socket socket = new Socket("localhost", connector.getLocalPort());
- SSLSocket sslSocket = (SSLSocket)sslContext.getSocketFactory().createSocket(socket, socket.getInetAddress().getHostName(), socket.getPort(), true);
- sslSocket.setUseClientMode(true);
- final CountDownLatch handshakeLatch = new CountDownLatch(1);
- sslSocket.addHandshakeCompletedListener(new HandshakeCompletedListener()
- {
- public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent)
- {
- handshakeLatch.countDown();
- }
- });
- sslSocket.startHandshake();
-
- Assert.assertTrue(handshakeLatch.await(1, TimeUnit.SECONDS));
-
- handleCount.set(0);
-
- // Send TCP FIN without SSL close alert
- socket.close();
-
- // Sleep for a while to detect eventual spin looping
- TimeUnit.SECONDS.sleep(1);
-
- Assert.assertTrue("endpoint closed", endPointClosed.get());
- Assert.assertEquals("handle() invocations", 1, handleCount.get());
- }
-
-
- @Test
- public void testTruncationAttackBeforeHandshake() throws Exception
- {
- Socket socket = new Socket("localhost", connector.getLocalPort());
- SSLSocket sslSocket = (SSLSocket)sslContext.getSocketFactory().createSocket(socket, socket.getInetAddress().getHostName(), socket.getPort(), true);
- sslSocket.setUseClientMode(true);
-
- // Wait for the socket to be connected
- TimeUnit.SECONDS.sleep(1);
-
- handleCount.set(0);
-
- // Send TCP FIN without SSL close alert
- socket.close();
-
- // Sleep for a while to detect eventual spin looping
- TimeUnit.SECONDS.sleep(1);
-
- Assert.assertEquals("handle() invocations", 1, handleCount.get());
- Assert.assertTrue("endpoint not closed", endPointClosed.get());
- }
-
- private class EmptyHandler extends AbstractHandler
- {
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- baseRequest.setHandled(true);
- }
- }
-}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslUploadTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslUploadTest.java
index 7bcf8a3e79d..b06acc1ea60 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslUploadTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslUploadTest.java
@@ -15,6 +15,7 @@
package org.eclipse.jetty.server.ssl;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import java.io.FileInputStream;
import java.io.IOException;
@@ -31,11 +32,11 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.http.ssl.SslContextFactory;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -129,6 +130,7 @@ public class SslUploadTest
InputStream in = socket.getInputStream();
String response = IO.toString(in);
+ assertTrue (response.indexOf("200")>0);
// System.err.println(response);
long end = System.nanoTime();
diff --git a/jetty-servlet/pom.xml b/jetty-servlet/pom.xml
index 09908ee58f9..70ab5daf8a3 100644
--- a/jetty-servlet/pom.xml
+++ b/jetty-servlet/pom.xml
@@ -3,7 +3,7 @@
jetty-project
org.eclipse.jetty
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
4.0.0
jetty-servlet
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java
index b6ebf48708f..1f742af5e6d 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java
@@ -22,6 +22,7 @@ import java.net.URL;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
+
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
@@ -39,9 +40,9 @@ import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.WriterOutputStream;
+import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Dispatcher;
-import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.server.HttpOutput;
import org.eclipse.jetty.server.InclusiveByteRange;
import org.eclipse.jetty.server.ResourceCache;
@@ -280,7 +281,8 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
if (h.getServletInstance()==this)
_defaultHolder=h;
- if (LOG.isDebugEnabled()) LOG.debug("resource base = "+_resourceBase);
+ if (LOG.isDebugEnabled())
+ LOG.debug("resource base = "+_resourceBase);
}
/**
@@ -770,7 +772,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
}
else
{
- Connector connector = HttpConnection.getCurrentConnection().getConnector();
+ Connector connector = AbstractHttpConnection.getCurrentConnection().getConnector();
direct=connector instanceof NIOConnector && ((NIOConnector)connector).getUseDirectBuffers() && !(connector instanceof SslConnector);
content_length=content.getContentLength();
}
@@ -786,7 +788,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
// has a filter already written to the response?
written = out instanceof HttpOutput
? ((HttpOutput)out).isWritten()
- : HttpConnection.getCurrentConnection().getGenerator().isWritten();
+ : AbstractHttpConnection.getCurrentConnection().getGenerator().isWritten();
}
catch(IllegalStateException e)
{
@@ -809,7 +811,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
if (response instanceof Response)
{
writeOptionHeaders(((Response)response).getHttpFields());
- ((HttpConnection.Output)out).sendContent(content);
+ ((AbstractHttpConnection.Output)out).sendContent(content);
}
else
{
@@ -817,7 +819,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
if (buffer!=null)
{
writeHeaders(response,content,content_length);
- ((HttpConnection.Output)out).sendContent(buffer);
+ ((AbstractHttpConnection.Output)out).sendContent(buffer);
}
else
{
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java
index af9629ce146..ada696e330e 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java
@@ -18,14 +18,15 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Dispatcher;
-import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ErrorHandler;
@@ -63,7 +64,7 @@ public class ErrorPageErrorHandler extends ErrorHandler
String method = request.getMethod();
if(!method.equals(HttpMethods.GET) && !method.equals(HttpMethods.POST) && !method.equals(HttpMethods.HEAD))
{
- HttpConnection.getCurrentConnection().getRequest().setHandled(true);
+ AbstractHttpConnection.getCurrentConnection().getRequest().setHandled(true);
return;
}
if (_errorPages!=null)
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterHolder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterHolder.java
index a4fd20c328e..937dba53f18 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterHolder.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterHolder.java
@@ -19,12 +19,12 @@ import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
-import org.eclipse.jetty.server.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterConfig;
-import org.eclipse.jetty.servlet.api.FilterRegistration;
import javax.servlet.ServletException;
+import org.eclipse.jetty.server.DispatcherType;
+import org.eclipse.jetty.servlet.api.FilterRegistration;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java
index bef03e29e15..7bd6559d6d8 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java
@@ -14,17 +14,14 @@
package org.eclipse.jetty.servlet;
import java.io.IOException;
-import java.util.Arrays;
import java.util.EnumSet;
-import org.eclipse.jetty.server.DispatcherType;
-
import org.eclipse.jetty.http.PathMap;
+import org.eclipse.jetty.server.DispatcherType;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.component.AggregateLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
-import org.eclipse.jetty.util.log.Log;
public class FilterMapping implements Dumpable
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Holder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Holder.java
index e1be344bdcf..cbbbb02ec9b 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Holder.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Holder.java
@@ -21,11 +21,11 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import org.eclipse.jetty.servlet.api.Registration;
import javax.servlet.ServletContext;
import javax.servlet.UnavailableException;
import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.servlet.api.Registration;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.component.AggregateLifeCycle;
@@ -82,7 +82,8 @@ public class Holder extends AbstractLifeCycle implements Dumpable
try
{
_class=Loader.loadClass(Holder.class, _className);
- if(LOG.isDebugEnabled())LOG.debug("Holding {}",_class);
+ if(LOG.isDebugEnabled())
+ LOG.debug("Holding {}",_class);
}
catch (Exception e)
{
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Invoker.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Invoker.java
index 9a378264186..b4c0ca6a442 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Invoker.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Invoker.java
@@ -26,9 +26,9 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Dispatcher;
import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.HandlerWrapper;
@@ -140,7 +140,8 @@ public class Invoker extends HttpServlet
{
// Found a named servlet (from a user's web.xml file) so
// now we add a mapping for it
- LOG.debug("Adding servlet mapping for named servlet:"+servlet+":"+URIUtil.addPaths(servlet_path,servlet)+"/*");
+ if (LOG.isDebugEnabled())
+ LOG.debug("Adding servlet mapping for named servlet:"+servlet+":"+URIUtil.addPaths(servlet_path,servlet)+"/*");
ServletMapping mapping = new ServletMapping();
mapping.setServletName(servlet);
mapping.setPathSpec(URIUtil.addPaths(servlet_path,servlet)+"/*");
@@ -174,7 +175,8 @@ public class Invoker extends HttpServlet
else
{
// Make a holder
- LOG.debug("Making new servlet="+servlet+" with path="+path+"/*");
+ if (LOG.isDebugEnabled())
+ LOG.debug("Making new servlet="+servlet+" with path="+path+"/*");
holder=_servletHandler.addServletWithMapping(servlet, path+"/*");
if (_parameters!=null)
@@ -211,7 +213,7 @@ public class Invoker extends HttpServlet
}
}
- if (_verbose)
+ if (_verbose && LOG.isDebugEnabled())
LOG.debug("Dynamic load '"+servlet+"' at "+path);
}
}
@@ -219,7 +221,7 @@ public class Invoker extends HttpServlet
if (holder!=null)
{
- final Request baseRequest=(request instanceof Request)?((Request)request):HttpConnection.getCurrentConnection().getRequest();
+ final Request baseRequest=(request instanceof Request)?((Request)request):AbstractHttpConnection.getCurrentConnection().getRequest();
holder.handle(baseRequest,
new InvokedRequest(request,included,servlet,servlet_path,path_info),
response);
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
index 72de75cf444..1a5e485f216 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
@@ -18,7 +18,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Queue;
@@ -26,7 +25,6 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentMap;
-import org.eclipse.jetty.server.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.RequestDispatcher;
@@ -46,8 +44,9 @@ import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.io.RuntimeIOException;
import org.eclipse.jetty.security.IdentityService;
import org.eclipse.jetty.security.SecurityHandler;
+import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Dispatcher;
-import org.eclipse.jetty.server.HttpConnection;
+import org.eclipse.jetty.server.DispatcherType;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServletRequestHttpWrapper;
@@ -390,27 +389,24 @@ public class ServletHandler extends ScopedHandler
}
if (LOG.isDebugEnabled())
- LOG.debug("servlet {} -> {}",baseRequest.getContextPath()+"|"+baseRequest.getServletPath()+"|"+baseRequest.getPathInfo(),servlet_holder);
+ LOG.debug("servlet {}|{}|{} -> {}",baseRequest.getContextPath(),baseRequest.getServletPath(),baseRequest.getPathInfo(),servlet_holder);
try
{
// Do the filter/handling thang
- if (servlet_holder!=null)
- {
- old_scope=baseRequest.getUserIdentityScope();
- baseRequest.setUserIdentityScope(servlet_holder);
+ old_scope=baseRequest.getUserIdentityScope();
+ baseRequest.setUserIdentityScope(servlet_holder);
- // start manual inline of nextScope(target,baseRequest,request,response);
- if (never())
- nextScope(target,baseRequest,request,response);
- else if (_nextScope!=null)
- _nextScope.doScope(target,baseRequest,request, response);
- else if (_outerScope!=null)
- _outerScope.doHandle(target,baseRequest,request, response);
- else
- doHandle(target,baseRequest,request, response);
- // end manual inline (pathentic attempt to reduce stack depth)
- }
+ // start manual inline of nextScope(target,baseRequest,request,response);
+ if (never())
+ nextScope(target,baseRequest,request,response);
+ else if (_nextScope!=null)
+ _nextScope.doScope(target,baseRequest,request, response);
+ else if (_outerScope!=null)
+ _outerScope.doHandle(target,baseRequest,request, response);
+ else
+ doHandle(target,baseRequest,request, response);
+ // end manual inline (pathentic attempt to reduce stack depth)
}
finally
{
@@ -455,13 +451,16 @@ public class ServletHandler extends ScopedHandler
}
}
- LOG.debug("chain=",chain);
+ LOG.debug("chain={}",chain);
try
{
if (servlet_holder==null)
{
- notFound(request, response);
+ if (getHandler()==null)
+ notFound(request, response);
+ else
+ nextHandle(target,baseRequest,request,response);
}
else
{
@@ -1231,7 +1230,8 @@ public class ServletHandler extends ScopedHandler
HttpServletResponse response)
throws IOException
{
- if(LOG.isDebugEnabled())LOG.debug("Not Found "+request.getRequestURI());
+ if(LOG.isDebugEnabled())
+ LOG.debug("Not Found "+request.getRequestURI());
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
@@ -1318,7 +1318,9 @@ public class ServletHandler extends ScopedHandler
/* ------------------------------------------------------------ */
public void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException
- {
+ {
+ final Request baseRequest=(request instanceof Request)?((Request)request):AbstractHttpConnection.getCurrentConnection().getRequest();
+
// pass to next filter
if (_filterHolder!=null)
{
@@ -1329,7 +1331,6 @@ public class ServletHandler extends ScopedHandler
filter.doFilter(request, response, _next);
else
{
- final Request baseRequest=(request instanceof Request)?((Request)request):HttpConnection.getCurrentConnection().getRequest();
final boolean suspendable=baseRequest.isAsyncSupported();
if (suspendable)
{
@@ -1350,15 +1351,20 @@ public class ServletHandler extends ScopedHandler
}
// Call servlet
+
+ HttpServletRequest srequest = (HttpServletRequest)request;
if (_servletHolder != null)
{
if (LOG.isDebugEnabled())
LOG.debug("call servlet " + _servletHolder);
- final Request baseRequest=(request instanceof Request)?((Request)request):HttpConnection.getCurrentConnection().getRequest();
_servletHolder.handle(baseRequest,request, response);
}
- else // Not found
- notFound((HttpServletRequest)request, (HttpServletResponse)response);
+ else if (getHandler()==null)
+ notFound(srequest, (HttpServletResponse)response);
+ else
+ nextHandle(URIUtil.addPaths(srequest.getServletPath(),srequest.getPathInfo()),
+ baseRequest,srequest,(HttpServletResponse)response);
+
}
public String toString()
@@ -1392,13 +1398,15 @@ public class ServletHandler extends ScopedHandler
public void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException
{
- if (LOG.isDebugEnabled()) LOG.debug("doFilter " + _filter);
+ if (LOG.isDebugEnabled())
+ LOG.debug("doFilter " + _filter);
// pass to next filter
if (_filter < LazyList.size(_chain))
{
FilterHolder holder= (FilterHolder)LazyList.get(_chain, _filter++);
- if (LOG.isDebugEnabled()) LOG.debug("call filter " + holder);
+ if (LOG.isDebugEnabled())
+ LOG.debug("call filter " + holder);
Filter filter= holder.getFilter();
if (holder.isAsyncSupported() || !_baseRequest.isAsyncSupported())
@@ -1422,13 +1430,21 @@ public class ServletHandler extends ScopedHandler
}
// Call servlet
+ HttpServletRequest srequest = (HttpServletRequest)request;
if (_servletHolder != null)
{
- if (LOG.isDebugEnabled()) LOG.debug("call servlet " + _servletHolder);
+ if (LOG.isDebugEnabled())
+ LOG.debug("call servlet " + _servletHolder);
_servletHolder.handle(_baseRequest,request, response);
}
- else // Not found
- notFound((HttpServletRequest)request, (HttpServletResponse)response);
+ else if (getHandler()==null)
+ notFound(srequest, (HttpServletResponse)response);
+ else
+ {
+ Request baseRequest=(request instanceof Request)?((Request)request):AbstractHttpConnection.getCurrentConnection().getRequest();
+ nextHandle(URIUtil.addPaths(srequest.getServletPath(),srequest.getPathInfo()),
+ baseRequest,srequest,(HttpServletResponse)response);
+ }
}
/* ------------------------------------------------------------ */
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java
index 1bcbe0822fd..59299c608c4 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java
@@ -25,21 +25,20 @@ import java.util.Map;
import java.util.Set;
import java.util.Stack;
-
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
-import org.eclipse.jetty.servlet.api.ServletRegistration;
-
import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.SingleThreadModel;
import javax.servlet.UnavailableException;
+
import org.eclipse.jetty.security.IdentityService;
import org.eclipse.jetty.security.RunAsToken;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.UserIdentity;
+import org.eclipse.jetty.servlet.api.ServletRegistration;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/listener/ELContextCleaner.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/listener/ELContextCleaner.java
index 6dd03442b81..285de0f3035 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/listener/ELContextCleaner.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/listener/ELContextCleaner.java
@@ -14,8 +14,6 @@
package org.eclipse.jetty.servlet.listener;
import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java
index 4a07b031192..4a4f2fad1b5 100644
--- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java
+++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java
@@ -1,8 +1,11 @@
package org.eclipse.jetty.servlet;
+import static org.junit.Assert.assertTrue;
+
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
+
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
@@ -11,6 +14,7 @@ import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import junit.framework.AssertionFailedError;
+
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.toolchain.test.FS;
@@ -25,8 +29,6 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
-import static org.junit.Assert.assertTrue;
-
public class DefaultServletTest
{
@Rule
diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DispatcherTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DispatcherTest.java
index c034633d125..b17796f0d4d 100644
--- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DispatcherTest.java
+++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DispatcherTest.java
@@ -13,14 +13,13 @@
package org.eclipse.jetty.servlet;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
import java.io.IOException;
-import java.io.PrintWriter;
-import java.net.HttpRetryException;
import java.util.Arrays;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
@@ -30,7 +29,6 @@ import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
-import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestWrapper;
import javax.servlet.ServletResponse;
@@ -52,12 +50,8 @@ import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
public class DispatcherTest
{
private Server _server;
diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InvokerTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InvokerTest.java
index 1456e80cb53..ae9da69e67a 100644
--- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InvokerTest.java
+++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InvokerTest.java
@@ -13,7 +13,10 @@
package org.eclipse.jetty.servlet;
+import static org.junit.Assert.assertEquals;
+
import java.io.IOException;
+
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
@@ -26,8 +29,6 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import static org.junit.Assert.assertEquals;
-
/**
*
*/
diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/StatisticsServletTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/StatisticsServletTest.java
index 7154d32acaa..d775512cb7f 100644
--- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/StatisticsServletTest.java
+++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/StatisticsServletTest.java
@@ -13,6 +13,7 @@
package org.eclipse.jetty.servlet;
import junit.framework.AssertionFailedError;
+
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.StatisticsHandler;
diff --git a/jetty-servlets/pom.xml b/jetty-servlets/pom.xml
index a1e809a71b5..9e112abff9e 100644
--- a/jetty-servlets/pom.xml
+++ b/jetty-servlets/pom.xml
@@ -3,7 +3,7 @@
jetty-project
org.eclipse.jetty
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
4.0.0
jetty-servlets
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CGI.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CGI.java
index 0c6fe30bbc8..8df44021880 100644
--- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CGI.java
+++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CGI.java
@@ -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;
@@ -34,27 +34,26 @@ import org.eclipse.jetty.util.log.Logger;
//-----------------------------------------------------------------------------
/**
* CGI Servlet.
- *
- * The cgi bin directory can be set with the "cgibinResourceBase" init parameter
- * or it will default to the resource base of the context.
- *
- * The "commandPrefix" init parameter may be used to set a prefix to all
- * commands passed to exec. This can be used on systems that need assistance to
- * execute a particular file type. For example on windows this can be set to
- * "perl" so that perl scripts are executed.
- *
- * The "Path" init param is passed to the exec environment as PATH. Note: Must
- * be run unpacked somewhere in the filesystem.
- *
- * Any initParameter that starts with ENV_ is used to set an environment
- * variable with the name stripped of the leading ENV_ and using the init
- * parameter value.
- *
- *
- *
+ *
+ * The cgi bin directory can be set with the "cgibinResourceBase" init parameter or it will default to the resource base of the context. If the
+ * "cgibinResourceBaseIsRelative" init parameter is set the resource base is relative to the webapp. For example "WEB-INF/cgi" would work.
+ *
+ * Not that this only works for extracted war files as "jar cf" will not reserve the execute permissions on the cgi files.
+ *
+ * The "commandPrefix" init parameter may be used to set a prefix to all commands passed to exec. This can be used on systems that need assistance to execute a
+ * particular file type. For example on windows this can be set to "perl" so that perl scripts are executed.
+ *
+ * The "Path" init param is passed to the exec environment as PATH. Note: Must be run unpacked somewhere in the filesystem.
+ *
+ * Any initParameter that starts with ENV_ is used to set an environment variable with the name stripped of the leading ENV_ and using the init parameter value.
*/
public class CGI extends HttpServlet
{
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6182088932884791073L;
+
private static final Logger LOG = Log.getLogger(CGI.class);
private boolean _ok;
@@ -63,81 +62,89 @@ public class CGI extends HttpServlet
private String _cmdPrefix;
private EnvList _env;
private boolean _ignoreExitState;
+ private boolean _relative;
/* ------------------------------------------------------------ */
+ @Override
public void init() throws ServletException
{
- _env=new EnvList();
- _cmdPrefix=getInitParameter("commandPrefix");
+ _env = new EnvList();
+ _cmdPrefix = getInitParameter("commandPrefix");
+ _relative = Boolean.parseBoolean(getInitParameter("cgibinResourceBaseIsRelative"));
- String tmp=getInitParameter("cgibinResourceBase");
- if (tmp==null)
+ String tmp = getInitParameter("cgibinResourceBase");
+ if (tmp == null)
{
- tmp=getInitParameter("resourceBase");
- if (tmp==null)
- tmp=getServletContext().getRealPath("/");
+ tmp = getInitParameter("resourceBase");
+ if (tmp == null)
+ tmp = getServletContext().getRealPath("/");
+ }
+ else if (_relative)
+ {
+ tmp = getServletContext().getRealPath(tmp);
}
- if (tmp==null)
+ if (tmp == null)
{
LOG.warn("CGI: no CGI bin !");
return;
}
- File dir=new File(tmp);
+ File dir = new File(tmp);
if (!dir.exists())
{
- LOG.warn("CGI: CGI bin does not exist - "+dir);
+ LOG.warn("CGI: CGI bin does not exist - " + dir);
return;
}
if (!dir.canRead())
{
- LOG.warn("CGI: CGI bin is not readable - "+dir);
+ LOG.warn("CGI: CGI bin is not readable - " + dir);
return;
}
if (!dir.isDirectory())
{
- LOG.warn("CGI: CGI bin is not a directory - "+dir);
+ LOG.warn("CGI: CGI bin is not a directory - " + dir);
return;
}
try
{
- _docRoot=dir.getCanonicalFile();
+ _docRoot = dir.getCanonicalFile();
}
catch (IOException e)
{
- LOG.warn("CGI: CGI bin failed - "+dir,e);
+ LOG.warn("CGI: CGI bin failed - " + dir,e);
return;
}
- _path=getInitParameter("Path");
- if (_path!=null)
+ _path = getInitParameter("Path");
+ if (_path != null)
_env.set("PATH",_path);
- _ignoreExitState="true".equalsIgnoreCase(getInitParameter("ignoreExitState"));
- Enumeration e=getInitParameterNames();
+ _ignoreExitState = "true".equalsIgnoreCase(getInitParameter("ignoreExitState"));
+ Enumeration e = getInitParameterNames();
while (e.hasMoreElements())
{
- String n=(String)e.nextElement();
- if (n!=null&&n.startsWith("ENV_"))
+ String n = (String)e.nextElement();
+ if (n != null && n.startsWith("ENV_"))
_env.set(n.substring(4),getInitParameter(n));
}
- if(!_env.envMap.containsKey("SystemRoot"))
+ if (!_env.envMap.containsKey("SystemRoot"))
{
- String os = System.getProperty("os.name");
- if (os!=null && os.toLowerCase().indexOf("windows")!=-1)
+ String os = System.getProperty("os.name");
+ if (os != null && os.toLowerCase().indexOf("windows") != -1)
{
- _env.set("SystemRoot", "C:\\WINDOWS");
+ _env.set("SystemRoot","C:\\WINDOWS");
}
- }
-
- _ok=true;
+ }
+
+ _ok = true;
}
/* ------------------------------------------------------------ */
+ @Override
public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
{
if (!_ok)
@@ -145,39 +152,38 @@ public class CGI extends HttpServlet
res.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
return;
}
-
- String pathInContext=StringUtil.nonNull(req.getServletPath())+StringUtil.nonNull(req.getPathInfo());
+ String pathInContext = (_relative?"":StringUtil.nonNull(req.getServletPath())) + StringUtil.nonNull(req.getPathInfo());
if (LOG.isDebugEnabled())
{
- LOG.debug("CGI: ContextPath : "+req.getContextPath());
- LOG.debug("CGI: ServletPath : "+req.getServletPath());
- LOG.debug("CGI: PathInfo : "+req.getPathInfo());
- LOG.debug("CGI: _docRoot : "+_docRoot);
- LOG.debug("CGI: _path : "+_path);
- LOG.debug("CGI: _ignoreExitState: "+_ignoreExitState);
+ LOG.debug("CGI: ContextPath : " + req.getContextPath());
+ LOG.debug("CGI: ServletPath : " + req.getServletPath());
+ LOG.debug("CGI: PathInfo : " + req.getPathInfo());
+ LOG.debug("CGI: _docRoot : " + _docRoot);
+ LOG.debug("CGI: _path : " + _path);
+ LOG.debug("CGI: _ignoreExitState: " + _ignoreExitState);
}
// pathInContext may actually comprises scriptName/pathInfo...We will
// walk backwards up it until we find the script - the rest must
// be the pathInfo;
- String both=pathInContext;
- String first=both;
- String last="";
+ String both = pathInContext;
+ String first = both;
+ String last = "";
- File exe=new File(_docRoot,first);
+ File exe = new File(_docRoot,first);
- while ((first.endsWith("/")||!exe.exists())&&first.length()>=0)
+ while ((first.endsWith("/") || !exe.exists()) && first.length() >= 0)
{
- int index=first.lastIndexOf('/');
+ int index = first.lastIndexOf('/');
- first=first.substring(0,index);
- last=both.substring(index,both.length());
- exe=new File(_docRoot,first);
+ first = first.substring(0,index);
+ last = both.substring(index,both.length());
+ exe = new File(_docRoot,first);
}
- if (first.length()==0||!exe.exists()||exe.isDirectory()||!exe.getCanonicalPath().equals(exe.getAbsolutePath()))
+ if (first.length() == 0 || !exe.exists() || exe.isDirectory() || !exe.getCanonicalPath().equals(exe.getAbsolutePath()))
{
res.sendError(404);
}
@@ -185,8 +191,8 @@ public class CGI extends HttpServlet
{
if (LOG.isDebugEnabled())
{
- LOG.debug("CGI: script is "+exe);
- LOG.debug("CGI: pathInfo is "+last);
+ LOG.debug("CGI: script is " + exe);
+ LOG.debug("CGI: pathInfo is " + last);
}
exec(exe,last,req,res);
}
@@ -198,19 +204,19 @@ public class CGI extends HttpServlet
*/
private void exec(File command, String pathInfo, HttpServletRequest req, HttpServletResponse res) throws IOException
{
- String path=command.getAbsolutePath();
- File dir=command.getParentFile();
- String scriptName=req.getRequestURI().substring(0,req.getRequestURI().length()-pathInfo.length());
- String scriptPath=getServletContext().getRealPath(scriptName);
- String pathTranslated=req.getPathTranslated();
+ String path = command.getAbsolutePath();
+ File dir = command.getParentFile();
+ String scriptName = req.getRequestURI().substring(0,req.getRequestURI().length() - pathInfo.length());
+ String scriptPath = getServletContext().getRealPath(scriptName);
+ String pathTranslated = req.getPathTranslated();
- int len=req.getContentLength();
- if (len<0)
- len=0;
- if ((pathTranslated==null)||(pathTranslated.length()==0))
- pathTranslated=path;
+ int len = req.getContentLength();
+ if (len < 0)
+ len = 0;
+ if ((pathTranslated == null) || (pathTranslated.length() == 0))
+ pathTranslated = path;
- EnvList env=new EnvList(_env);
+ EnvList env = new EnvList(_env);
// these ones are from "The WWW Common Gateway Interface Version 1.1"
// look at :
// http://Web.Golux.Com/coar/cgi/draft-coar-cgi-v11-03-clean.html#6.1.1
@@ -218,7 +224,7 @@ public class CGI extends HttpServlet
env.set("CONTENT_LENGTH",Integer.toString(len));
env.set("CONTENT_TYPE",req.getContentType());
env.set("GATEWAY_INTERFACE","CGI/1.1");
- if ((pathInfo!=null)&&(pathInfo.length()>0))
+ if ((pathInfo != null) && (pathInfo.length() > 0))
{
env.set("PATH_INFO",pathInfo);
}
@@ -240,12 +246,12 @@ public class CGI extends HttpServlet
env.set("SERVER_PROTOCOL",req.getProtocol());
env.set("SERVER_SOFTWARE",getServletContext().getServerInfo());
- Enumeration enm=req.getHeaderNames();
+ Enumeration enm = req.getHeaderNames();
while (enm.hasMoreElements())
{
- String name=(String)enm.nextElement();
- String value=req.getHeader(name);
- env.set("HTTP_"+name.toUpperCase().replace('-','_'),value);
+ String name = (String)enm.nextElement();
+ String value = req.getHeader(name);
+ env.set("HTTP_" + name.toUpperCase().replace('-','_'),value);
}
// these extra ones were from printenv on www.dev.nomura.co.uk
@@ -257,28 +263,28 @@ public class CGI extends HttpServlet
// are we meant to decode args here ? or does the script get them
// via PATH_INFO ? if we are, they should be decoded and passed
// into exec here...
- String execCmd=path;
- if ((execCmd.charAt(0)!='"')&&(execCmd.indexOf(" ")>=0))
- execCmd="\""+execCmd+"\"";
- if (_cmdPrefix!=null)
- execCmd=_cmdPrefix+" "+execCmd;
+ String execCmd = path;
+ if ((execCmd.charAt(0) != '"') && (execCmd.indexOf(" ") >= 0))
+ execCmd = "\"" + execCmd + "\"";
+ if (_cmdPrefix != null)
+ execCmd = _cmdPrefix + " " + execCmd;
- Process p=(dir==null)?Runtime.getRuntime().exec(execCmd,env.getEnvArray()):Runtime.getRuntime().exec(execCmd,env.getEnvArray(),dir);
+ Process p = (dir == null)?Runtime.getRuntime().exec(execCmd,env.getEnvArray()):Runtime.getRuntime().exec(execCmd,env.getEnvArray(),dir);
// hook processes input to browser's output (async)
- final InputStream inFromReq=req.getInputStream();
- final OutputStream outToCgi=p.getOutputStream();
- final int inLength=len;
+ final InputStream inFromReq = req.getInputStream();
+ final OutputStream outToCgi = p.getOutputStream();
+ final int inLength = len;
IO.copyThread(p.getErrorStream(),System.err);
-
+
new Thread(new Runnable()
{
public void run()
{
try
{
- if (inLength>0)
+ if (inLength > 0)
IO.copy(inFromReq,outToCgi,inLength);
outToCgi.close();
}
@@ -296,28 +302,28 @@ public class CGI extends HttpServlet
{
// read any headers off the top of our input stream
// NOTE: Multiline header items not supported!
- String line=null;
- InputStream inFromCgi=p.getInputStream();
+ String line = null;
+ InputStream inFromCgi = p.getInputStream();
- //br=new BufferedReader(new InputStreamReader(inFromCgi));
- //while ((line=br.readLine())!=null)
- while( (line = getTextLineFromStream( inFromCgi )).length() > 0 )
+ // br=new BufferedReader(new InputStreamReader(inFromCgi));
+ // while ((line=br.readLine())!=null)
+ while ((line = getTextLineFromStream(inFromCgi)).length() > 0)
{
if (!line.startsWith("HTTP"))
{
- int k=line.indexOf(':');
- if (k>0)
+ int k = line.indexOf(':');
+ if (k > 0)
{
- String key=line.substring(0,k).trim();
- String value = line.substring(k+1).trim();
+ String key = line.substring(0,k).trim();
+ String value = line.substring(k + 1).trim();
if ("Location".equals(key))
{
res.sendRedirect(res.encodeRedirectURL(value));
}
else if ("Status".equals(key))
{
- String[] token = value.split( " " );
- int status=Integer.parseInt(token[0]);
+ String[] token = value.split(" ");
+ int status = Integer.parseInt(token[0]);
res.setStatus(status);
}
else
@@ -330,15 +336,15 @@ public class CGI extends HttpServlet
}
// copy cgi content to response stream...
os = res.getOutputStream();
- IO.copy(inFromCgi, os);
+ IO.copy(inFromCgi,os);
p.waitFor();
if (!_ignoreExitState)
{
- int exitValue=p.exitValue();
- if (0!=exitValue)
+ int exitValue = p.exitValue();
+ if (0 != exitValue)
{
- LOG.warn("Non-zero exit status ("+exitValue+") from CGI program: "+path);
+ LOG.warn("Non-zero exit status (" + exitValue + ") from CGI program: " + path);
if (!res.isCommitted())
res.sendError(500,"Failed to exec CGI");
}
@@ -356,13 +362,13 @@ public class CGI extends HttpServlet
}
finally
{
- if( os != null )
+ if (os != null)
{
try
{
os.close();
}
- catch(Exception e)
+ catch (Exception e)
{
LOG.ignore(e);
}
@@ -375,19 +381,24 @@ public class CGI extends HttpServlet
/**
* Utility method to get a line of text from the input stream.
- * @param is the input stream
+ *
+ * @param is
+ * the input stream
* @return the line of text
* @throws IOException
*/
- private String getTextLineFromStream( InputStream is ) throws IOException {
+ private String getTextLineFromStream(InputStream is) throws IOException
+ {
StringBuilder buffer = new StringBuilder();
int b;
- while( (b = is.read()) != -1 && b != (int) '\n' ) {
- buffer.append( (char) b );
- }
- return buffer.toString().trim();
+ while ((b = is.read()) != -1 && b != '\n')
+ {
+ buffer.append((char)b);
+ }
+ return buffer.toString().trim();
}
+
/* ------------------------------------------------------------ */
/**
* private utility class that manages the Environment passed to exec.
@@ -398,12 +409,12 @@ public class CGI extends HttpServlet
EnvList()
{
- envMap=new HashMap();
+ envMap = new HashMap();
}
EnvList(EnvList l)
{
- envMap=new HashMap(l.envMap);
+ envMap = new HashMap(l.envMap);
}
/**
@@ -411,7 +422,7 @@ public class CGI extends HttpServlet
*/
public void set(String name, String value)
{
- envMap.put(name,name+"="+StringUtil.nonNull(value));
+ envMap.put(name,name + "=" + StringUtil.nonNull(value));
}
/** Get representation suitable for passing to exec. */
@@ -420,6 +431,7 @@ public class CGI extends HttpServlet
return (String[])envMap.values().toArray(new String[envMap.size()]);
}
+ @Override
public String toString()
{
return envMap.toString();
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CloseableDoSFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CloseableDoSFilter.java
index 0bec5df794e..9b2b659dcff 100644
--- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CloseableDoSFilter.java
+++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CloseableDoSFilter.java
@@ -18,7 +18,7 @@ import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.server.HttpConnection;
+import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -37,7 +37,7 @@ public class CloseableDoSFilter extends DoSFilter
{
try
{
- Request base_request=(request instanceof Request)?(Request)request:HttpConnection.getCurrentConnection().getRequest();
+ Request base_request=(request instanceof Request)?(Request)request:AbstractHttpConnection.getCurrentConnection().getRequest();
base_request.getConnection().getEndPoint().close();
}
catch(IOException e)
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java
index e38c73de306..f4026369372 100644
--- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java
+++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java
@@ -18,6 +18,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
@@ -74,7 +75,7 @@ import org.eclipse.jetty.util.log.Logger;
*/
public class CrossOriginFilter implements Filter
{
- private static final Logger logger = Log.getLogger(CrossOriginFilter.class);
+ private static final Logger LOG = Log.getLogger(CrossOriginFilter.class);
// Request headers
private static final String ORIGIN_HEADER = "Origin";
@@ -145,7 +146,7 @@ public class CrossOriginFilter implements Filter
}
catch (NumberFormatException x)
{
- logger.info("Cross-origin filter, could not parse '{}' parameter as integer: {}", PREFLIGHT_MAX_AGE_PARAM, preflightMaxAgeConfig);
+ LOG.info("Cross-origin filter, could not parse '{}' parameter as integer: {}", PREFLIGHT_MAX_AGE_PARAM, preflightMaxAgeConfig);
}
String allowedCredentialsConfig = config.getInitParameter(ALLOW_CREDENTIALS_PARAM);
@@ -153,12 +154,15 @@ public class CrossOriginFilter implements Filter
allowedCredentialsConfig = "true";
allowCredentials = Boolean.parseBoolean(allowedCredentialsConfig);
- logger.debug("Cross-origin filter configuration: " +
- ALLOWED_ORIGINS_PARAM + " = " + allowedOriginsConfig + ", " +
- ALLOWED_METHODS_PARAM + " = " + allowedMethodsConfig + ", " +
- ALLOWED_HEADERS_PARAM + " = " + allowedHeadersConfig + ", " +
- PREFLIGHT_MAX_AGE_PARAM + " = " + preflightMaxAgeConfig + ", " +
- ALLOW_CREDENTIALS_PARAM + " = " + allowedCredentialsConfig);
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("Cross-origin filter configuration: " +
+ ALLOWED_ORIGINS_PARAM + " = " + allowedOriginsConfig + ", " +
+ ALLOWED_METHODS_PARAM + " = " + allowedMethodsConfig + ", " +
+ ALLOWED_HEADERS_PARAM + " = " + allowedHeadersConfig + ", " +
+ PREFLIGHT_MAX_AGE_PARAM + " = " + preflightMaxAgeConfig + ", " +
+ ALLOW_CREDENTIALS_PARAM + " = " + allowedCredentialsConfig);
+ }
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
@@ -176,23 +180,23 @@ public class CrossOriginFilter implements Filter
{
if (isSimpleRequest(request))
{
- logger.debug("Cross-origin request to {} is a simple cross-origin request", request.getRequestURI());
+ LOG.debug("Cross-origin request to {} is a simple cross-origin request", request.getRequestURI());
handleSimpleResponse(request, response, origin);
}
else if (isPreflightRequest(request))
{
- logger.debug("Cross-origin request to {} is a preflight cross-origin request", request.getRequestURI());
+ LOG.debug("Cross-origin request to {} is a preflight cross-origin request", request.getRequestURI());
handlePreflightResponse(request, response, origin);
}
else
{
- logger.debug("Cross-origin request to {} is a non-simple cross-origin request", request.getRequestURI());
+ LOG.debug("Cross-origin request to {} is a non-simple cross-origin request", request.getRequestURI());
handleSimpleResponse(request, response, origin);
}
}
else
{
- logger.debug("Cross-origin request to " + request.getRequestURI() + " with origin " + origin + " does not match allowed origins " + allowedOrigins);
+ LOG.debug("Cross-origin request to " + request.getRequestURI() + " with origin " + origin + " does not match allowed origins " + allowedOrigins);
}
}
@@ -291,18 +295,18 @@ public class CrossOriginFilter implements Filter
private boolean isMethodAllowed(HttpServletRequest request)
{
String accessControlRequestMethod = request.getHeader(ACCESS_CONTROL_REQUEST_METHOD_HEADER);
- logger.debug("{} is {}", ACCESS_CONTROL_REQUEST_METHOD_HEADER, accessControlRequestMethod);
+ LOG.debug("{} is {}", ACCESS_CONTROL_REQUEST_METHOD_HEADER, accessControlRequestMethod);
boolean result = false;
if (accessControlRequestMethod != null)
result = allowedMethods.contains(accessControlRequestMethod);
- logger.debug("Method {} is" + (result ? "" : " not") + " among allowed methods {}", accessControlRequestMethod, allowedMethods);
+ LOG.debug("Method {} is" + (result ? "" : " not") + " among allowed methods {}", accessControlRequestMethod, allowedMethods);
return result;
}
private boolean areHeadersAllowed(HttpServletRequest request)
{
String accessControlRequestHeaders = request.getHeader(ACCESS_CONTROL_REQUEST_HEADERS_HEADER);
- logger.debug("{} is {}", ACCESS_CONTROL_REQUEST_HEADERS_HEADER, accessControlRequestHeaders);
+ LOG.debug("{} is {}", ACCESS_CONTROL_REQUEST_HEADERS_HEADER, accessControlRequestHeaders);
boolean result = true;
if (accessControlRequestHeaders != null)
{
@@ -325,7 +329,7 @@ public class CrossOriginFilter implements Filter
}
}
}
- logger.debug("Headers [{}] are" + (result ? "" : " not") + " among allowed headers {}", accessControlRequestHeaders, allowedHeaders);
+ LOG.debug("Headers [{}] are" + (result ? "" : " not") + " among allowed headers {}", accessControlRequestHeaders, allowedHeaders);
return result;
}
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java
index 51c94694459..6c12e2e75b3 100644
--- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java
+++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java
@@ -14,13 +14,16 @@
package org.eclipse.jetty.servlets;
import java.io.IOException;
+import java.io.Serializable;
import java.util.HashSet;
+import java.util.Map;
import java.util.Queue;
import java.util.StringTokenizer;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
+
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
@@ -31,8 +34,10 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
+import javax.servlet.http.HttpSessionEvent;
import org.eclipse.jetty.continuation.Continuation;
import org.eclipse.jetty.continuation.ContinuationListener;
@@ -907,13 +912,14 @@ public class DoSFilter implements Filter
* A RateTracker is associated with a connection, and stores request rate
* data.
*/
- class RateTracker extends Timeout.Task implements HttpSessionBindingListener
+ class RateTracker extends Timeout.Task implements HttpSessionBindingListener, HttpSessionActivationListener
{
- protected final String _id;
- protected final int _type;
- protected final long[] _timestamps;
- protected int _next;
-
+ transient protected final String _id;
+ transient protected final int _type;
+ transient protected final long[] _timestamps;
+ transient protected int _next;
+
+
public RateTracker(String id, int type,int maxRequestsPerSecond)
{
_id = id;
@@ -952,25 +958,49 @@ public class DoSFilter implements Filter
public void valueBound(HttpSessionBindingEvent event)
- {
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("Value bound:"+_id);
}
public void valueUnbound(HttpSessionBindingEvent event)
{
- _rateTrackers.remove(_id);
+ //take the tracker out of the list of trackers
+ if (_rateTrackers != null)
+ _rateTrackers.remove(_id);
+ if (LOG.isDebugEnabled()) LOG.debug("Tracker removed: "+_id);
}
+ public void sessionWillPassivate(HttpSessionEvent se)
+ {
+ //take the tracker of the list of trackers (if its still there)
+ //and ensure that we take ourselves out of the session so we are not saved
+ if (_rateTrackers != null)
+ _rateTrackers.remove(_id);
+ se.getSession().removeAttribute(__TRACKER);
+ if (LOG.isDebugEnabled()) LOG.debug("Value removed: "+_id);
+ }
+
+ public void sessionDidActivate(HttpSessionEvent se)
+ {
+ LOG.warn("Unexpected session activation");
+ }
+
+
public void expired()
{
- long now = _trackerTimeoutQ.getNow();
- int latestIndex = _next == 0 ? 3 : (_next - 1 ) % _timestamps.length;
- long last=_timestamps[latestIndex];
- boolean hasRecentRequest = last != 0 && (now-last)<1000L;
+ if (_rateTrackers != null && _trackerTimeoutQ != null)
+ {
+ long now = _trackerTimeoutQ.getNow();
+ int latestIndex = _next == 0 ? 3 : (_next - 1 ) % _timestamps.length;
+ long last=_timestamps[latestIndex];
+ boolean hasRecentRequest = last != 0 && (now-last)<1000L;
- if (hasRecentRequest)
- reschedule();
- else
- _rateTrackers.remove(_id);
+ if (hasRecentRequest)
+ reschedule();
+ else
+ _rateTrackers.remove(_id);
+ }
}
@Override
@@ -978,6 +1008,8 @@ public class DoSFilter implements Filter
{
return "RateTracker/"+_id+"/"+_type;
}
+
+
}
class FixedRateTracker extends RateTracker
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java
index 0084ddaf861..7d9a24ac58a 100644
--- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java
+++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java
@@ -67,10 +67,10 @@ public class IncludableGzipFilter extends GzipFilter
public IncludableResponseWrapper(HttpServletRequest request, HttpServletResponse response)
{
super(request,response);
-
- _mimeTypes = IncludableGzipFilter.this._mimeTypes;
- _bufferSize = IncludableGzipFilter.this._bufferSize;
- _minGzipSize = IncludableGzipFilter.this._minGzipSize;
+
+ super.setMimeTypes(IncludableGzipFilter.this._mimeTypes);
+ super.setBufferSize(IncludableGzipFilter.this._bufferSize);
+ super.setMinGzipSize(IncludableGzipFilter.this._minGzipSize);
}
@Override
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/MultiPartFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/MultiPartFilter.java
index 4111a1de6ff..049f37072b1 100644
--- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/MultiPartFilter.java
+++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/MultiPartFilter.java
@@ -63,6 +63,7 @@ import org.eclipse.jetty.util.TypeUtil;
*/
public class MultiPartFilter implements Filter
{
+ public final static String CONTENT_TYPE_SUFFIX=".org.eclipse.jetty.servlet.contentType";
private final static String FILES ="org.eclipse.jetty.servlet.MultiPartFilter.files";
private File tempdir;
private boolean _deleteFiles;
@@ -132,8 +133,11 @@ public class MultiPartFilter implements Filter
String content_disposition=null;
String content_transfer_encoding=null;
+
outer:while(!lastPart)
{
+ String type_content=null;
+
while(true)
{
// read a line
@@ -155,7 +159,9 @@ public class MultiPartFilter implements Filter
if(key.equals("content-disposition"))
content_disposition=value;
else if(key.equals("content-transfer-encoding"))
- content_transfer_encoding=value;
+ content_transfer_encoding=value;
+ else if (key.equals("content-type"))
+ type_content = value;
}
}
// Extract content-disposition
@@ -207,6 +213,8 @@ public class MultiPartFilter implements Filter
out = new BufferedOutputStream(out, _fileOutputBuffer);
request.setAttribute(name,file);
params.add(name, filename);
+ if (type_content != null)
+ params.add(name+CONTENT_TYPE_SUFFIX, type_content);
if (_deleteFiles)
{
@@ -330,6 +338,8 @@ public class MultiPartFilter implements Filter
{
bytes = ((ByteArrayOutputStream)out).toByteArray();
params.add(name,bytes);
+ if (type_content != null)
+ params.add(name+CONTENT_TYPE_SUFFIX, type_content);
}
}
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java
index c506a82c0e4..2b186b49677 100644
--- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java
+++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java
@@ -27,6 +27,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
+
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
@@ -38,7 +39,6 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.HttpClient;
-import org.eclipse.jetty.client.HttpConnection;
import org.eclipse.jetty.client.HttpExchange;
import org.eclipse.jetty.continuation.Continuation;
import org.eclipse.jetty.continuation.ContinuationSupport;
@@ -49,15 +49,11 @@ import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.PathMap;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.EofException;
-import org.eclipse.jetty.servlet.Holder;
import org.eclipse.jetty.util.HostMap;
import org.eclipse.jetty.util.IO;
-import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.omg.CORBA._PolicyStub;
/**
* Asynchronous Proxy Servlet.
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/AbstractDoSFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/AbstractDoSFilterTest.java
index c2def316972..3774a28bf8f 100644
--- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/AbstractDoSFilterTest.java
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/AbstractDoSFilterTest.java
@@ -1,7 +1,11 @@
package org.eclipse.jetty.servlets;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
import java.io.IOException;
import java.net.Socket;
+
import javax.servlet.Filter;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
@@ -18,9 +22,6 @@ import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
/**
* @version $Revision$ $Date$
*/
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/AsyncProxyServer.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/AsyncProxyServer.java
index 10b93271858..252783d68e8 100644
--- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/AsyncProxyServer.java
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/AsyncProxyServer.java
@@ -16,7 +16,6 @@ package org.eclipse.jetty.servlets;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
-import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder;
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterContentLengthTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterContentLengthTest.java
index 1b83855aa1a..7d1304ad110 100644
--- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterContentLengthTest.java
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterContentLengthTest.java
@@ -5,6 +5,7 @@ import java.util.List;
import javax.servlet.Servlet;
+import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.gzip.GzipResponseWrapper;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.FilterHolder;
@@ -104,7 +105,7 @@ public class GzipFilterContentLengthTest
try
{
tester.start();
- tester.assertIsResponseNotGzipCompressed(filename,filesize);
+ tester.assertIsResponseNotGzipCompressed(filename,filesize,HttpStatus.OK_200);
}
finally
{
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java
index e597c139b1c..0f12e9f27a6 100644
--- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java
@@ -1,5 +1,13 @@
package org.eclipse.jetty.servlets;
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.gzip.GzipResponseWrapper;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.FilterHolder;
@@ -13,6 +21,29 @@ import org.junit.Test;
*/
public class GzipFilterDefaultTest
{
+
+
+ public static class HttpStatusServlet extends HttpServlet
+ {
+ private int _status = 204;
+
+ public HttpStatusServlet()
+ {
+ super();
+ }
+
+ public void setStatus (int status)
+ {
+ _status = status;
+ }
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
+ {
+ resp.setStatus(_status);
+ }
+
+ }
@Rule
public TestingDir testingdir = new TestingDir();
@@ -77,11 +108,33 @@ public class GzipFilterDefaultTest
try
{
tester.start();
- tester.assertIsResponseNotGzipCompressed("file.mp3", filesize);
+ tester.assertIsResponseNotGzipCompressed("file.mp3", filesize, HttpStatus.OK_200);
}
finally
{
tester.stop();
}
}
+
+ @Test
+ public void testIsNotGzipCompressedHttpStatus() throws Exception
+ {
+ GzipTester tester = new GzipTester(testingdir);
+
+ // Test error code 204
+ FilterHolder holder = tester.setContentServlet(HttpStatusServlet.class);
+ holder.setInitParameter("mimeTypes","text/plain");
+
+ try
+ {
+ tester.start();
+ tester.assertIsResponseNotGzipCompressed(null, -1, 204);
+ }
+ finally
+ {
+ tester.stop();
+ }
+
+ }
+
}
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterMinSizeTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterMinSizeTest.java
new file mode 100644
index 00000000000..6e37eb311fb
--- /dev/null
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterMinSizeTest.java
@@ -0,0 +1,85 @@
+// ========================================================================
+// Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+
+package org.eclipse.jetty.servlets;
+
+import javax.servlet.Servlet;
+
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.eclipse.jetty.servlets.gzip.GzipTester;
+import org.eclipse.jetty.servlets.gzip.TestMinGzipSizeServlet;
+import org.eclipse.jetty.toolchain.test.TestingDir;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Perform specific tests on the IncludableGzipFilter's ability to manage
+ * minGzipSize initialization parameter.
+ *
+ * @see http://bugs.eclipse.org/366106
+ */
+public class IncludableGzipFilterMinSizeTest
+{
+ @Rule
+ public TestingDir testdir = new TestingDir();
+
+ private Class extends Servlet> testServlet = TestMinGzipSizeServlet.class;
+
+ @Test
+ public void testUnderMinSize() throws Exception
+ {
+ GzipTester tester = new GzipTester(testdir);
+ // Use IncludableGzipFilter
+ tester.setGzipFilterClass(IncludableGzipFilter.class);
+
+ FilterHolder holder = tester.setContentServlet(testServlet);
+ // A valid mime type that we will never use in this test.
+ // configured here to prevent mimeType==null logic
+ holder.setInitParameter("mimeTypes","application/soap+xml");
+ holder.setInitParameter("minGzipSize", "2048");
+ holder.setInitParameter("uncheckedPrintWriter","true");
+
+ tester.copyTestServerFile("small_script.js");
+
+ try {
+ tester.start();
+ tester.assertIsResponseNotGzipFiltered("small_script.js",
+ "small_script.js.sha1",
+ "text/javascript; charset=utf-8");
+ } finally {
+ tester.stop();
+ }
+ }
+
+ @Test
+ public void testOverMinSize() throws Exception
+ {
+ GzipTester tester = new GzipTester(testdir);
+ // Use IncludableGzipFilter
+ tester.setGzipFilterClass(IncludableGzipFilter.class);
+
+ FilterHolder holder = tester.setContentServlet(testServlet);
+ holder.setInitParameter("mimeTypes","application/soap+xml,text/javascript");
+ holder.setInitParameter("minGzipSize", "2048");
+ holder.setInitParameter("uncheckedPrintWriter","true");
+
+ tester.copyTestServerFile("big_script.js");
+
+ try {
+ tester.start();
+ tester.assertIsResponseGzipCompressed("big_script.js");
+ } finally {
+ tester.stop();
+ }
+ }
+}
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/MultipartFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/MultipartFilterTest.java
index 2dc3048024c..0dfd6f17bf8 100644
--- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/MultipartFilterTest.java
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/MultipartFilterTest.java
@@ -15,6 +15,7 @@ package org.eclipse.jetty.servlets;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertNotNull;
import java.io.File;
import java.io.FileInputStream;
@@ -39,6 +40,21 @@ public class MultipartFilterTest
private File _dir;
private ServletTester tester;
+
+ public static class TestServlet extends DumpServlet
+ {
+
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
+ {
+ 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
{
@@ -51,7 +67,7 @@ public class MultipartFilterTest
tester=new ServletTester();
tester.setContextPath("/context");
tester.setResourceBase(_dir.getCanonicalPath());
- tester.addServlet(DumpServlet.class, "/");
+ tester.addServlet(TestServlet.class, "/");
FilterHolder multipartFilter = tester.addFilter(MultiPartFilter.class,"/*",FilterMapping.DEFAULT);
multipartFilter.setInitParameter("deleteFiles", "true");
tester.start();
@@ -93,6 +109,7 @@ public class MultipartFilterTest
assertTrue(response.getMethod()==null);
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
}
+
@Test
public void testPost() throws Exception
@@ -124,6 +141,7 @@ public class MultipartFilterTest
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
assertTrue(response.getContent().indexOf("brown cow")>=0);
}
+
@Test
public void testEncodedPost() throws Exception
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PutFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PutFilterTest.java
index 2b158eb6e87..c92cc007f80 100644
--- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PutFilterTest.java
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PutFilterTest.java
@@ -13,6 +13,9 @@
package org.eclipse.jetty.servlets;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
@@ -21,6 +24,7 @@ import java.net.URL;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
+
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.servlet.FilterHolder;
@@ -31,9 +35,6 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
public class PutFilterTest
{
private File _dir;
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/QoSFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/QoSFilterTest.java
index f84b14367f8..85141c21852 100644
--- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/QoSFilterTest.java
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/QoSFilterTest.java
@@ -12,10 +12,14 @@
// ========================================================================
package org.eclipse.jetty.servlets;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
@@ -34,9 +38,6 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
public class QoSFilterTest
{
private static final Logger LOG = Log.getLogger(QoSFilterTest.class);
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java
index 722e907a20e..2c72e5eb6ed 100644
--- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java
@@ -32,6 +32,7 @@ import org.junit.Assert;
public class GzipTester
{
+ private Class extends GzipFilter> gzipFilterClass = GzipFilter.class;
private String encoding = "ISO8859_1";
private ServletTester servletTester;
private TestingDir testdir;
@@ -198,7 +199,7 @@ public class GzipTester
* passing -1 will disable the Content-Length assertion)
* @throws Exception
*/
- public void assertIsResponseNotGzipCompressed(String filename, int expectedFilesize) throws Exception
+ public void assertIsResponseNotGzipCompressed(String filename, int expectedFilesize, int status) throws Exception
{
System.err.printf("[GzipTester] requesting /context/%s%n",filename);
HttpTester request = new HttpTester();
@@ -208,7 +209,10 @@ public class GzipTester
request.setVersion("HTTP/1.0");
request.setHeader("Host","tester");
request.setHeader("Accept-Encoding","gzip");
- request.setURI("/context/" + filename);
+ if (filename == null)
+ request.setURI("/context/");
+ else
+ request.setURI("/context/"+filename);
// Issue the request
ByteArrayBuffer reqsBuff = new ByteArrayBuffer(request.generate().getBytes());
@@ -218,7 +222,7 @@ public class GzipTester
// Assert the response headers
Assert.assertThat("Response.method",response.getMethod(),nullValue());
- Assert.assertThat("Response.status",response.getStatus(),is(HttpServletResponse.SC_OK));
+ Assert.assertThat("Response.status",response.getStatus(),is(status));
if (expectedFilesize != (-1))
{
Assert.assertThat("Response.header[Content-Length]",response.getHeader("Content-Length"),notNullValue());
@@ -226,29 +230,35 @@ public class GzipTester
Assert.assertThat("Response.header[Content-Length]",serverLength,is(expectedFilesize));
}
Assert.assertThat("Response.header[Content-Encoding]",response.getHeader("Content-Encoding"),not(containsString("gzip")));
-
+
// Assert that the contents are what we expect.
- File serverFile = testdir.getFile(filename);
- String expected = IO.readToString(serverFile);
- String actual = null;
-
- InputStream in = null;
- ByteArrayOutputStream out = null;
- try
+ if (filename != null)
{
- in = new ByteArrayInputStream(response.getContentBytes());
- out = new ByteArrayOutputStream();
- IO.copy(in,out);
+ File serverFile = testdir.getFile(filename);
+ String expected = IO.readToString(serverFile);
+ String actual = null;
- actual = out.toString(encoding);
- Assert.assertEquals("Server contents",expected,actual);
- }
- finally
- {
- IO.close(out);
- IO.close(in);
+ InputStream in = null;
+ ByteArrayOutputStream out = null;
+ try
+ {
+ in = new ByteArrayInputStream(response.getContentBytes());
+ out = new ByteArrayOutputStream();
+ IO.copy(in,out);
+
+ actual = out.toString(encoding);
+ Assert.assertEquals("Server contents",expected,actual);
+ }
+ finally
+ {
+ IO.close(out);
+ IO.close(in);
+ }
}
}
+
+
+
/**
* Generate string content of arbitrary length.
@@ -320,6 +330,20 @@ public class GzipTester
IO.close(fos);
}
}
+
+ /**
+ * Copy a src/test/resource file into the server tree for eventual serving.
+ *
+ * @param filename
+ * the filename to look for in src/test/resources
+ */
+ public void copyTestServerFile(String filename) throws IOException
+ {
+ File srcFile = MavenTestingUtils.getTestResourceFile(filename);
+ File testFile = testdir.getFile(filename);
+
+ IO.copy(srcFile,testFile);
+ }
/**
* Set the servlet that provides content for the GzipFilter in being tested.
@@ -335,10 +359,20 @@ public class GzipTester
servletTester.setResourceBase(testdir.getDir().getCanonicalPath());
ServletHolder servletHolder = servletTester.addServlet(servletClass,"/");
servletHolder.setInitParameter("baseDir",testdir.getDir().getAbsolutePath());
- FilterHolder holder = servletTester.addFilter(GzipFilter.class,"/*",0);
+ FilterHolder holder = servletTester.addFilter(gzipFilterClass,"/*",0);
return holder;
}
+ public Class extends GzipFilter> getGzipFilterClass()
+ {
+ return gzipFilterClass;
+ }
+
+ public void setGzipFilterClass(Class extends GzipFilter> gzipFilterClass)
+ {
+ this.gzipFilterClass = gzipFilterClass;
+ }
+
public void setEncoding(String encoding)
{
this.encoding = encoding;
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestMinGzipSizeServlet.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestMinGzipSizeServlet.java
new file mode 100644
index 00000000000..3a3c9897f6c
--- /dev/null
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestMinGzipSizeServlet.java
@@ -0,0 +1,52 @@
+package org.eclipse.jetty.servlets.gzip;
+
+import java.io.IOException;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.http.MimeTypes;
+import org.eclipse.jetty.io.Buffer;
+
+/**
+ * Test servlet for testing against unusual minGzip configurable.
+ */
+@SuppressWarnings("serial")
+public class TestMinGzipSizeServlet extends TestDirContentServlet
+{
+ private MimeTypes mimeTypes;
+
+ @Override
+ public void init(ServletConfig config) throws ServletException
+ {
+ super.init(config);
+ mimeTypes = new MimeTypes();
+ }
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ String fileName = request.getServletPath();
+ byte[] dataBytes = loadContentFileBytes(fileName);
+
+ response.setContentLength(dataBytes.length);
+ if (fileName.endsWith(".js"))
+ {
+ // intentionally long-form content type to test ";" splitting in code
+ response.setContentType("text/javascript; charset=utf-8");
+ }
+ else
+ {
+ Buffer buf = mimeTypes.getMimeByExtension(fileName);
+ if (buf != null)
+ {
+ response.setContentType(buf.toString());
+ }
+ }
+ ServletOutputStream out = response.getOutputStream();
+ out.write(dataBytes);
+ }
+}
diff --git a/jetty-servlets/src/test/resources/big_script.js b/jetty-servlets/src/test/resources/big_script.js
new file mode 100644
index 00000000000..938a413c3fd
--- /dev/null
+++ b/jetty-servlets/src/test/resources/big_script.js
@@ -0,0 +1,792 @@
+//----------------------------------------------------------------------
+//
+// Silly / Pointless Javascript to test GZIP compression.
+//
+//----------------------------------------------------------------------
+
+var LOGO = {
+ dat: [
+ 0x50, 0x89, 0x47, 0x4e, 0x0a, 0x0d, 0x0a, 0x1a, 0x00, 0x00, 0x0d, 0x00, 0x48, 0x49, 0x52, 0x44,
+ 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x78, 0x00, 0x06, 0x08, 0x00, 0x00, 0x2a, 0x00, 0x21, 0x96,
+ 0x00, 0x0f, 0x00, 0x00, 0x73, 0x04, 0x49, 0x42, 0x08, 0x54, 0x08, 0x08, 0x7c, 0x08, 0x64, 0x08,
+ 0x00, 0x88, 0x00, 0x00, 0x70, 0x09, 0x59, 0x48, 0x00, 0x73, 0x04, 0x00, 0x00, 0x27, 0x04, 0x00,
+ 0x01, 0x27, 0x4f, 0xd9, 0x80, 0x1d, 0x00, 0x00, 0x19, 0x00, 0x45, 0x74, 0x74, 0x58, 0x6f, 0x53,
+ 0x74, 0x66, 0x61, 0x77, 0x65, 0x72, 0x77, 0x00, 0x77, 0x77, 0x69, 0x2e, 0x6b, 0x6e, 0x63, 0x73,
+ 0x70, 0x61, 0x2e, 0x65, 0x72, 0x6f, 0x9b, 0x67, 0x3c, 0xee, 0x00, 0x1a, 0x20, 0x00, 0x49, 0x00,
+ 0x41, 0x44, 0x78, 0x54, 0xed, 0x9c, 0x79, 0x9d, 0x1c, 0xd8, 0x95, 0x55, 0x3f, 0xff, 0xfb, 0xa7,
+ 0xb2, 0xdd, 0x24, 0xef, 0x24, 0x81, 0x81, 0x2c, 0x20, 0x40, 0xd5, 0x91, 0x8b, 0xb0, 0x3f, 0xbb,
+ 0x1d, 0x04, 0x54, 0x1c, 0x46, 0x74, 0x17, 0x18, 0xd1, 0x98, 0x19, 0xd1, 0x05, 0x11, 0x37, 0xf4,
+ 0xe2, 0x8f, 0xcc, 0xb8, 0x28, 0x8c, 0x82, 0x02, 0x22, 0x8c, 0xe0, 0xe8, 0xe2, 0x86, 0x02, 0x88,
+ 0x8e, 0xa2, 0x08, 0xe8, 0x42, 0x42, 0x4b, 0x08, 0xc2, 0xc8, 0x12, 0x12, 0xf6, 0x42, 0x7d, 0x90,
+ 0xf7, 0x7d, 0x3e, 0xee, 0x47, 0xf3, 0x77, 0x75, 0xeb, 0x6a, 0xdf, 0x7e, 0xee, 0xea, 0xab, 0x7b,
+ 0xdc, 0x93, 0xf3, 0xcf, 0xd0, 0xf0, 0xa9, 0x55, 0x53, 0xae, 0x6f, 0x5d, 0x3d, 0xd5, 0x9e, 0xf7,
+ 0xee, 0x7b, 0x8a, 0xf9, 0xe2, 0xaa, 0x38, 0x70, 0x0e, 0x1c, 0xc3, 0x87, 0x99, 0x2e, 0x2f, 0xb4,
+ 0xe1, 0xc0, 0x38, 0x70, 0x8e, 0x1c, 0x11, 0x83, 0x80, 0xe7, 0x0e, 0x1d, 0xc3, 0x87, 0x48, 0xe1,
+ 0xe7, 0x01, 0x1d, 0x80, 0x87, 0x0e, 0xe1, 0xc3, 0x01, 0x48, 0x80, 0xe7, 0x0e, 0x1d, 0xc3, 0x87,
+ 0x48, 0xe1, 0xe7, 0x01, 0x1d, 0x80, 0x87, 0x0e, 0xe1, 0xc3, 0x01, 0x48, 0x80, 0xe7, 0x0e, 0x1d,
+ 0xc3, 0x87, 0x48, 0xe1, 0xe7, 0x01, 0x1d, 0x80, 0x87, 0x0e, 0xe1, 0xc3, 0x01, 0x48, 0x80, 0xe7,
+ 0x0e, 0x1d, 0xc3, 0x87, 0x48, 0xe1, 0xe7, 0x01, 0x1d, 0x80, 0x87, 0x0e, 0xe1, 0xc3, 0x01, 0x48,
+ 0x80, 0xe7, 0x0e, 0x1d, 0xc3, 0x87, 0x48, 0xe1, 0xe7, 0x01, 0x1d, 0x80, 0x87, 0x0e, 0xe1, 0xc3,
+ 0x01, 0x48, 0x80, 0xe7, 0x0e, 0x1d, 0xc3, 0x87, 0x48, 0xe1, 0x96, 0x81, 0x2f, 0xb4, 0x44, 0x40,
+ 0x2c, 0x3a, 0xe9, 0x98, 0xa7, 0x55, 0xe1, 0x3a, 0x38, 0x70, 0x8e, 0x1c, 0x42, 0x26, 0xf0, 0xd2,
+ 0x22, 0x4b, 0x16, 0x32, 0x0c, 0xb8, 0x02, 0xb8, 0xde, 0x38, 0xc9, 0x82, 0xe0, 0x4e, 0x80, 0xbf,
+ 0xa9, 0x4f, 0xbf, 0x6a, 0x7b, 0x05, 0x88, 0xb1, 0x6c, 0xc8, 0xc3, 0xe0, 0xfb, 0xc0, 0xd1, 0x81,
+ 0xcd, 0x86, 0x81, 0xe5, 0xc0, 0xe5, 0xab, 0xdf, 0x02, 0xea, 0xb6, 0xc3, 0x0e, 0x1c, 0xa3, 0x87,
+ 0x44, 0x6e, 0x12, 0x64, 0x29, 0x70, 0x41, 0xf0, 0x7a, 0x60, 0xaf, 0xc2, 0x01, 0x77, 0x80, 0xf3,
+ 0x55, 0x9b, 0x21, 0xf5, 0xf6, 0x0b, 0x81, 0xba, 0x81, 0xc7, 0x54, 0x5b, 0x77, 0xf5, 0xbf, 0x09,
+ 0xd9, 0xeb, 0xed, 0xb7, 0x45, 0x80, 0x0b, 0x24, 0x04, 0x2c, 0x5b, 0x66, 0xec, 0x35, 0x28, 0xf1,
+ 0xd7, 0xf0, 0xba, 0xaa, 0xb6, 0xd5, 0x11, 0x61, 0x23, 0x79, 0x27, 0xf0, 0x76, 0xdb, 0x5e, 0x81,
+ 0x27, 0x3c, 0xc3, 0xfc, 0x6c, 0x14, 0x1c, 0x3b, 0xc7, 0x0e, 0x10, 0xa0, 0x23, 0x91, 0x67, 0x81,
+ 0x91, 0x81, 0x9e, 0x75, 0x13, 0xaa, 0x4b, 0x38, 0x17, 0x55, 0xb2, 0x5b, 0x05, 0xd7, 0xa3, 0x9c,
+ 0x0b, 0xaa, 0x7e, 0x93, 0x8d, 0x31, 0xe0, 0x39, 0x48, 0x2b, 0xf9, 0xc7, 0x9c, 0x02, 0xbc, 0x0b,
+ 0xb6, 0xdb, 0x62, 0xd1, 0xe3, 0xa7, 0xdb, 0x66, 0x8b, 0x76, 0x03, 0xb4, 0xa5, 0x37, 0xdb, 0x64,
+ 0x70, 0xe1, 0x06, 0x38, 0x2d, 0xcb, 0xef, 0xd4, 0x01, 0x0c, 0x01, 0x86, 0x8b, 0xf7, 0xab, 0x48,
+ 0x7b, 0x25, 0x81, 0x43, 0x0d, 0x5f, 0x5e, 0xc2, 0x34, 0x84, 0x80, 0xe6, 0x50, 0x3f, 0x20, 0xfa,
+ 0x98, 0x19, 0xfa, 0xfd, 0xd7, 0xc4, 0x0c, 0x9c, 0x96, 0x55, 0x92, 0x3c, 0x0b, 0x43, 0x3d, 0xe5,
+ 0xcc, 0x33, 0x8c, 0x1a, 0x0e, 0x65, 0xab, 0x30, 0x31, 0xb4, 0x4d, 0xb9, 0xd6, 0x98, 0xb6, 0x6e,
+ 0xf3, 0xef, 0x9f, 0x6a, 0xba, 0xb2, 0xfc, 0xb7, 0xc7, 0xa3, 0xc8, 0x88, 0x55, 0x04, 0x62, 0xdd,
+ 0xa8, 0xd4, 0xe1, 0xc3, 0xd4, 0x70, 0x71, 0x40, 0xee, 0x7a, 0xd2, 0x82, 0xb0, 0xf6, 0x30, 0x8c,
+ 0x58, 0x6b, 0x36, 0xb2, 0x55, 0x72, 0x81, 0x4f, 0xfd, 0x4d, 0x88, 0xe5, 0x34, 0xee, 0x69, 0xbc,
+ 0x63, 0x38, 0xd6, 0xf6, 0x16, 0xf4, 0xd8, 0xd8, 0xb6, 0x57, 0x38, 0x77, 0xa8, 0x50, 0x78, 0x72,
+ 0x56, 0x2c, 0xb0, 0x1d, 0xb4, 0x88, 0xa7, 0x03, 0xb6, 0x95, 0x1e, 0xa7, 0xe5, 0x97, 0x9f, 0x9a,
+ 0x33, 0x0f, 0x73, 0x6a, 0xba, 0xdb, 0x9f, 0x02, 0x79, 0x3c, 0x7f, 0xb7, 0x34, 0xd7, 0x06, 0xa3,
+ 0x39, 0xe3, 0xbf, 0xdb, 0xdd, 0x71, 0x76, 0x94, 0x9f, 0x2e, 0x66, 0xd8, 0xe0, 0xd4, 0xaf, 0x95,
+ 0x70, 0xf4, 0xab, 0xeb, 0xfe, 0x7d, 0x87, 0x5d, 0xce, 0x03, 0x3b, 0x01, 0x8e, 0x1c, 0xe4, 0x66,
+ 0xff, 0x5a, 0xa7, 0xc6, 0x6d, 0x0e, 0x8b, 0xe3, 0xdb, 0x53, 0xfd, 0x07, 0x02, 0xe5, 0xfc, 0x70,
+ 0xbd, 0xc2, 0x07, 0x7e, 0x53, 0xbc, 0xab, 0x55, 0xc4, 0x39, 0xea, 0x6b, 0xa7, 0xb1, 0x89, 0xc0,
+ 0xf6, 0x8b, 0x1d, 0xfa, 0xa7, 0x70, 0x56, 0xaa, 0xf8, 0x74, 0xb0, 0x95, 0x82, 0x1d, 0x15, 0x3e,
+ 0x24, 0x2f, 0xc0, 0x0a, 0x73, 0x31, 0xfb, 0xcc, 0x65, 0xff, 0xe4, 0x4f, 0xbb, 0xc2, 0x1a, 0x96,
+ 0x1a, 0x37, 0xe0, 0x25, 0xcf, 0x80, 0x69, 0x1a, 0x77, 0xfe, 0xdd, 0xcf, 0x78, 0x13, 0xf2, 0x16,
+ 0x32, 0xc0, 0x46, 0xe3, 0x0e, 0x1d, 0x23, 0x87, 0x22, 0x21, 0x38, 0x72, 0x49, 0x70, 0x7b, 0x69,
+ 0x46, 0x68, 0xc4, 0xf8, 0x64, 0xe4, 0x94, 0x03, 0xb7, 0x7b, 0xb3, 0xf5, 0x27, 0xa2, 0x6f, 0xe0,
+ 0xb6, 0x2b, 0x45, 0x77, 0xef, 0x7b, 0xc7, 0xab, 0x83, 0xde, 0x72, 0x3b, 0xdf, 0x3c, 0xb0, 0x15,
+ 0x3c, 0xb7, 0x09, 0xd1, 0xd8, 0x8a, 0xc0, 0x76, 0x47, 0x01, 0x63, 0x34, 0xd6, 0x4e, 0xc1, 0xb8,
+ 0x16, 0x97, 0x3a, 0x44, 0x8f, 0x25, 0x37, 0x19, 0xe5, 0x1a, 0xd2, 0xac, 0xb1, 0x87, 0xc2, 0x2d,
+ 0x21, 0xcc, 0x6f, 0x66, 0xde, 0xfb, 0xb2, 0xbc, 0x2b, 0xb8, 0xbb, 0xf0, 0xa8, 0x97, 0x1e, 0xea,
+ 0x46, 0xa3, 0x0e, 0x1d, 0xa3, 0x87, 0x3e, 0x36, 0x2f, 0x8d, 0xfb, 0x1a, 0x43, 0xa1, 0x19, 0x5a,
+ 0x22, 0xdf, 0x4e, 0x89, 0xfd, 0x70, 0xbe, 0xfa, 0xae, 0xf0, 0xcd, 0x1b, 0xeb, 0xda, 0xef, 0x0d,
+ 0x66, 0xfa, 0x13, 0xa2, 0xb1, 0x14, 0x07, 0x3d, 0x74, 0x1c, 0xa7, 0xc0, 0x37, 0x9b, 0xd2, 0xff,
+ 0xc0, 0xfc, 0x38, 0x08, 0xcc, 0x0f, 0x6e, 0x37, 0x87, 0xd4, 0x1c, 0x88, 0x1c, 0x03, 0xda, 0x52,
+ 0x63, 0x3e, 0x96, 0x44, 0x7f, 0x64, 0xe4, 0xea, 0xd8, 0x2c, 0x27, 0x9b, 0x4c, 0x1f, 0x9f, 0x6e,
+ 0xd8, 0x6b, 0x01, 0xe4, 0x88, 0x83, 0x0d, 0x1c, 0x0e, 0x5c, 0x07, 0x9c, 0xff, 0x46, 0x0a, 0x54,
+ 0xc2, 0x6c, 0x32, 0x5b, 0x67, 0xf1, 0x46, 0x53, 0x64, 0x44, 0x5e, 0x08, 0xe1, 0xe2, 0x62, 0xdf,
+ 0xe9, 0x7e, 0x37, 0x5b, 0x08, 0xf0, 0x15, 0xf0, 0x8d, 0x55, 0x9e, 0x84, 0x8e, 0x1c, 0x22, 0x30,
+ 0x1e, 0x32, 0x48, 0xf8, 0xbb, 0x69, 0xe0, 0x45, 0x43, 0xaa, 0x8d, 0x93, 0xff, 0x46, 0x57, 0x77,
+ 0x67, 0x8e, 0x03, 0x3a, 0x8e, 0x03, 0xc0, 0x15, 0x9b, 0x7f, 0x37, 0xb2, 0x4f, 0x77, 0x79, 0x9e,
+ 0x08, 0xc1, 0x1a, 0xe3, 0xee, 0xe0, 0x27, 0x44, 0xd9, 0x29, 0xe5, 0xaf, 0x75, 0x4b, 0x1e, 0x50,
+ 0x8e, 0x09, 0x98, 0x9e, 0xc2, 0x61, 0xb3, 0x34, 0xc1, 0x23, 0xdd, 0xae, 0xda, 0xca, 0x03, 0x17,
+ 0x6a, 0x37, 0xaa, 0x91, 0x35, 0xee, 0x34, 0x6a, 0x30, 0x4a, 0x3c, 0xfc, 0xfc, 0xc2, 0x3f, 0xa8,
+ 0x7e, 0x14, 0xe7, 0x06, 0x07, 0x80, 0x88, 0x85, 0x1b, 0xfc, 0x59, 0xf0, 0x3a, 0xcc, 0x30, 0xde,
+ 0x88, 0x17, 0xa7, 0xc8, 0xf5, 0x55, 0x8d, 0x5b, 0xb1, 0x3e, 0xcc, 0x88, 0x8b, 0xc2, 0x8c, 0xf8,
+ 0xf4, 0x6a, 0xab, 0xb9, 0x7a, 0xf0, 0xf5, 0xe0, 0xf2, 0x22, 0x55, 0x5e, 0x6c, 0xdd, 0xae, 0xd1,
+ 0xff, 0x63, 0x9f, 0xe4, 0xb2, 0xf0, 0x01, 0x88, 0xef, 0x78, 0x56, 0xb8, 0x4f, 0x0e, 0xa0, 0x98,
+ 0xb5, 0xfa, 0xe8, 0xe8, 0x1b, 0xf7, 0xe6, 0x55, 0xeb, 0x7f, 0x17, 0xb6, 0xfa, 0x37, 0xb5, 0xad,
+ 0x69, 0xc3, 0x04, 0x2d, 0x22, 0x2d, 0x80, 0x33, 0xa5, 0x09, 0x1b, 0x6d, 0xe7, 0xe1, 0x4f, 0x15,
+ 0xb2, 0x05, 0x21, 0x9f, 0x47, 0x1d, 0x70, 0x14, 0x67, 0xc0, 0x30, 0x8f, 0xe7, 0xdf, 0xe7, 0x99,
+ 0x70, 0x1c, 0x44, 0x62, 0x38, 0xe4, 0x6a, 0xe0, 0x3a, 0xec, 0xf0, 0x5f, 0xc1, 0x3a, 0x8b, 0x37,
+ 0x39, 0xc8, 0xce, 0x06, 0x13, 0x7d, 0x9d, 0x76, 0x89, 0x6f, 0x80, 0xf3, 0x52, 0xdb, 0xeb, 0xb0,
+ 0x8f, 0xd8, 0x91, 0x10, 0xc0, 0x61, 0xfc, 0x27, 0xae, 0xfb, 0x6c, 0x39, 0x89, 0xf0, 0x00, 0x50,
+ 0x74, 0xcf, 0xf9, 0xe6, 0xae, 0xd3, 0xef, 0x80, 0x04, 0xdb, 0x65, 0xdc, 0xde, 0xca, 0x5d, 0x73,
+ 0x7e, 0x05, 0x23, 0xbb, 0x6f, 0x60, 0x70, 0x1b, 0xa2, 0x47, 0xf8, 0x93, 0x39, 0xb0, 0xb6, 0x02,
+ 0x7e, 0x1f, 0xa2, 0x7e, 0xe6, 0x29, 0xcb, 0x7f, 0xbb, 0xbf, 0xe0, 0x55, 0xe1, 0xb4, 0x3b, 0x66,
+ 0x05, 0x1e, 0x7e, 0x60, 0x01, 0xd0, 0x53, 0xaf, 0x35, 0xd5, 0x8d, 0x46, 0x18, 0x1e, 0x13, 0xfc,
+ 0xf7, 0xbe, 0x3d, 0xa1, 0x3e, 0x63, 0xdc, 0xfe, 0xec, 0x1b, 0xce, 0x1c, 0x81, 0xa4, 0x67, 0xcf,
+ 0x99, 0x71, 0x9b, 0xc5, 0xdb, 0x4a, 0xf1, 0x59, 0x3f, 0x9e, 0xf4, 0x93, 0x02, 0x15, 0x30, 0xeb,
+ 0x9a, 0x66, 0xe6, 0xb5, 0x00, 0x38, 0x02, 0xb8, 0x5b, 0x18, 0x38, 0xda, 0x4c, 0x7f, 0xb3, 0x0b,
+ 0x26, 0x86, 0x8d, 0x1d, 0x46, 0x46, 0x37, 0xbf, 0x6a, 0xa9, 0x85, 0x4f, 0x2f, 0xc3, 0xd7, 0xaf,
+ 0xd7, 0xde, 0xf4, 0x37, 0x2a, 0x12, 0x75, 0x5d, 0xaa, 0xab, 0x26, 0x76, 0x89, 0x3a, 0xf4, 0x8f,
+ 0x70, 0x1c, 0x19, 0x3a, 0x56, 0xd0, 0x82, 0x47, 0x32, 0x22, 0x38, 0x0e, 0xb4, 0xae, 0xca, 0x7d,
+ 0x2c, 0xf0, 0xf3, 0x86, 0x58, 0xaf, 0x99, 0xd2, 0x4f, 0x67, 0x02, 0x70, 0x8d, 0xd8, 0x07, 0x7e,
+ 0x79, 0x47, 0xda, 0x04, 0x81, 0x9e, 0xaf, 0xed, 0x89, 0x1d, 0xa5, 0xc9, 0x8b, 0xda, 0xf3, 0x3b,
+ 0xb2, 0x9c, 0xf0, 0x38, 0x1e, 0xde, 0x60, 0xd3, 0x81, 0x13, 0xf5, 0x11, 0x87, 0xf5, 0xf0, 0x77,
+ 0x84, 0xc9, 0x9e, 0x99, 0x79, 0x49, 0x73, 0xd3, 0x3c, 0x5d, 0xbb, 0xb2, 0xce, 0xfc, 0x17, 0x4d,
+ 0x71, 0x11, 0xd8, 0x35, 0x71, 0x1d, 0x8b, 0x14, 0x5c, 0x56, 0xdf, 0xe5, 0xed, 0x77, 0xc9, 0xa1,
+ 0xa3, 0x46, 0x7a, 0x2b, 0xdc, 0x0a, 0x2d, 0xbb, 0x59, 0x50, 0x37, 0x78, 0x9f, 0xf0, 0xec, 0x55,
+ 0xba, 0x7d, 0x7b, 0x1e, 0x7a, 0x6b, 0xfc, 0x0b, 0x6b, 0x6c, 0x5e, 0xc0, 0x5e, 0x17, 0x8f, 0x31,
+ 0xb1, 0x9a, 0x05, 0x99, 0x76, 0x5d, 0x6d, 0xc0, 0x84, 0x43, 0x67, 0xc3, 0x1d, 0x9b, 0xe6, 0x09,
+ 0xe1, 0xfb, 0x67, 0xe5, 0x23, 0x02, 0x55, 0xc1, 0xba, 0xaa, 0xa8, 0xde, 0x28, 0xd1, 0xe2, 0x67,
+ 0x48, 0x1b, 0x9d, 0x9d, 0xfc, 0xce, 0x3c, 0xef, 0x46, 0xe3, 0x73, 0xf7, 0x64, 0x44, 0xbe, 0x14,
+ 0x29, 0x42, 0x0c, 0xa7, 0x1a, 0xcb, 0xbe, 0x75, 0xfb, 0x10, 0x6a, 0x77, 0xb3, 0xf4, 0x70, 0x19,
+ 0xa6, 0xc0, 0xbd, 0x9f, 0xc2, 0x9c, 0x7b, 0x93, 0xbf, 0x03, 0xa3, 0x69, 0xbe, 0x73, 0x2a, 0x8e,
+ 0x0d, 0xfc, 0xb5, 0x30, 0x71, 0xb4, 0x88, 0xc6, 0xe7, 0x2c, 0x4c, 0x8c, 0x8c, 0xf6, 0x73, 0x7e,
+ 0x5f, 0x43, 0xf2, 0xb8, 0x77, 0xc5, 0x75, 0x55, 0x85, 0x57, 0xdf, 0xc3, 0xaf, 0x5f, 0x1b, 0xbd,
+ 0xf6, 0x37, 0x0b, 0x91, 0xd1, 0x3e, 0xa8, 0x77, 0xb6, 0xea, 0x27, 0x44, 0x61, 0x09, 0x01, 0xc5,
+ 0x47, 0x17, 0xc7, 0x82, 0xb6, 0x96, 0x9f, 0xa7, 0x25, 0x92, 0x78, 0x6b, 0xbc, 0x00, 0x49, 0x6a,
+ 0xbe, 0x9e, 0xc0, 0xee, 0x4a, 0xdd, 0xfc, 0x23, 0x68, 0x1c, 0xcf, 0x04, 0xf3, 0x72, 0xcd, 0xbf,
+ 0x59, 0xca, 0xde, 0xf8, 0x1b, 0x05, 0x25, 0x1d, 0x7f, 0x0b, 0xf2, 0xa7, 0x37, 0xb3, 0x23, 0x34,
+ 0x34, 0x9c, 0xec, 0xcc, 0x7a, 0x6f, 0x33, 0xb6, 0x57, 0x4f, 0x45, 0xc1, 0x1c, 0x5e, 0x23, 0x03,
+ 0x42, 0x22, 0x10, 0xa8, 0xb5, 0xc6, 0xe7, 0x09, 0x5f, 0x62, 0x57, 0xed, 0xda, 0xee, 0x08, 0x12,
+ 0xf7, 0x3f, 0x61, 0x52, 0x51, 0xe9, 0xec, 0x23, 0xcb, 0x6d, 0x77, 0x29, 0x0a, 0x6e, 0x7e, 0x8c,
+ 0xc0, 0x73, 0x89, 0x0d, 0x12, 0x4e, 0xad, 0x83, 0xf0, 0x11, 0xf8, 0x59, 0x82, 0x46, 0xc2, 0x36,
+ 0x2f, 0xcf, 0x48, 0x2d, 0xfc, 0x37, 0x24, 0x5c, 0x76, 0x10, 0xd3, 0x3f, 0xc3, 0x7e, 0x89, 0xde,
+ 0x6c, 0x57, 0x51, 0xdc, 0x50, 0x9d, 0xba, 0xa6, 0x8e, 0xf5, 0x17, 0x52, 0xfc, 0x0d, 0x89, 0x3b,
+ 0x14, 0xc8, 0x15, 0x7c, 0x5e, 0xdf, 0x3c, 0x3b, 0xc2, 0x4b, 0x8e, 0x65, 0x71, 0x89, 0xf7, 0x99,
+ 0x04, 0x8e, 0x03, 0xbc, 0x0a, 0x9f, 0xf1, 0xde, 0x32, 0x43, 0x38, 0x5c, 0xd9, 0x26, 0x77, 0x3b,
+ 0xc6, 0xcb, 0x70, 0xbe, 0xc5, 0x0e, 0x54, 0x8f, 0x63, 0x75, 0xc3, 0x85, 0x04, 0x2f, 0xa8, 0x4e,
+ 0xde, 0xc7, 0x37, 0xb7, 0x85, 0xf6, 0x98, 0x3b, 0x37, 0x77, 0xb7, 0x22, 0x96, 0xc6, 0x0e, 0x03,
+ 0x60, 0x25, 0x28, 0x59, 0x11, 0xc0, 0xff, 0x9d, 0x3a, 0xb5, 0x16, 0x02, 0x36, 0x91, 0x65, 0x7c,
+ 0x8f, 0x37, 0xc8, 0xee, 0xd1, 0x30, 0x16, 0x70, 0xba, 0xcc, 0x02, 0xbe, 0x82, 0x6b, 0xe5, 0x4f,
+ 0xb5, 0x13, 0x47, 0x94, 0x08, 0x3b, 0x44, 0x09, 0x4c, 0x2a, 0x94, 0x77, 0x07, 0xd6, 0x74, 0xeb,
+ 0xf7, 0x83, 0x6a, 0x77, 0xba, 0xe4, 0xab, 0x59, 0x67, 0xe1, 0x91, 0x70, 0x47, 0x17, 0x02, 0x22,
+ 0x27, 0x65, 0x73, 0x3f, 0x7b, 0x58, 0x84, 0xa2, 0xdd, 0xc7, 0xe5, 0x79, 0xc1, 0x3b, 0xbb, 0x32,
+ 0xe0, 0x05, 0xa6, 0xeb, 0x75, 0xec, 0x94, 0x16, 0x07, 0x6f, 0x29, 0xed, 0x7d, 0x70, 0x53, 0x82,
+ 0xc4, 0x54, 0x03, 0x96, 0x27, 0x2e, 0x88, 0x98, 0x31, 0xc0, 0xd9, 0xa7, 0x80, 0xc8, 0xb4, 0x0e,
+ 0x3b, 0x67, 0xe7, 0x81, 0x1b, 0x8c, 0x32, 0x0d, 0xe8, 0x0d, 0x6d, 0x28, 0x58, 0xd8, 0xeb, 0xff,
+ 0xc1, 0x1a, 0x14, 0xe4, 0x33, 0x93, 0x94, 0xe6, 0x67, 0xb6, 0x64, 0x74, 0x60, 0x98, 0xa3, 0xb8,
+ 0x6f, 0x34, 0xf1, 0x8f, 0x4c, 0xe8, 0xf4, 0xa8, 0x8d, 0xa9, 0x2f, 0x67, 0x9b, 0xf0, 0x93, 0x76,
+ 0xc9, 0x4e, 0x47, 0x57, 0x53, 0x93, 0x6e, 0x5c, 0xae, 0x57, 0x31, 0x07, 0x2d, 0xb5, 0xfb, 0xc3,
+ 0x27, 0xc7, 0xe4, 0x13, 0xee, 0xf9, 0x7e, 0xa6, 0x05, 0x76, 0x4d, 0x13, 0xa5, 0x7f, 0x2f, 0xaa,
+ 0xb0, 0x55, 0x36, 0x77, 0xf7, 0xbe, 0x16, 0xa1, 0x77, 0x7b, 0xea, 0x6e, 0x5b, 0x67, 0xf2, 0x70,
+ 0x41, 0xf7, 0x6d, 0x55, 0xf3, 0xc8, 0x2b, 0x6d, 0xba, 0x0b, 0x54, 0x3c, 0x0c, 0x97, 0xf1, 0x7c,
+ 0xb3, 0x7c, 0x30, 0xb5, 0x05, 0x0a, 0xd7, 0x65, 0xc0, 0x96, 0x9b, 0x0d, 0x42, 0x97, 0xc8, 0x42,
+ 0xbc, 0x5a, 0x59, 0x9e, 0xe0, 0x06, 0x3b, 0x0f, 0x9c, 0x73, 0xb8, 0xba, 0x6c, 0xe6, 0x41, 0xf5,
+ 0xb9, 0xb1, 0xb2, 0x3f, 0x7c, 0xf6, 0x86, 0xc0, 0x58, 0xbd, 0x75, 0x17, 0xe9, 0x22, 0x53, 0x48,
+ 0x16, 0x0e, 0xf6, 0x05, 0xad, 0xe0, 0xdb, 0xf1, 0xcb, 0x5e, 0x52, 0xdf, 0x0e, 0x44, 0x5e, 0x25,
+ 0x63, 0x88, 0x30, 0x06, 0xb4, 0xa4, 0xc7, 0x61, 0x45, 0x59, 0x4a, 0x3a, 0x45, 0xbb, 0x8c, 0xe4,
+ 0x9a, 0x06, 0x43, 0x78, 0x43, 0xe9, 0x38, 0x06, 0xf0, 0xc3, 0xb7, 0xd2, 0x82, 0x57, 0x30, 0xaa,
+ 0x55, 0xe0, 0x9a, 0x22, 0x4d, 0xe3, 0xd5, 0xbd, 0x3f, 0x44, 0x52, 0xb0, 0x77, 0x55, 0x48, 0x88,
+ 0x38, 0x06, 0x5f, 0x11, 0x79, 0x0d, 0xf4, 0x43, 0x2b, 0x00, 0x16, 0x92, 0x11, 0xea, 0xc3, 0x91,
+ 0x25, 0xf0, 0x18, 0xf7, 0x7c, 0xa2, 0xaa, 0x3f, 0x47, 0x5c, 0x70, 0x2b, 0x60, 0x12, 0x01, 0xfa,
+ 0x01, 0xee, 0xd7, 0x96, 0xf4, 0xb1, 0xb3, 0xe6, 0x8d, 0xfe, 0x0f, 0x2b, 0x4b, 0x6d, 0x3c, 0xb4,
+ 0xb7, 0xae, 0xdf, 0x00, 0x18, 0xda, 0x84, 0x29, 0x35, 0xf1, 0xf6, 0x53, 0x15, 0xfa, 0xdc, 0x6e,
+ 0x59, 0x10, 0x54, 0xea, 0x5e, 0xcd, 0x6c, 0x22, 0xe0, 0x39, 0x1f, 0xf2, 0x90, 0xab, 0x0d, 0x87,
+ 0xad, 0xcb, 0x45, 0x47, 0x6b, 0xbf, 0x20, 0xdb, 0xdb, 0x5e, 0x03, 0xb7, 0x07, 0x18, 0xd2, 0x5e,
+ 0xab, 0xc0, 0x56, 0xfd, 0xf7, 0x7f, 0x40, 0xcb, 0xc4, 0xa4, 0xb1, 0x61, 0xc4, 0xe0, 0xc0, 0x25,
+ 0x78, 0x19, 0xf2, 0x21, 0x36, 0xf1, 0xaa, 0x2f, 0xf4, 0x01, 0xc8, 0x8b, 0xc0, 0xab, 0xe0, 0x02,
+ 0xc0, 0xd7, 0x55, 0x03, 0x1f, 0x32, 0x91, 0x11, 0x00, 0xb7, 0x0c, 0xff, 0xcf, 0x9c, 0x1a, 0x20,
+ 0x1b, 0x27, 0xbf, 0xf3, 0x77, 0x73, 0x9e, 0x47, 0x86, 0x83, 0xb3, 0x84, 0x98, 0xe2, 0x34, 0x39,
+ 0x68, 0xc3, 0x13, 0xc3, 0xf3, 0xc0, 0xbf, 0xa2, 0x14, 0xe7, 0xf1, 0xe0, 0x4f, 0x3a, 0x2d, 0xdb,
+ 0x77, 0x22, 0xef, 0x00, 0x53, 0xc4, 0xb2, 0xf2, 0x16, 0xc1, 0x79, 0x11, 0xaa, 0x8f, 0x32, 0x3e,
+ 0x81, 0xd0, 0xf2, 0x22, 0xe0, 0x0e, 0xc0, 0xe3, 0xb0, 0x5b, 0x79, 0xd3, 0x16, 0xed, 0x2b, 0x91,
+ 0xf5, 0x54, 0xa1, 0x27, 0x98, 0xeb, 0x5c, 0x02, 0x5c, 0x09, 0xaf, 0x86, 0x91, 0xd0, 0x36, 0x61,
+ 0xc8, 0x89, 0x55, 0xbb, 0xd1, 0x35, 0x5e, 0xb4, 0x32, 0xb1, 0xdb, 0xdb, 0xdb, 0x4b, 0x5b, 0x63,
+ 0xcb, 0x84, 0x26, 0x27, 0x8d, 0x1b, 0x68, 0xfe, 0x5f, 0x4b, 0xb3, 0xb8, 0x67, 0xf7, 0x7d, 0x55,
+ 0x82, 0xb2, 0x13, 0xbd, 0x49, 0xf0, 0xd6, 0x0e, 0xef, 0x62, 0x5b, 0x67, 0x59, 0xfb, 0x17, 0xdb,
+ 0xd8, 0x18, 0x4d, 0xcc, 0xbb, 0xfa, 0x61, 0xab, 0xb5, 0xbc, 0xf6, 0x29, 0xaf, 0x10, 0x6d, 0x34,
+ 0x0a, 0xa7, 0x50, 0x7f, 0xfb, 0xd5, 0xb0, 0x53, 0x59, 0xfb, 0xce, 0x8a, 0x25, 0x37, 0xad, 0x3e,
+ 0xe5, 0xaa, 0x9b, 0xae, 0x4c, 0x88, 0xbe, 0x04, 0x4f, 0x81, 0x79, 0x8f, 0xa5, 0x3f, 0x6f, 0x15,
+ 0x31, 0xc4, 0xb8, 0x15, 0xe8, 0x18, 0x91, 0x13, 0x80, 0x07, 0x54, 0xeb, 0x30, 0x35, 0x20, 0xcd,
+ 0x33, 0x22, 0x07, 0x81, 0xdf, 0x8b, 0x14, 0x19, 0xe7, 0xa6, 0x3b, 0x4b, 0xca, 0x0b, 0x2e, 0xa2,
+ 0x1d, 0x7b, 0x73, 0xb1, 0x74, 0x6c, 0xa2, 0x28, 0xfa, 0x23, 0x30, 0x46, 0xaf, 0x04, 0x8a, 0x38,
+ 0x26, 0x4d, 0x7f, 0x00, 0x91, 0x14, 0x86, 0x0f, 0x9d, 0x1d, 0x11, 0x1f, 0x15, 0x39, 0x0f, 0xb8,
+ 0x55, 0xbb, 0x86, 0xd3, 0x3f, 0x00, 0x91, 0x16, 0xaa, 0xe9, 0x25, 0xfa, 0xfe, 0xdf, 0x00, 0x9f,
+ 0xb3, 0xaf, 0x1d, 0x78, 0x45, 0xe0, 0xfe, 0xcc, 0x78, 0xb7, 0x7e, 0x9f, 0xe0, 0x9a, 0xd7, 0x7b,
+ 0xbb, 0xe2, 0x1f, 0x67, 0xd4, 0x9f, 0xb0, 0xc6, 0xe0, 0xcc, 0x61, 0x6f, 0x6f, 0x01, 0x51, 0xe9,
+ 0xff, 0x88, 0xf2, 0xa8, 0x6b, 0x95, 0xb1, 0xea, 0x78, 0xa7, 0x37, 0x85, 0x34, 0x42, 0xf4, 0x6c,
+ 0x76, 0x0b, 0x6e, 0x7a, 0x01, 0x5f, 0x8a, 0xcc, 0x56, 0xfe, 0xfa, 0xc7, 0x57, 0xe8, 0x26, 0x44,
+ 0x95, 0xe3, 0x4c, 0x35, 0x35, 0x8b, 0x7a, 0xaa, 0xf1, 0x5f, 0x32, 0x5a, 0xf2, 0x22, 0xc0, 0x8f,
+ 0xec, 0x8b, 0xce, 0xff, 0x8e, 0x37, 0x3c, 0x36, 0xbc, 0x47, 0x44, 0x50, 0x26, 0xbe, 0x43, 0x22,
+ 0xff, 0x7d, 0x4d, 0xf6, 0x38, 0x12, 0xf1, 0xdf, 0xc2, 0x2d, 0x86, 0xb1, 0xa5, 0x2b, 0xb1, 0x3c,
+ 0x22, 0x27, 0x61, 0x94, 0x3b, 0x14, 0xc7, 0xb5, 0x28, 0x0f, 0x85, 0xdd, 0xe0, 0x16, 0x01, 0xd2,
+ 0xb9, 0x8e, 0xfb, 0x01, 0x4b, 0x25, 0x7c, 0x4b, 0xf4, 0xb8, 0x44, 0x41, 0xc2, 0x2e, 0xf3, 0xbe,
+ 0xd1, 0x2d, 0x27, 0x8a, 0x31, 0xf0, 0xe2, 0x28, 0x00, 0x24, 0x9e, 0x3f, 0x30, 0xb0, 0xaf, 0xcc,
+ 0xf5, 0xb7, 0x52, 0xf3, 0x72, 0x50, 0xa1, 0x70, 0xfe, 0xaa, 0x82, 0xa1, 0x69, 0xbd, 0x6b, 0x78,
+ 0x6b, 0x7f, 0x17, 0xb6, 0x39, 0x23, 0x1c, 0xf8, 0x9b, 0xf0, 0x27, 0x44, 0x00, 0x19, 0x21, 0x1b,
+ 0x0b, 0xe8, 0x1f, 0x4b, 0x8f, 0x86, 0xde, 0x15, 0xb9, 0x7a, 0xa9, 0xd9, 0xae, 0x9c, 0xca, 0x5d,
+ 0xbf, 0xef, 0xe8, 0x1b, 0xcc, 0xb5, 0x6a, 0x30, 0x9e, 0x30, 0xe1, 0xb7, 0x57, 0x9b, 0xcb, 0x7c,
+ 0x16, 0xe8, 0x31, 0x4e, 0x0e, 0xbc, 0x4f, 0xf3, 0x72, 0xbb, 0xb5, 0x3c, 0x10, 0xaf, 0x54, 0xc2,
+ 0xe9, 0x11, 0x53, 0xc0, 0xfa, 0x7f, 0xf0, 0x39, 0xb8, 0xae, 0x4c, 0xef, 0x13, 0x6e, 0x19, 0x4e,
+ 0xe5, 0x96, 0x21, 0xb8, 0x5a, 0x19, 0x9f, 0x6a, 0x33, 0xaf, 0x02, 0x8e, 0x72, 0xbb, 0x86, 0xca,
+ 0x02, 0xbe, 0xfa, 0x1b, 0x95, 0x95, 0x05, 0x3d, 0xe4, 0x76, 0x5e, 0x22, 0x15, 0xac, 0xc7, 0xaf,
+ 0x57, 0xfb, 0x72, 0x22, 0xb0, 0x3e, 0x2f, 0x05, 0x08, 0x3c, 0x94, 0xc0, 0x0c, 0xb6, 0x3b, 0x7f,
+ 0xba, 0xa1, 0x3e, 0x2f, 0xdd, 0xb2, 0x3d, 0xfc, 0xc8, 0xe8, 0xe2, 0x48, 0x88, 0x35, 0xf0, 0xf5,
+ 0x51, 0xc6, 0x5f, 0x66, 0x02, 0xf1, 0xce, 0xf0, 0xad, 0x31, 0x38, 0x5c, 0x71, 0xa6, 0x0c, 0xe7,
+ 0xcb, 0x3d, 0x7b, 0xbc, 0x2b, 0x5c, 0x3b, 0xd3, 0x76, 0xcc, 0x7e, 0x8c, 0xad, 0xb1, 0x95, 0x9f,
+ 0x1a, 0xfb, 0x8a, 0xf7, 0x86, 0x6d, 0x8c, 0x88, 0xe7, 0xc1, 0x8e, 0xf4, 0xcf, 0x68, 0x49, 0x70,
+ 0xa4, 0xc2, 0xa4, 0x9e, 0xbd, 0xc4, 0xc5, 0xdb, 0x8b, 0x72, 0xf9, 0x17, 0xfb, 0x8f, 0x21, 0xc8,
+ 0x8c, 0xad, 0xb5, 0x6f, 0x9f, 0x7a, 0x4e, 0x8e, 0xd5, 0xf0, 0xf0, 0xab, 0x9b, 0xf9, 0xd7, 0x0f,
+ 0x01, 0x22, 0x1d, 0x18, 0x56, 0xfd, 0xba, 0x9b, 0x0a, 0xb9, 0xe7, 0x5f, 0x16, 0xbb, 0x5f, 0x7b,
+ 0x8a, 0x8b, 0x5c, 0x2e, 0xe8, 0xdf, 0x22, 0x5c, 0x6f, 0xa3, 0x31, 0x67, 0x58, 0x04, 0x63, 0x9e,
+ 0xfe, 0x3c, 0x16, 0xec, 0xfa, 0xfe, 0x8e, 0xea, 0xdf, 0x2a, 0x9f, 0xa8, 0x1f, 0x67, 0x0f, 0xea,
+ 0xe0, 0x3b, 0x36, 0x06, 0x83, 0x0d, 0x90, 0x26, 0xfa, 0x85, 0x0f, 0xff, 0xe7, 0x6b, 0xc3, 0x5c,
+ 0x3d, 0xc9, 0xbc, 0xcf, 0x08, 0x10, 0x0a, 0x03, 0xcd, 0x5e, 0x2f, 0xd3, 0x72, 0x11, 0xad, 0xbe,
+ 0x57, 0x02, 0xda, 0x1d, 0x27, 0xce, 0xb5, 0x26, 0xb9, 0x31, 0x79, 0xad, 0x6e, 0x9d, 0xf2, 0x35,
+ 0x8f, 0x0a, 0xce, 0xec, 0xef, 0x71, 0x1c, 0xb6, 0x6f, 0x77, 0x64, 0x8d, 0x1e, 0x44, 0x3c, 0x0b,
+ 0x17, 0x8a, 0x2a, 0x2a, 0xf4, 0xdf, 0xc6, 0x0b, 0xf0, 0xb4, 0x69, 0xd5, 0x1c, 0xf6, 0x25, 0x5f,
+ 0x1a, 0xce, 0xb5, 0x91, 0x2a, 0x32, 0x45, 0xb5, 0xf8, 0x06, 0x83, 0x72, 0xeb, 0xef, 0xe0, 0xc2,
+ 0xcc, 0xb3, 0x87, 0xf5, 0x33, 0xb7, 0x70, 0xcd, 0xb2, 0x69, 0x83, 0xbb, 0x06, 0x25, 0x4d, 0xab,
+ 0x05, 0x1d, 0x1a, 0x6a, 0x34, 0x5c, 0xfc, 0xd6, 0x15, 0x73, 0xb7, 0x7a, 0x78, 0x33, 0xda, 0x6d,
+ 0x7c, 0x46, 0x4c, 0xed, 0x06, 0x47, 0x39, 0x6e, 0x08, 0x6a, 0x5f, 0xa6, 0xd0, 0xe9, 0x1a, 0x7d,
+ 0xdb, 0x54, 0x2c, 0x5a, 0x74, 0xc4, 0x69, 0x79, 0x45, 0xbb, 0x53, 0xe0, 0x25, 0x09, 0xff, 0x00,
+ 0xea, 0x1c, 0x01, 0x94, 0x81, 0x2b, 0x98, 0x5f, 0x37, 0xb2, 0x4f, 0x77, 0xc7, 0x9e, 0x24, 0x1b,
+ 0x58, 0x39, 0xd3, 0x0d, 0xe8, 0x21, 0x7a, 0xc0, 0x63, 0xc4, 0xb0, 0xcf, 0x80, 0x51, 0x32, 0x23,
+ 0xb5, 0x1f, 0xb8, 0xc0, 0x28, 0xd1, 0x05, 0xd6, 0x9e, 0x18, 0x3e, 0x08, 0x1b, 0x2c, 0xf7, 0x81,
+ 0xd3, 0xe2, 0x04, 0xbd, 0x6f, 0x38, 0x0b, 0x64, 0x9c, 0xcf, 0x9c, 0x38, 0x4e, 0xaf, 0xdf, 0x6b,
+ 0x9d, 0x6f, 0x78, 0x2f, 0x02, 0xc2, 0x1c, 0x6f, 0xc2, 0xd5, 0x47, 0xad, 0xf0, 0x75, 0xc9, 0xc2,
+ 0xb9, 0xc3, 0x42, 0x6c, 0x38, 0x6b, 0x78, 0x1e, 0x10, 0x18, 0xf7, 0x90, 0x90, 0x3b, 0xde, 0x9c,
+ 0x4c, 0x81, 0x4c, 0x58, 0x4a, 0x64, 0xc6, 0x5b, 0xf3, 0xb8, 0x59, 0x8d, 0xff, 0x3f, 0x95, 0x54,
+ 0xad, 0xc3, 0x8b, 0xca, 0xbc, 0xc6, 0x1b, 0xdb, 0x75, 0x54, 0x31, 0x63, 0xa3, 0xa7, 0x02, 0x3c,
+ 0x75, 0x3d, 0xd6, 0x58, 0xf3, 0xb8, 0xb9, 0x8d, 0xb1, 0x4f, 0x4f, 0xc9, 0x04, 0x31, 0x00, 0x24,
+ 0x19, 0x2f, 0x83, 0x5f, 0x60, 0x04, 0xf4, 0x74, 0x8d, 0xfb, 0x35, 0x2a, 0x3e, 0x0e, 0x6f, 0x81,
+ 0xb3, 0xda, 0x7b, 0x16, 0xa3, 0x31, 0x6f, 0xdf, 0x6a, 0xaa, 0xdc, 0x7f, 0xf5, 0xb1, 0xd5, 0x60,
+ 0xdb, 0x01, 0x40, 0x51, 0x5d, 0x4a, 0x61, 0x80, 0x3e, 0x2c, 0x86, 0x01, 0x87, 0x93, 0x17, 0x99,
+ 0x58, 0x60, 0x99, 0xda, 0x77, 0x67, 0x14, 0x70, 0xc1, 0x98, 0xb8, 0x4b, 0x73, 0x2a, 0xc4, 0xc5,
+ 0xfe, 0x36, 0xc2, 0x74, 0x66, 0x50, 0xbe, 0x9a, 0xcb, 0x18, 0xd2, 0x1c, 0x7c, 0x2a, 0xe8, 0xff,
+ 0xfc, 0x21, 0xd8, 0xe2, 0x55, 0xa1, 0x37, 0xeb, 0x58, 0xdb, 0xe4, 0x5e, 0x9f, 0xa8, 0xba, 0xe7,
+ 0xcf, 0x82, 0x13, 0x72, 0x9f, 0xae, 0x96, 0x0f, 0x1d, 0x97, 0xb6, 0x69, 0x8b, 0x4d, 0xb7, 0x79,
+ 0xd7, 0x4b, 0x96, 0x76, 0xe7, 0x7f, 0x86, 0xd9, 0x03, 0xaf, 0xab, 0x6a, 0x10, 0x33, 0x01, 0x27,
+ 0x75, 0x78, 0x11, 0x42, 0x67, 0x84, 0xf3, 0x3b, 0xb4, 0x3c, 0xd0, 0x33, 0x6f, 0xae, 0x7e, 0x06,
+ 0xc1, 0x50, 0xd0, 0xde, 0xed, 0x7a, 0xd7, 0x3d, 0xe0, 0x55, 0x0d, 0x77, 0x1c, 0x94, 0x86, 0xac,
+ 0x07, 0x35, 0x31, 0xdc, 0x38, 0x4c, 0x96, 0x7c, 0x01, 0x79, 0x95, 0x86, 0x83, 0x0b, 0x0a, 0x61,
+ 0x7d, 0x55, 0xa8, 0xd5, 0x28, 0xd1, 0x10, 0x81, 0x4a, 0x55, 0x0c, 0x02, 0xf1, 0x13, 0x5f, 0x85,
+ 0x3f, 0x5f, 0x85, 0xaa, 0x1d, 0x6f, 0x36, 0x69, 0x9f, 0xf4, 0x17, 0x36, 0x6d, 0x8d, 0xbe, 0xe1,
+ 0x86, 0xe3, 0x96, 0xc6, 0x9c, 0x5c, 0x26, 0xdc, 0x69, 0x1c, 0x5d, 0x5a, 0xd1, 0xc1, 0xc2, 0x10,
+ 0xb2, 0xcf, 0x75, 0x95, 0xd1, 0xd9, 0x54, 0x65, 0x8e, 0xb1, 0x58, 0xa5, 0xee, 0xdd, 0xa5, 0xb5,
+ 0xa3, 0xed, 0x32, 0x3a, 0x32, 0x4c, 0xb4, 0x5c, 0x4a, 0xa5, 0x4f, 0x89, 0xd5, 0xeb, 0x62, 0xce,
+ 0xcf, 0x96, 0x46, 0x0d, 0xe5, 0xe8, 0x7c, 0x72, 0xfd, 0x21, 0x49, 0x06, 0xde, 0x0e, 0x45, 0x5c,
+ 0xf0, 0x72, 0xf8, 0x23, 0x3d, 0xa6, 0x41, 0x9b, 0xb0, 0x72, 0xc6, 0x1a, 0xa5, 0x5a, 0xe1, 0x62,
+ 0xa3, 0x83, 0xdb, 0x4a, 0x9f, 0x47, 0x25, 0x96, 0xf8, 0x63, 0x59, 0x19, 0x38, 0xb5, 0x5f, 0x4f,
+ 0xea, 0x4f, 0xe1, 0x05, 0xa8, 0x53, 0x54, 0x42, 0x19, 0x79, 0xd1, 0xc8, 0x19, 0x1d, 0x99, 0xee,
+ 0xc4, 0x31, 0x16, 0xb8, 0x33, 0x6c, 0xe6, 0xf0, 0x2d, 0x51, 0x74, 0x7c, 0x74, 0x62, 0xe7, 0xae,
+ 0x0b, 0x4c, 0x71, 0x4b, 0x8d, 0x1c, 0x34, 0x21, 0xc6, 0xef, 0x16, 0x39, 0xcb, 0x1c, 0x41, 0x63,
+ 0x05, 0x9b, 0xaf, 0x2a, 0x3e, 0x61, 0x5f, 0x05, 0xbb, 0x75, 0x4b, 0x94, 0x96, 0x7c, 0x19, 0xdb,
+ 0x4e, 0xc1, 0xf9, 0x9d, 0x67, 0x50, 0xc7, 0x20, 0xd3, 0x00, 0x8d, 0x7b, 0x1c, 0x90, 0xb9, 0x7c,
+ 0xc0, 0xa7, 0xb7, 0x2f, 0x22, 0x07, 0x7b, 0xbf, 0xdb, 0x80, 0xd8, 0x2a, 0xa1, 0x6b, 0xc9, 0x4e,
+ 0xd5, 0xc1, 0x24, 0x06, 0xab, 0x07, 0x72, 0x61, 0x90, 0x58, 0xfc, 0xc2, 0xf3, 0x6f, 0x30, 0x09,
+ 0xa4, 0xa4, 0x54, 0x80, 0xc6, 0xe6, 0x3a, 0x23, 0x6b, 0x18, 0x12, 0xba, 0x13, 0x7f, 0xdd, 0x71,
+ 0xf6, 0xd4, 0xb6, 0x48, 0x9b, 0xa3, 0xdd, 0xff, 0xf0, 0x7f, 0x46, 0x8f, 0x67, 0x87, 0xd9, 0x85,
+ 0xcd, 0x43, 0xed, 0xfe, 0xe6, 0xf6, 0x25, 0x95, 0x75, 0xc1, 0x4b, 0xd9, 0x75, 0x54, 0x85, 0x77,
+ 0xad, 0xc3, 0xff, 0xce, 0xbc, 0x42, 0x8a, 0xb8, 0x0c, 0x88, 0xeb, 0xc1, 0x00, 0x0c, 0xdc, 0x70,
+ 0x8c, 0x90, 0x77, 0xf1, 0x4f, 0x7c, 0x3e, 0xf4, 0x54, 0x2d, 0xae, 0xd5, 0xbe, 0x01, 0x7e, 0xf6,
+ 0xd5, 0x7c, 0x6a, 0xe7, 0x1c, 0x95, 0x2d, 0x0c, 0xbb, 0xdb, 0x55, 0x5d, 0x56, 0x77, 0xfc, 0x38,
+ 0xf8, 0x7d, 0xb6, 0x8a, 0x62, 0xd4, 0x26, 0xef, 0x92, 0x03, 0xd5, 0x83, 0xe7, 0xb0, 0x6d, 0x80,
+ 0xff, 0xcc, 0xec, 0xa6, 0xc3, 0x80, 0x2a, 0x21, 0x02, 0x5b, 0xa1, 0x0c, 0xfe, 0xc2, 0x26, 0x65,
+ 0x0a, 0xb5, 0x1d, 0x6f, 0x70, 0x7d, 0xfe, 0x8d, 0xb4, 0xc6, 0xff, 0x08, 0xca, 0x1a, 0xb5, 0x4a,
+ 0x52, 0x31, 0xd4, 0x71, 0xc6, 0xcf, 0xe5, 0x3e, 0xdf, 0x15, 0x7c, 0xb3, 0xf0, 0xfa, 0x59, 0x2c,
+ 0x7d, 0xc3, 0x27, 0xc7, 0x46, 0xf6, 0x65, 0xd6, 0x7a, 0x0f, 0xf7, 0xfe, 0xc3, 0x6c, 0xeb, 0x9d,
+ 0xa2, 0x2a, 0x73, 0x1d, 0x2d, 0xf0, 0xb1, 0xb1, 0xff, 0x31, 0xf0, 0x9b, 0x35, 0x3e, 0x02, 0x44,
+ 0x53, 0x70, 0x72, 0x54, 0x8f, 0xb0, 0x92, 0x0a, 0x45, 0x83, 0xb2, 0xea, 0x35, 0xb7, 0x72, 0x5e,
+ 0x9b, 0xf0, 0x4e, 0x89, 0x10, 0x92, 0x0e, 0x93, 0xdc, 0xf8, 0x87, 0xd2, 0x0b, 0x6c, 0x3f, 0x4c,
+ 0x82, 0xd5, 0x52, 0x02, 0x03, 0x30, 0x0d, 0x3a, 0x86, 0x01, 0x88, 0x40, 0xa5, 0x2a, 0x92, 0x04,
+ 0x7f, 0x32, 0xa1, 0x33, 0x78, 0xd5, 0xd6, 0x03, 0xbc, 0x8c, 0xec, 0x6b, 0x75, 0xbe, 0x43, 0x99,
+ 0x18, 0x32, 0xc2, 0xd7, 0x34, 0x75, 0xb0, 0x86, 0x45, 0x48, 0xf9, 0x4a, 0xd5, 0x13, 0x4b, 0x1c,
+ 0xf1, 0x39, 0x4c, 0x69, 0x30, 0x8b, 0xe1, 0x33, 0x62, 0xdc, 0x62, 0x52, 0x9c, 0x0a, 0xc2, 0x44,
+ 0x60, 0xcf, 0x9d, 0xa9, 0xe4, 0x19, 0xb9, 0x3c, 0xba, 0x8f, 0x00, 0x25, 0xd9, 0x6f, 0x47, 0xd8,
+ 0xee, 0xb0, 0x3f, 0x06, 0xd5, 0x56, 0x71, 0xf5, 0x8a, 0xc7, 0x05, 0xc8, 0xec, 0xc0, 0xec, 0x7a,
+ 0x16, 0xdd, 0x1c, 0x95, 0x99, 0xfc, 0xae, 0xaa, 0x74, 0x4e, 0x84, 0x92, 0x79, 0x18, 0x44, 0x82,
+ 0x24, 0x64, 0x9a, 0xf0, 0xf6, 0xd2, 0xb3, 0xe1, 0xb4, 0xb3, 0x35, 0x0f, 0x09, 0xeb, 0xad, 0x36,
+ 0xb0, 0x2a, 0x73, 0x6b, 0xaf, 0xe0, 0x78, 0xf5, 0x02, 0x0a, 0xcd, 0x0c, 0x62, 0xf0, 0xb9, 0x94,
+ 0x42, 0x6c, 0xb5, 0xb2, 0x07, 0x6f, 0x87, 0x0a, 0x0a, 0xb4, 0x8a, 0x63, 0xb9, 0x21, 0x86, 0xd3,
+ 0x0f, 0x67, 0xf9, 0x8a, 0x03, 0xef, 0xf0, 0x81, 0x6f, 0xfc, 0x25, 0x93, 0x1d, 0x60, 0x1c, 0x03,
+ 0xda, 0x52, 0x63, 0x3e, 0xd6, 0x44, 0x29, 0x78, 0x2a, 0xac, 0x66, 0xd7, 0x9d, 0xbd, 0x41, 0xa9,
+ 0xb9, 0xef, 0x09, 0x2e, 0x3d, 0xc0, 0xe5, 0x79, 0x9b, 0x3b, 0x12, 0x22, 0x46, 0x80, 0x07, 0x25,
+ 0x8d, 0x6f, 0x0e, 0x4a, 0xb4, 0x36, 0x64, 0xec, 0xa6, 0x1c, 0x17, 0x62, 0xe2, 0x67, 0xee, 0x73,
+ 0xc2, 0x36, 0xcb, 0xcf, 0x5e, 0x53, 0x54, 0x7e, 0x94, 0x24, 0x95, 0x80, 0x1d, 0x5e, 0xe9, 0xde,
+ 0x99, 0x1d, 0xd9, 0xc4, 0xf5, 0x7f, 0x6c, 0xf0, 0x9e, 0x67, 0x6d, 0xef, 0x67, 0xea, 0x4f, 0x45,
+ 0x97, 0x81, 0x0a, 0x7b, 0x30, 0x28, 0x4d, 0xa5, 0xd6, 0x98, 0xe1, 0x9e, 0xa3, 0x6d, 0xf8, 0x5b,
+ 0x00, 0xc0, 0xa8, 0x55, 0x4d, 0x1a, 0x4d, 0x69, 0xfc, 0xe4, 0x79, 0x3d, 0x3f, 0xc6, 0xa7, 0xb9,
+ 0xb1, 0xea, 0x1e, 0x37, 0xc1, 0xd1, 0x86, 0xa5, 0xef, 0xaf, 0xcf, 0xcd, 0xf1, 0x77, 0xa7, 0x6c,
+ 0x1a, 0x9d, 0xc7, 0xd0, 0xc9, 0x0e, 0x77, 0x30, 0xd9, 0x96, 0xaf, 0xea, 0xde, 0x3f, 0xcf, 0xd2,
+ 0xab, 0x95, 0x25, 0x2a, 0xd6, 0xa2, 0xa7, 0x46, 0xc6, 0x2f, 0x15, 0x99, 0x04, 0x2f, 0x92, 0x6d,
+ 0x7a, 0xbc, 0x55, 0xa1, 0xeb, 0x1f, 0x8c, 0xab, 0x82, 0x78, 0x8f, 0xcb, 0x3b, 0xec, 0x02, 0xbd,
+ 0xbf, 0x30, 0xda, 0x18, 0x8f, 0x2d, 0x27, 0xc4, 0x0a, 0xb6, 0x1b, 0x47, 0x12, 0xae, 0x73, 0x16,
+ 0x56, 0x9f, 0xea, 0xa9, 0x4a, 0xc6, 0x37, 0xc7, 0x02, 0x42, 0xf6, 0xf0, 0xfd, 0x4d, 0x0c, 0xec,
+ 0xc6, 0x4e, 0x5a, 0xfe, 0x5f, 0x55, 0x60, 0xac, 0x4c, 0xef, 0x11, 0x7c, 0x5a, 0xd7, 0x07, 0x25,
+ 0x07, 0xb7, 0xfd, 0xed, 0x51, 0xb6, 0x83, 0x92, 0x30, 0xd5, 0x21, 0xe5, 0xaf, 0xec, 0x6d, 0xff,
+ 0x04, 0xb2, 0xb1, 0xac, 0x62, 0x2d, 0xcd, 0x7c, 0xde, 0xed, 0xb2, 0xbc, 0x42, 0xb8, 0xff, 0x61,
+ 0x59, 0xd7, 0xf7, 0x5a, 0x5d, 0xda, 0x2f, 0x80, 0xed, 0xae, 0xa6, 0xe1, 0x91, 0x8d, 0x09, 0x64,
+ 0xf7, 0x56, 0x8d, 0x7a, 0xdd, 0xc8, 0xfb, 0x5b, 0x7f, 0xb9, 0x8e, 0x47, 0xa7, 0x3b, 0x30, 0x77,
+ 0x42, 0xc2, 0x7c, 0x4c, 0x5e, 0x4f, 0xd4, 0xd9, 0x5d, 0xef, 0xbf, 0x4c, 0x7e, 0x12, 0x23, 0x91,
+ 0x6a, 0x9c, 0xa1, 0xb8, 0x2a, 0xef, 0x73, 0x28, 0xe7, 0x77, 0xb7, 0xe8, 0x8f, 0x14, 0x9d, 0x31,
+ 0x04, 0xb8, 0x97, 0xf0, 0xb9, 0xdd, 0xef, 0x01, 0x3d, 0x6b, 0x1e, 0xcc, 0x35, 0x9a, 0xac, 0xfe,
+ 0xe9, 0x2c, 0xb3, 0xca, 0xf8, 0x27, 0x56, 0xd0, 0xb9, 0x53, 0x74, 0x09, 0x4d, 0xae, 0x5c, 0x8b,
+ 0xbc, 0xc4, 0x4b, 0xdb, 0x75, 0x55, 0x51, 0x57, 0x68, 0x51, 0x69, 0x74, 0x8d, 0xa7, 0xcf, 0x24,
+ 0x5d, 0xc5, 0xf6, 0x79, 0xaf, 0xc6, 0xae, 0x45, 0x5d, 0x44, 0x80, 0x12, 0x0a, 0x7d, 0x27, 0x37,
+ 0x1c, 0x93, 0x8c, 0x0c, 0x1b, 0x7e, 0x39, 0x24, 0x4d, 0x58, 0xa1, 0xe4, 0x98, 0x61, 0x10, 0xf2,
+ 0xfa, 0xe7, 0x52, 0x37, 0x80, 0xa8, 0x60, 0x35, 0x7c, 0x8a, 0x49, 0xa3, 0x44, 0x23, 0x20, 0xb5,
+ 0x18, 0x9a, 0xe6, 0x51, 0x16, 0x75, 0xdf, 0x46, 0x57, 0x00, 0xea, 0xaf, 0x86, 0xe1, 0xa6, 0x68,
+ 0x84, 0x62, 0xb7, 0x7b, 0xf3, 0xf5, 0x3b, 0x3f, 0x14, 0xed, 0x5f, 0xed, 0x13, 0xd1, 0x94, 0x9f,
+ 0xc7, 0x16, 0x0b, 0x18, 0xa5, 0x1d, 0xf7, 0x27, 0xad, 0xe6, 0x5f, 0x39, 0x2d, 0x48, 0xd9, 0x24,
+ 0x9a, 0x50, 0xfe, 0x70, 0x6a, 0xd7, 0xbb, 0x75, 0x77, 0x98, 0x3e, 0x3b, 0x6c, 0xfc, 0xa3, 0xa1,
+ 0xe4, 0x9d, 0x35, 0x3e, 0x02, 0x42, 0xc7, 0xf0, 0xfa, 0x5b, 0x10, 0xd9, 0x1c, 0x94, 0x44, 0x7c,
+ 0x9f, 0x55, 0x60, 0xa8, 0x26, 0x6f, 0x64, 0x9e, 0xcd, 0x65, 0x62, 0xf6, 0x07, 0x24, 0x35, 0xe7,
+ 0x72, 0x52, 0x1a, 0xb0, 0x6f, 0x0d, 0x8b, 0xa5, 0xbf, 0x6b, 0x94, 0xe6, 0x27, 0xb6, 0xcf, 0x4d,
+ 0x72, 0x30, 0x59, 0xbc, 0xd4, 0x57, 0x4b, 0xb5, 0xbf, 0x59, 0x71, 0x2c, 0x7c, 0x8a, 0x69, 0xa3,
+ 0x79, 0x86, 0x32, 0x99, 0x6b, 0xa6, 0x83, 0x4f, 0x48, 0xd7, 0xbe, 0xdc, 0xd2, 0x29, 0x04, 0x73,
+ 0x72, 0xaf, 0x37, 0x4c, 0x09, 0x30, 0x33, 0xdf, 0x60, 0xb6, 0x9e, 0x6f, 0x8f, 0x77, 0x1f, 0x33,
+ 0x5e, 0x8a, 0x75, 0x1e, 0x6b, 0xc0, 0xed, 0x81, 0xcf, 0xc5, 0xf0, 0xc3, 0xf0, 0x95, 0xd3, 0x3b,
+ 0x47, 0x42, 0xe6, 0x29, 0xb4, 0xef, 0x6f, 0x12, 0x63, 0x3d, 0x98, 0xa3, 0x4f, 0x81, 0xc3, 0xfc,
+ 0xb3, 0xf4, 0x35, 0xb7, 0x2c, 0xa7, 0x0e, 0xeb, 0xe3, 0xdc, 0xc0, 0xdd, 0x75, 0x2b, 0x76, 0x9e,
+ 0xbe, 0x0a, 0x0d, 0x82, 0x54, 0xcd, 0xab, 0x01, 0x5b, 0x58, 0x6a, 0xd8, 0xbb, 0x75, 0x4e, 0x2a,
+ 0xd0, 0x2f, 0x58, 0xce, 0x8b, 0x59, 0x2c, 0x9c, 0xab, 0x01, 0xc9, 0x6e, 0x1b, 0xc1, 0x12, 0xa2,
+ 0xb6, 0x80, 0x07, 0x25, 0x8c, 0xad, 0xc1, 0x7e, 0x08, 0x4c, 0x54, 0xfa, 0x8d, 0x7c, 0x95, 0x81,
+ 0x47, 0xe5, 0xe6, 0x4f, 0x04, 0xd0, 0xf2, 0x29, 0xb0, 0x86, 0xa2, 0x1a, 0xca, 0x82, 0xd0, 0x19,
+ 0xda, 0xd3, 0x1c, 0x33, 0xb8, 0x61, 0x93, 0xf2, 0x1f, 0x02, 0xd9, 0x5d, 0xc8, 0x43, 0xdd, 0xd5,
+ 0x7c, 0x07, 0x34, 0xac, 0x54, 0x3f, 0xcb, 0x2c, 0x5e, 0x59, 0xb7, 0x43, 0x73, 0xa8, 0x23, 0xf0,
+ 0x7a, 0xd3, 0xde, 0x58, 0xb1, 0x1d, 0x89, 0xf3, 0x26, 0x92, 0x88, 0xb4, 0x10, 0x7c, 0x19, 0x5f,
+ 0x94, 0xbb, 0xe5, 0x12, 0xae, 0xde, 0xcb, 0xaa, 0x71, 0x1a, 0xe2, 0xee, 0xe0, 0x9c, 0x8a, 0x36,
+ 0xdc, 0xef, 0x16, 0x21, 0x04, 0xe6, 0xc9, 0xc3, 0xc0, 0x52, 0x55, 0xf7, 0x53, 0xf5, 0x9c, 0xf5,
+ 0x44, 0x53, 0x8f, 0x7e, 0x22, 0xa7, 0xa4, 0x06, 0x80, 0x92, 0x17, 0xb5, 0x54, 0x58, 0x50, 0xe1,
+ 0x4e, 0xfb, 0x10, 0x6f, 0xb0, 0x15, 0x64, 0x86, 0xce, 0xbc, 0xe5, 0x80, 0xd9, 0x6b, 0xc4, 0x0d,
+ 0x8d, 0xce, 0x42, 0x36, 0xf0, 0x02, 0xed, 0xbe, 0xe1, 0xfd, 0xdd, 0xce, 0x55, 0x22, 0x7d, 0xfd,
+ 0x7b, 0x05, 0xf0, 0x53, 0x22, 0x49, 0x48, 0x36, 0xf0, 0x72, 0x1a, 0x79, 0x39, 0x2c, 0x0d, 0x58,
+ 0x5e, 0x13, 0x7e, 0xc2, 0xf9, 0xf8, 0x81, 0x89, 0x68, 0x7b, 0x1a, 0xc5, 0xef, 0xa1, 0xce, 0x01,
+ 0xb9, 0x20, 0x67, 0x96, 0x58, 0x01, 0x7c, 0x07, 0x55, 0x5b, 0x55, 0x77, 0xa6, 0x38, 0x92, 0xfc,
+ 0x59, 0xb6, 0x60, 0x12, 0x5f, 0x98, 0x01, 0xc1, 0x98, 0xdb, 0x7d, 0xff, 0x6f, 0x7a, 0xc5, 0x9e,
+ 0xa4, 0xd1, 0x1e, 0xa2, 0x3a, 0xe0, 0x27, 0xd9, 0x18, 0x6d, 0x7f, 0xa8, 0xc1, 0x39, 0x3a, 0x52,
+ 0x4c, 0x72, 0x7a, 0x08, 0xef, 0xb9, 0xa8, 0x73, 0x35, 0x31, 0x7c, 0xfb, 0x30, 0x2a, 0x98, 0x3f,
+ 0xb2, 0xc0, 0x51, 0xa5, 0xb7, 0xce, 0xf1, 0xc8, 0x54, 0xf8, 0xec, 0x69, 0x28, 0x74, 0x53, 0x22,
+ 0x75, 0x09, 0xeb, 0x85, 0x24, 0x44, 0x97, 0x83, 0x09, 0xb8, 0x49, 0x78, 0x53, 0x34, 0xcc, 0xdb,
+ 0x22, 0x76, 0xf6, 0xd6, 0xc2, 0x15, 0xc7, 0x61, 0xaa, 0x27, 0xf7, 0x14, 0x1a, 0xb7, 0xad, 0xf6,
+ 0xc0, 0x20, 0xaa, 0xb0, 0x33, 0xa8, 0x64, 0x7e, 0xe7, 0x69, 0x2d, 0x6b, 0xf8, 0x64, 0xee, 0xaf,
+ 0xb0, 0x2d, 0x2f, 0xae, 0xba, 0xb2, 0x52, 0xa4, 0xba, 0x4f, 0xc9, 0x7e, 0x68, 0xc1, 0x49, 0xd9,
+ 0x92, 0xdb, 0x5f, 0x83, 0xb9, 0xb3, 0xc6, 0x7a, 0xeb, 0x44, 0x3d, 0x63, 0x6b, 0x01, 0x00, 0xf9,
+ 0x58, 0x09, 0x72, 0x22, 0x70, 0x15, 0x30, 0x1d, 0x4e, 0xb2, 0x97, 0x53, 0xc8, 0x89, 0x85, 0x5f,
+ 0xd0, 0x1b, 0x00, 0x88, 0xf0, 0xc3, 0x86, 0x2c, 0x21, 0x07, 0xe9, 0x2c, 0x24, 0x8c, 0x94, 0x90,
+ 0x31, 0xb1, 0x7b, 0xff, 0xf6, 0xdf, 0xf9, 0xd8, 0x4b, 0xdc, 0x7d, 0xaa, 0x18, 0xe7, 0x37, 0xd3,
+ 0x48, 0xa5, 0x04, 0x28, 0xc0, 0x5d, 0xf9, 0x0b, 0xb0, 0x96, 0x97, 0x3a, 0x7c, 0xf7, 0x21, 0x57,
+ 0xac, 0x9c, 0x98, 0x34, 0xb9, 0xfa, 0xb0, 0x49, 0x79, 0x5e, 0x86, 0xad, 0x29, 0x25, 0x31, 0x03,
+ 0xdf, 0x1b, 0xd9, 0xbb, 0xcb, 0x4c, 0x8a, 0x8f, 0xbd, 0x58, 0x31, 0xc7, 0x0c, 0x02, 0x0e, 0xa5,
+ 0xd5, 0x8e, 0x23, 0xce, 0x0e, 0x24, 0xd7, 0xd3, 0x01, 0x25, 0xf0, 0xf8, 0x1c, 0xae, 0x86, 0x4f,
+ 0xad, 0xb2, 0xf4, 0xf1, 0xe3, 0xcc, 0x8d, 0xec, 0xae, 0x01, 0xc7, 0xa8, 0x8c, 0x5e, 0xe0, 0xe4,
+ 0x0c, 0x5a, 0x0e, 0x48, 0xa3, 0x56, 0x2d, 0xa1, 0x31, 0x62, 0x56, 0x1c, 0x48, 0x7e, 0x4d, 0x46,
+ 0x26, 0x10, 0x65, 0x1d, 0x45, 0x38, 0x1f, 0xbe, 0x7e, 0x5e, 0x70, 0x26, 0x5f, 0x13, 0xa7, 0xf1,
+ 0x8b, 0xc8, 0x0c, 0xc8, 0x98, 0xbc, 0xbd, 0x7e, 0x17, 0xce, 0xad, 0x3c, 0x27, 0xd9, 0x35, 0x8a,
+ 0xfd, 0x47, 0x83, 0x34, 0x43, 0x00, 0x1b, 0x19, 0xbf, 0xf3, 0xed, 0xf7, 0xae, 0x48, 0x65, 0xcc,
+ 0x34, 0x3a, 0x62, 0x5a, 0x30, 0x45, 0xb5, 0x84, 0x55, 0x56, 0x21, 0x7b, 0xb9, 0xad, 0xc6, 0xbc,
+ 0x16, 0x8e, 0xb0, 0x63, 0x94, 0x5a, 0xb7, 0xbf, 0x4f, 0x00, 0x23, 0x07, 0x2f, 0x1f, 0x40, 0x37,
+ 0xc4, 0xf0, 0x88, 0x7a, 0xe6, 0x37, 0x89, 0xfd, 0xbb, 0xfd, 0x48, 0x88, 0x70, 0x3b, 0x69, 0x5a,
+ 0x46, 0xdb, 0xbb, 0x75, 0x06, 0xc7, 0xff, 0x39, 0xd2, 0x9b, 0x79, 0x3c, 0x0e, 0xa5, 0xdd, 0x64,
+ 0x80, 0x12, 0x25, 0x09, 0x3f, 0x07, 0x0c, 0x0e, 0xc7, 0xaf, 0x2d, 0x9e, 0xc1, 0xc9, 0x34, 0x6a,
+ 0xf9, 0xba, 0x89, 0x99, 0x91, 0x2f, 0xc6, 0xc2, 0x77, 0xe8, 0x92, 0xd5, 0x05, 0x01, 0x3e, 0x18,
+ 0x2f, 0x8b, 0xd1, 0x4c, 0x46, 0x00, 0x13, 0xe1, 0x28, 0x99, 0x34, 0xd2, 0x9f, 0xf5, 0xb7, 0x27,
+ 0xf1, 0x89, 0xe6, 0x91, 0x9e, 0x8a, 0x78, 0x42, 0x64, 0xde, 0xd8, 0x50, 0xc0, 0x70, 0xfb, 0x9b,
+ 0xad, 0x95, 0x11, 0xc1, 0x3f, 0xa7, 0x1c, 0xfc, 0x28, 0xe8, 0xad, 0x25, 0x5b, 0x13, 0xb5, 0x0b,
+ 0xb8, 0x48, 0xa4, 0x25, 0xec, 0xfc, 0xc9, 0x0d, 0x29, 0xc0, 0x47, 0x86, 0xcf, 0xf4, 0xe6, 0x74,
+ 0x55, 0x09, 0x6d, 0x3e, 0xef, 0xc4, 0xdb, 0x49, 0xe7, 0x01, 0xf9, 0x81, 0x0e, 0x15, 0x0d, 0x3d,
+ 0xd7, 0x28, 0x4c, 0x34, 0x39, 0x39, 0x98, 0xec, 0x0e, 0xd2, 0x02, 0x5b, 0x8f, 0x0c, 0x8e, 0xed,
+ 0xa7, 0xdc, 0x36, 0x48, 0x71, 0x72, 0xef, 0x7a, 0xfc, 0x9f, 0x92, 0xfb, 0x00, 0x4a, 0xea, 0x2e,
+ 0xf3, 0xcc, 0xe0, 0x87, 0x89, 0x2a, 0xc0, 0x2d, 0xe3, 0xf7, 0x2d, 0x8e, 0xc2, 0xd6, 0xe7, 0xfe,
+ 0xec, 0x7a, 0x48, 0xc5, 0x6e, 0x0e, 0xbe, 0x07, 0xe8, 0x97, 0x0d, 0x24, 0xd1, 0xa0, 0xa2, 0x9e,
+ 0x05, 0x19, 0x5e, 0x18, 0xfa, 0x5f, 0xd6, 0xd0, 0x7c, 0x21, 0x8f, 0xf9, 0xc9, 0xc3, 0x5c, 0x24,
+ 0xf8, 0x5f, 0x6f, 0xe4, 0xb8, 0xfa, 0xab, 0xe7, 0xa2, 0x81, 0x33, 0x03, 0x97, 0x80, 0xdb, 0x7c,
+ 0xd0, 0xcd, 0x05, 0x33, 0x84, 0xec, 0x27, 0x9f, 0x0a, 0xb5, 0x9d, 0xcf, 0x7c, 0x34, 0x03, 0xe0,
+ 0x1c, 0x43, 0xc1, 0x65, 0x3f, 0x01, 0x9d, 0x1a, 0x7c, 0x9f, 0xf7, 0xc6, 0xed, 0x39, 0x52, 0x8e,
+ 0xf0, 0x0f, 0xa3, 0x74, 0x2d, 0xce, 0x93, 0x22, 0x75, 0xf0, 0x6d, 0x06, 0xfd, 0x54, 0xec, 0x1a,
+ 0x31, 0xc8, 0xe5, 0x21, 0xcb, 0xbf, 0xac, 0x88, 0xcb, 0x30, 0x3a, 0xf0, 0x3d, 0xe6, 0x65, 0x79,
+ 0x54, 0x69, 0xa1, 0x80, 0x56, 0x52, 0xda, 0x7a, 0x76, 0xef, 0xfb, 0x27, 0xc3, 0x92, 0x53, 0xca,
+ 0x19, 0x29, 0x73, 0x81, 0x1a, 0x96, 0xc8, 0x51, 0x10, 0x0b, 0x10, 0x93, 0x37, 0xb5, 0xb0, 0xe6,
+ 0xe4, 0x80, 0xdb, 0xe0, 0x91, 0x6b, 0x8c, 0x1c, 0x7e, 0x8e, 0x51, 0x6f, 0xee, 0xd5, 0x87, 0x0a,
+ 0x18, 0x7f, 0x50, 0x98, 0x3d, 0x9f, 0x92, 0x7b, 0xd5, 0x83, 0xeb, 0x30, 0x6d, 0x80, 0x40, 0x64,
+ 0xa9, 0x57, 0x15, 0x80, 0x5a, 0x4e, 0x7e, 0x98, 0x96, 0x4a, 0x8e, 0xc3, 0xfe, 0x4d, 0x6d, 0x02,
+ 0x1f, 0x5b, 0x6b, 0x99, 0x2f, 0x2d, 0x8a, 0x71, 0x60, 0x13, 0xc4, 0x38, 0x00, 0x82, 0x9a, 0xc3,
+ 0x02, 0x0a, 0x36, 0x0c, 0xb0, 0x12, 0x67, 0x86, 0x63, 0x85, 0x34, 0x87, 0x7d, 0x67, 0x47, 0xc7,
+ 0x73, 0xa3, 0x8f, 0x7b, 0x3e, 0xf8, 0x6d, 0x5b, 0x37, 0x4c, 0x29, 0xf6, 0x83, 0x2b, 0xd1, 0xf3,
+ 0xaa, 0x4f, 0xec, 0x6a, 0xad, 0xba, 0x49, 0x1a, 0x4e, 0x61, 0xb1, 0xb0, 0x6f, 0x05, 0xe4, 0x44,
+ 0x7c, 0x30, 0x36, 0x0a, 0x28, 0x4d, 0x60, 0xc0, 0xba, 0xb5, 0xcc, 0x5d, 0x5d, 0xbb, 0x60, 0x12,
+ 0x5f, 0x00, 0x3f, 0xa7, 0xf0, 0xaf, 0x34, 0x62, 0xdf, 0xdb, 0xff, 0x34, 0xde, 0x19, 0x27, 0x11,
+ 0x78, 0x01, 0xc2, 0x4d, 0xe8, 0xd1, 0x9e, 0xca, 0xff, 0x02, 0x2d, 0xbd, 0xf9, 0x10, 0x0b, 0xdd,
+ 0x1a, 0xdc, 0xac, 0x77, 0x64, 0x88, 0xb5, 0xeb, 0xba, 0xb7, 0xc0, 0xb7, 0x2d, 0xcf, 0x0e, 0x4a,
+ 0xa3, 0x56, 0x43, 0xd1, 0xb2, 0x92, 0x6e, 0x03, 0x2a, 0x1f, 0x9b, 0x4c, 0x5d, 0x65, 0x61, 0x80,
+ 0x41, 0x17, 0x86, 0x01, 0xcb, 0xc0, 0xcc, 0x73, 0xda, 0x9c, 0x9e, 0x5e, 0x93, 0x90, 0x11, 0xcf,
+ 0xc3, 0x0c, 0x95, 0x34, 0x83, 0x00, 0x02, 0xad, 0xcd, 0x1c, 0x23, 0xca, 0x90, 0xd1, 0x63, 0xd9,
+ 0xee, 0x50, 0x05, 0x28, 0xf2, 0xe6, 0x77, 0x4c, 0x1a, 0x94, 0xac, 0xed, 0x48, 0x62, 0xf6, 0xbb,
+ 0x76, 0xf8, 0x85, 0xe0, 0x4f, 0x3a, 0x2c, 0x19, 0xd8, 0xf1, 0x09, 0xc4, 0x36, 0x58, 0xdb, 0xaa,
+ 0x30, 0x0d, 0xf1, 0x65, 0xe0, 0x43, 0xa3, 0x7e, 0x50, 0x17, 0x05, 0x99, 0x87, 0xc4, 0x03, 0x84,
+ 0x83, 0x92, 0xd6, 0x67, 0x01, 0x20, 0x63, 0x78, 0x8a, 0xb4, 0xf7, 0xde, 0x75, 0x54, 0x85, 0x47,
+ 0x2f, 0xc3, 0x37, 0xc1, 0xaa, 0xa8, 0xde, 0xc9, 0x88, 0x86, 0xe0, 0xe4, 0xaa, 0x9d, 0x35, 0xba,
+ 0x49, 0xd1, 0x44, 0x1a, 0x5a, 0xc3, 0x62, 0xeb, 0xb6, 0x4f, 0x63, 0x7c, 0x3e, 0x8e, 0x4b, 0x2d,
+ 0xb0, 0xd6, 0xd8, 0x2f, 0x3a, 0xbc, 0x80, 0x56, 0xbf, 0xc1, 0x14, 0x23, 0x4f, 0x12, 0x72, 0xfe,
+ 0xed, 0x77, 0xd6, 0x52, 0x8b, 0x05, 0x3c, 0x7c, 0x0a, 0x1b, 0x04, 0x55, 0x21, 0x47, 0x1c, 0x16,
+ 0x25, 0x60, 0x86, 0x01, 0xad, 0x09, 0x1b, 0xe6, 0x66, 0x88, 0x47, 0x66, 0x12, 0x2e, 0x5c, 0x5a,
+ 0xd3, 0xe8, 0x3d, 0x76, 0xf4, 0x95, 0x4a, 0x3b, 0x4e, 0x8d, 0xb2, 0xc0, 0xca, 0x2a, 0xac, 0xbe,
+ 0x10, 0xbb, 0x5f, 0x9e, 0xd7, 0x9f, 0x25, 0x80, 0x69, 0x1b, 0xff, 0xcf, 0xe5, 0x42, 0xde, 0xcc,
+ 0xf0, 0xe3, 0x56, 0x85, 0x16, 0x53, 0x40, 0x60, 0x77, 0x55, 0xc8, 0x8b, 0xc0, 0x45, 0x80, 0xe7,
+ 0x00, 0x0f, 0x0d, 0x63, 0x0e, 0x5f, 0xb3, 0xc0, 0x73, 0x78, 0xf7, 0xa3, 0x97, 0x87, 0xc5, 0x1f,
+ 0x0e, 0x49, 0x93, 0x5e, 0x02, 0x50, 0x73, 0x70, 0xf2, 0xbf, 0xcd, 0x83, 0xa0, 0x81, 0x3f, 0x50,
+ 0x25, 0xd5, 0xeb, 0x00, 0xb7, 0xb2, 0xa7, 0x35, 0x7f, 0x7c, 0x44, 0x73, 0xf0, 0x72, 0x44, 0x86,
+ 0x69, 0x27, 0x8d, 0x20, 0x16, 0xf4, 0x15, 0x4d, 0x2e, 0x7e, 0xaf, 0xb2, 0x12, 0x81, 0xe6, 0x38,
+ 0xe4, 0xb4, 0xb4, 0xd7, 0xa9, 0xfc, 0x5a, 0x1c, 0xe9, 0x3d, 0x7a, 0xc4, 0xf6, 0x91, 0x2c, 0x98,
+ 0x00, 0x49, 0x3d, 0xce, 0x47, 0xc8, 0x8f, 0xbf, 0xc9, 0xed, 0xe7, 0x87, 0x1e, 0x75, 0x7d, 0xf6,
+ 0xbb, 0x4e, 0x99, 0x52, 0xc0, 0xd2, 0x48, 0x25, 0xc4, 0xc5, 0x93, 0x97, 0xdb, 0x4b, 0x87, 0x33,
+ 0xca, 0x64, 0x50, 0x0a, 0x30, 0xa6, 0x50, 0x94, 0xfe, 0x56, 0xa4, 0xbb, 0xc0, 0x24, 0x56, 0xb0,
+ 0xd7, 0x55, 0x74, 0x0c, 0x90, 0x6d, 0xe7, 0x4a, 0x00, 0xa0, 0xee, 0x3c, 0x51, 0xdf, 0xf0, 0xec,
+ 0x5b, 0xfc, 0xbf, 0xf1, 0xb9, 0xb4, 0x98, 0x00, 0xda, 0x55, 0x45, 0xa8, 0xf0, 0x02, 0xa8, 0xd6,
+ 0xe0, 0xe4, 0x54, 0x4f, 0x5d, 0x75, 0xb1, 0xdc, 0xf2, 0x22, 0x80, 0xff, 0xeb, 0x13, 0xf7, 0xb1,
+ 0x14, 0xed, 0x07, 0x24, 0xd1, 0xab, 0xe1, 0xc8, 0x53, 0x52, 0x60, 0x25, 0xc8, 0x89, 0xe0, 0x30,
+ 0xd2, 0xa4, 0x61, 0xf6, 0x65, 0xc7, 0x3a, 0x19, 0x79, 0x2a, 0x35, 0x03, 0x22, 0x88, 0x65, 0x1f,
+ 0x92, 0x65, 0x2d, 0xb1, 0x71, 0xc2, 0x04, 0x16, 0x96, 0x18, 0x2c, 0xa4, 0xd0, 0xc0, 0xdc, 0xac,
+ 0x3d, 0xb7, 0x82, 0xb2, 0x3f, 0xc0, 0x1b, 0xff, 0xae, 0x5c, 0xb8, 0x63, 0xd2, 0xb3, 0xd0, 0x55,
+ 0xfa, 0xb0, 0xf3, 0xd1, 0xc2, 0x55, 0xb5, 0x6a, 0x5d, 0x60, 0x3d, 0x94, 0xa4, 0x26, 0x6f, 0x5e,
+ 0x8e, 0x01, 0xf8, 0xe1, 0xd4, 0x1a, 0x0c, 0xd7, 0x32, 0xcd, 0xf0, 0xdc, 0x70, 0x04, 0x61, 0x42,
+ 0xd0, 0x81, 0xaf, 0x12, 0x04, 0x54, 0x76, 0x18, 0x3a, 0x57, 0x09, 0xbe, 0x5b, 0xa8, 0xf0, 0x72,
+ 0xa8, 0xb6, 0x60, 0xe4, 0xc2, 0xb5, 0x01, 0x1b, 0x87, 0x91, 0x24, 0x5a, 0xbf, 0x07, 0x95, 0x1d,
+ 0xac, 0x1c, 0xcf, 0x66, 0x8d, 0x38, 0x16, 0xf4, 0x0a, 0xe5, 0xd9, 0x58, 0x2f, 0x16, 0x6d, 0x04,
+ 0x18, 0x9a, 0x06, 0x01, 0xdc, 0xff, 0x1c, 0xec, 0x23, 0x7c, 0x19, 0xfc, 0x6a, 0x73, 0x9e, 0xbb,
+ 0x9c, 0x01, 0x40, 0x7c, 0xc1, 0x80, 0x5d, 0x46, 0x98, 0xe1, 0x92, 0x04, 0xe7, 0x32, 0xc4, 0x1d,
+ 0xb8, 0x0e, 0x23, 0x4f, 0x41, 0xc5, 0x81, 0xba, 0xfb, 0x3f, 0xad, 0xb6, 0x94, 0x76, 0xdc, 0x9e,
+ 0x0f, 0x9b, 0x33, 0xcf, 0xff, 0xed, 0xbf, 0xf3, 0xd1, 0xc1, 0x1f, 0x59, 0x54, 0xf0, 0xa7, 0x9d,
+ 0x1d, 0x3c, 0x5f, 0x28, 0x33, 0x78, 0x9f, 0x85, 0x58, 0x8b, 0x6e, 0xad, 0x23, 0x17, 0x60, 0xc0,
+ 0x10, 0x45, 0x16, 0xa0, 0xe4, 0x44, 0x7c, 0x2c, 0x94, 0x1d, 0x24, 0x5a, 0xbf, 0x00, 0x95, 0x17,
+ 0x7c, 0x1c, 0x55, 0x40, 0x73, 0x63, 0x44, 0x0a, 0x74, 0xe4, 0xbc, 0xe0, 0xec, 0x7a, 0x11, 0xdd,
+ 0x39, 0x2f, 0x24, 0xb8, 0x49, 0xd1, 0x4c, 0x1a, 0xba, 0x43, 0x22, 0x74, 0x0a, 0x32, 0x9a, 0xaf,
+ 0x00, 0x0d, 0x66, 0xd3, 0x69, 0x65, 0x6a, 0x1f, 0x80, 0x41, 0xc5, 0xe1, 0xdc, 0xc8, 0x5f, 0xac,
+ 0xa1, 0x80, 0x90, 0xee, 0x85, 0x78, 0x1f, 0x22, 0x7c, 0x1b, 0x69, 0xdb, 0x35, 0x87, 0x8c, 0xcb,
+ 0x31, 0x69, 0x7c, 0xbf, 0x99, 0xa3, 0xe3, 0xf9, 0x1c, 0xce, 0x82, 0x3b, 0xd7, 0x2f, 0xa5, 0x83,
+ 0xfa, 0xb9, 0x31, 0x62, 0xf2, 0x96, 0x85, 0xb2, 0x04, 0x94, 0x8c, 0x18, 0xff, 0xcd, 0x2a, 0x42,
+ 0x0c, 0x02, 0xa9, 0x4f, 0xbd, 0x6a, 0xc0, 0x82, 0x9b, 0x4d, 0x25, 0x80, 0x87, 0x22, 0x5b, 0xe0,
+ 0x6b, 0x77, 0xba, 0xa3, 0x40, 0xdd, 0x03, 0x9d, 0x19, 0x11, 0xbc, 0x0d, 0xc6, 0x89, 0x35, 0xd6,
+ 0xa3, 0x88, 0xaf, 0x17, 0xad, 0x3d, 0xb0, 0x26, 0x42, 0x61, 0xb0, 0x72, 0x08, 0x9a, 0xdd, 0x42,
+ 0x83, 0x92, 0x45, 0x37, 0x3a, 0x97, 0x93, 0x55, 0xb4, 0x38, 0xa3, 0x42, 0x2a, 0x62, 0xe2, 0x67,
+ 0x4d, 0x1b, 0x98, 0xdb, 0x5d, 0xff, 0xd4, 0xfe, 0x02, 0x80, 0x81, 0x0c, 0xaa, 0x06, 0xa2, 0x96,
+ 0xab, 0x20, 0xe4, 0x96, 0xeb, 0xe9, 0x1a, 0xae, 0xb2, 0xae, 0x0c, 0xbf, 0x42, 0xa4, 0xd6, 0x02,
+ 0x16, 0x39, 0x4a, 0x9c, 0x73, 0x33, 0xb6, 0xcf, 0xf8, 0x48, 0x1e, 0xf9, 0xe7, 0xdf, 0xb3, 0xb4,
+ 0xa1, 0x85, 0x23, 0x81, 0x62, 0xe0, 0x4b, 0xf2, 0x76, 0xb9, 0xc4, 0xf2, 0x61, 0x56, 0x7d, 0xba,
+ 0x86, 0x01, 0x17, 0x86, 0x48, 0xe0, 0x14, 0x61, 0x07, 0xbf, 0x5c, 0x58, 0xd0, 0xe1, 0xfc, 0xb3,
+ 0x56, 0x1b, 0xe7, 0x46, 0x9e, 0x15, 0x11, 0x19, 0x12, 0x39, 0x57, 0xf8, 0xdd, 0xe0, 0x84, 0xf8,
+ 0x0c, 0x6e, 0x27, 0xd3, 0x9f, 0x22, 0xd5, 0x50, 0x71, 0x48, 0xa2, 0x8a, 0xe0, 0xe4, 0xa5, 0x85,
+ 0x5a, 0xed, 0x00, 0x24, 0xb2, 0x7f, 0x9f, 0xa5, 0x41, 0xf5, 0xc1, 0xc9, 0x55, 0x47, 0xf1, 0xf5,
+ 0x63, 0xb8, 0xc9, 0x8b, 0x17, 0x70, 0x63, 0xd5, 0xee, 0xef, 0xc9, 0x78, 0x47, 0xc1, 0x9d, 0x13,
+ 0x00, 0xc4, 0xf2, 0x8d, 0xf6, 0x18, 0x7f, 0xe7, 0xcc, 0xab, 0x86, 0xcd, 0xa8, 0x1b, 0x13, 0xd1,
+ 0x4c, 0x33, 0x96, 0x98, 0x81, 0xbc, 0x44, 0x1a, 0x0f, 0x91, 0x21, 0xab, 0x98, 0xaa, 0x92, 0x04,
+ 0xaf, 0x32, 0x75, 0x1b, 0x26, 0xf0, 0xf5, 0x60, 0xe0, 0x16, 0x60, 0xfe, 0xb9, 0xf8, 0x78, 0x13,
+ 0xb7, 0xd0, 0xb6, 0x9d, 0xc3, 0x00, 0x55, 0x46, 0x59, 0x5d, 0xf0, 0xe1, 0x38, 0x5a, 0xcb, 0x01,
+ 0xec, 0xa2, 0x02, 0x31, 0xf5, 0x0c, 0xff, 0xae, 0xe2, 0xcd, 0xa3, 0x09, 0x70, 0x00, 0x7b, 0x78,
+ 0x29, 0x86, 0x05, 0x86, 0x62, 0x18, 0x05, 0x84, 0x09, 0xaa, 0x58, 0x30, 0xff, 0x9d, 0x10, 0x2d,
+ 0xb7, 0x79, 0xfb, 0xd7, 0x83, 0x92, 0x07, 0x6e, 0x6c, 0xde, 0x02, 0xf4, 0xb4, 0xa2, 0xb7, 0x01,
+ 0xc8, 0x8b, 0x55, 0x14, 0x2e, 0xbd, 0x6f, 0xf4, 0x4b, 0x75, 0xc6, 0x00, 0x0e, 0x48, 0x1b, 0x56,
+ 0x5e, 0x8d, 0xaf, 0x5d, 0x6f, 0xbd, 0x88, 0xc4, 0x0c, 0x2e, 0x04, 0xfa, 0x69, 0x06, 0x53, 0xd4,
+ 0x50, 0x15, 0xb2, 0x40, 0x82, 0x51, 0x9a, 0xb2, 0x54, 0x73, 0x15, 0x55, 0xf2, 0x91, 0x3c, 0xd3,
+ 0x92, 0x66, 0xf4, 0xf0, 0x92, 0xef, 0xf8, 0x97, 0x26, 0x7c, 0x1d, 0xfa, 0x93, 0xbf, 0x08, 0x0f,
+ 0x9c, 0x30, 0x21, 0x62, 0xb5, 0x44, 0xab, 0xb4, 0x00, 0x8a, 0x85, 0x83, 0xfa, 0x1e, 0xbb, 0xc3,
+ 0x54, 0x72, 0x80, 0x18, 0xca, 0xa7, 0xae, 0xe2, 0xf1, 0x48, 0x07, 0xfa, 0xd3, 0x43, 0x56, 0x11,
+ 0x4a, 0x3b, 0x02, 0x31, 0x66, 0x0c, 0x7f, 0xe7, 0x4c, 0x9b, 0x7d, 0x94, 0xcc, 0x90, 0x46, 0x06,
+ 0x36, 0x94, 0x70, 0x9a, 0x58, 0x59, 0x1e, 0xe0, 0x5e, 0x9b, 0x15, 0xe2, 0xae, 0x23, 0x1a, 0x52,
+ 0xbe, 0xfd, 0xfb, 0x15, 0xd7, 0xce, 0xc5, 0xcf, 0x42, 0x78, 0x00, 0x36, 0xc8, 0x88, 0xea, 0x54,
+ 0x1c, 0x94, 0x7f, 0xbc, 0x2e, 0x7b, 0x44, 0x5c, 0x09, 0x64, 0xdb, 0xf0, 0x63, 0xb8, 0xcb, 0x8b,
+ 0x3f, 0x5b, 0x8f, 0x50, 0xdf, 0xbd, 0xc8, 0xec, 0x7c, 0xf1, 0xde, 0xd0, 0xc0, 0xf3, 0x89, 0x03,
+ 0x62, 0x4e, 0xba, 0x88, 0x65, 0x3d, 0xc0, 0xb1, 0x9c, 0xc1, 0xf6, 0xd2, 0xa3, 0xa4, 0x8c, 0x32,
+ 0x60, 0x9a, 0x18, 0x36, 0xcf, 0x9a, 0xe6, 0x45, 0x57, 0x66, 0xe6, 0x85, 0x01, 0x66, 0x51, 0x96,
+ 0x61, 0xec, 0xb2, 0xbf, 0xcf, 0x28, 0x97, 0x8d, 0x5d, 0xd5, 0x6c, 0x65, 0xc1, 0x23, 0x1f, 0x22,
+ 0x05, 0xd6, 0x2a, 0x18, 0x3f, 0x2d, 0xe0, 0x12, 0xc3, 0x78, 0xbf, 0xf3, 0x85, 0x79, 0x96, 0x8b,
+ 0x87, 0x75, 0x48, 0x33, 0x95, 0x9b, 0x82, 0xb2, 0x58, 0x4a, 0xc1, 0x80, 0x47, 0x46, 0x46, 0x29,
+ 0xc1, 0x80, 0x03, 0xa8, 0xc7, 0x3e, 0x00, 0xbe, 0xb2, 0xc3, 0x14, 0x06, 0x48, 0x2e, 0xfc, 0x3b,
+ 0x95, 0x0c, 0x7f, 0xe7, 0xf0, 0x3b, 0xec, 0x0a, 0x9e, 0x00, 0x97, 0x8a, 0xa2, 0xe9, 0x55, 0x2d,
+ 0x38, 0x3a, 0xfb, 0xe7, 0x7e, 0x77, 0x72, 0x6a, 0xc7, 0x1b, 0x4e, 0x18, 0xbc, 0x20, 0x4b, 0x6b,
+ 0x5f, 0xbf, 0xf1, 0x0e, 0x11, 0x68, 0xf8, 0xc9, 0x00, 0xd6, 0x90, 0x9b, 0xbc, 0x00, 0xca, 0xbe,
+ 0xf2, 0x7a, 0xe1, 0x4f, 0xc6, 0x8d, 0xb6, 0x6b, 0x7d, 0x77, 0x7b, 0x32, 0x69, 0x56, 0x50, 0xc4,
+ 0x50, 0x35, 0xc0, 0xe0, 0xe8, 0xc6, 0xf5, 0x77, 0x73, 0xc0, 0x00, 0xb3, 0xe1, 0x0f, 0x71, 0x0b,
+ 0x80, 0x35, 0x09, 0x7f, 0x44, 0x2d, 0xbb, 0x4f, 0x70, 0xae, 0x69, 0x99, 0x19, 0xed, 0xaa, 0xe3,
+ 0x31, 0x3e, 0x37, 0xcb, 0x95, 0x9a, 0xc0, 0x05, 0xbe, 0x7d, 0xb4, 0xed, 0x72, 0xd7, 0x41, 0x82,
+ 0xa4, 0x05, 0x19, 0x21, 0xc9, 0x38, 0x28, 0xb0, 0xd3, 0xfb, 0x01, 0x51, 0x86, 0x86, 0x7f, 0xd6,
+ 0xa6, 0x86, 0x60, 0x13, 0x83, 0x98, 0xd1, 0xaf, 0xb9, 0x4f, 0x10, 0x73, 0xb6, 0x28, 0x2f, 0xf2,
+ 0xda, 0x53, 0x6d, 0x19, 0xbd, 0x78, 0x77, 0xf7, 0x05, 0x36, 0x7f, 0x22, 0x78, 0x2d, 0x14, 0x62,
+ 0xc5, 0xdd, 0x5f, 0xa8, 0x12, 0x5d, 0x7f, 0x80, 0x9d, 0xd9, 0x41, 0x67, 0xd4, 0x30, 0x1a, 0xbe,
+ 0x59, 0xf8, 0xb1, 0xdc, 0xa4, 0xc5, 0xbf, 0xb3, 0xc7, 0xaf, 0x05, 0x5e, 0xc1, 0xc9, 0x26, 0x9f,
+ 0x89, 0x3a, 0x1a, 0x41, 0x6c, 0xd1, 0xc2, 0x07, 0x69, 0xcf, 0xff, 0xaf, 0xa1, 0x2d, 0x5f, 0xaa,
+ 0xeb, 0xc0, 0xd5, 0x3d, 0x34, 0x1b, 0x01, 0xdd, 0x08, 0xdc, 0x15, 0xdc, 0x6f, 0xda, 0x44, 0x35,
+ 0x95, 0x05, 0xb0, 0x13, 0x58, 0x66, 0x7e, 0xa8, 0x4d, 0x55, 0xb0, 0xfe, 0xc8, 0x49, 0xcd, 0xe3,
+ 0x5e, 0xfb, 0x9a, 0x1a, 0x9b, 0xd7, 0x3f, 0xe9, 0x4c, 0xe8, 0x1d, 0x0b, 0x67, 0xa5, 0x0d, 0x82,
+ 0x17, 0x4c, 0x35, 0x5e, 0x86, 0xa1, 0x22, 0x20, 0xf1, 0x23, 0x9c, 0x55, 0x21, 0xb3, 0xf0, 0xc0,
+ 0x67, 0x4c, 0xc3, 0xc3, 0xe0, 0xcf, 0x44, 0xeb, 0xcc, 0x8c, 0xb3, 0x0a, 0x77, 0x0c, 0x76, 0x22,
+ 0x95, 0xe7, 0xc1, 0xa5, 0xb1, 0xdf, 0x82, 0xb8, 0x00, 0xb0, 0xae, 0x58, 0x0c, 0xff, 0x02, 0xf1,
+ 0xe1, 0x0c, 0x2b, 0x62, 0x0f, 0xc7, 0x18, 0xcd, 0xbe, 0x77, 0xee, 0x15, 0x49, 0x53, 0xa1, 0x14,
+ 0xc9, 0x6e, 0x98, 0xc1, 0xef, 0xd1, 0xbe, 0x0d, 0xd7, 0x5a, 0xfe, 0x61, 0xdf, 0x11, 0xc5, 0x34,
+ 0x2a, 0xfe, 0x58, 0x39, 0x46, 0x8d, 0x59, 0x3c, 0x58, 0xcd, 0x0b, 0x01, 0x55, 0x00, 0x49, 0xbd,
+ 0xfe, 0x44, 0x37, 0x8c, 0xae, 0x12, 0x7b, 0x25, 0x03, 0x70, 0x09, 0x5e, 0xc0, 0xb6, 0x8b, 0x72,
+ 0x00, 0xb0, 0x8d, 0x83, 0xd5, 0x10, 0xbe, 0xda, 0x38, 0x42, 0xaf, 0x8b, 0xb1, 0xcc, 0x54, 0x16,
+ 0x62, 0x86, 0xff, 0x9c, 0x03, 0xbf, 0x8d, 0x9b, 0x1e, 0x1b, 0x3d, 0x1c, 0x6b, 0x78, 0xd7, 0x08,
+ 0xfc, 0xc7, 0x24, 0xdb, 0xc6, 0xff, 0xed, 0x11, 0xa7, 0x86, 0x14, 0x47, 0x0e, 0x5e, 0xf6, 0x96,
+ 0xb1, 0x79, 0x03, 0x4a, 0x0b, 0x53, 0xfd, 0x93, 0x47, 0x1b, 0x6c, 0x25, 0x6a, 0x90, 0xf4, 0x21,
+ 0x00, 0x7b, 0xd6, 0x96, 0xbe, 0x73, 0x3c, 0xe2, 0xd4, 0xe2, 0xf6, 0xd2, 0x23, 0xe9, 0x0d, 0xb2,
+ 0x4a, 0x2f, 0xe6, 0x1f, 0x3d, 0x89, 0x42, 0x79, 0x62, 0xbf, 0x02, 0xf0, 0x86, 0x0c, 0xd7, 0x3b,
+ 0x04, 0x95, 0x44, 0x18, 0x5c, 0xe4, 0x6d, 0x7c, 0x8d, 0xb4, 0x16, 0x55, 0xa3, 0xf3, 0xa9, 0xf7,
+ 0x4b, 0x54, 0x20, 0x3d, 0x28, 0x39, 0x97, 0x24, 0x5c, 0x00, 0x99, 0xdc, 0x7f, 0xe7, 0x92, 0x82,
+ 0x5b, 0x83, 0x3b, 0x81, 0x8e, 0xe3, 0x4e, 0x2d, 0x7c, 0x03, 0x1e, 0xb2, 0xcd, 0x7b, 0x39, 0x22,
+ 0x8d, 0x58, 0xfe, 0xba, 0xc5, 0xa2, 0xe3, 0x6c, 0xc3, 0xf2, 0x72, 0x3a, 0x30, 0xbc, 0xba, 0x69,
+ 0x06, 0xf9, 0x46, 0x21, 0xa1, 0x80, 0x83, 0x62, 0xaa, 0xa0, 0xd8, 0x8b, 0xe7, 0x27, 0x28, 0xd5,
+ 0xd7, 0xec, 0xae, 0x15, 0xfd, 0x92, 0x63, 0x64, 0x1c, 0x04, 0xab, 0x23, 0x1b, 0x77, 0xf1, 0x5e,
+ 0x34, 0x93, 0x01, 0xc9, 0x06, 0xdb, 0xcf, 0x98, 0xc4, 0x39, 0x31, 0xbf, 0x70, 0xde, 0x69, 0x47,
+ 0x6f, 0x75, 0xe0, 0x81, 0x0a, 0xea, 0x89, 0x26, 0x4d, 0xc8, 0x3a, 0xc0, 0xf0, 0xbc, 0x06, 0xd7,
+ 0xfb, 0xbc, 0xc7, 0x97, 0x7e, 0x4b, 0xfb, 0xcd, 0x8b, 0xfe, 0xee, 0xdb, 0xd5, 0x54, 0xbe, 0x5d,
+ 0x05, 0xf3, 0x8f, 0x7e, 0x8e, 0xe9, 0x78, 0x1f, 0xcf, 0xfa, 0xae, 0x21, 0x91, 0x15, 0x80, 0x17,
+ 0x78, 0x55, 0xc4, 0x21, 0x44, 0xdd, 0xbf, 0xaf, 0x6f, 0xd2, 0x11, 0xcb, 0x9a, 0x8a, 0x34, 0xa5,
+ 0xf0, 0x2d, 0x51, 0x42, 0x31, 0xce, 0xf2, 0x8e, 0xa4, 0x12, 0x16, 0x71, 0xb6, 0x8a, 0x49, 0x54,
+ 0x6b, 0x0e, 0x79, 0xa6, 0x8f, 0xf2, 0xe3, 0x00, 0x3b, 0x4b, 0xaf, 0xcf, 0x02, 0x41, 0xeb, 0xf0,
+ 0x75, 0xd1, 0xb7, 0xb8, 0x92, 0x86, 0xfd, 0x25, 0x08, 0x7c, 0xb3, 0xdf, 0x8b, 0x5e, 0x66, 0xbd,
+ 0x1c, 0x91, 0x46, 0xac, 0x5d, 0xbd, 0xe3, 0xaa, 0x15, 0xf1, 0xb7, 0x04, 0xff, 0x31, 0x65, 0xbb,
+ 0x81, 0x4d, 0x9b, 0x9d, 0x0d, 0x02, 0xfc, 0xc2, 0x91, 0x70, 0x0b, 0x70, 0x1d, 0xa4, 0x0a, 0xa2,
+ 0xba, 0x60, 0x58, 0x81, 0x5d, 0x13, 0xd1, 0xbe, 0xe7, 0x81, 0x9a, 0x4c, 0xed, 0x81, 0x72, 0x22,
+ 0xaa, 0xa9, 0x66, 0xc6, 0x12, 0x51, 0x58, 0x72, 0x5a, 0x13, 0xde, 0xcc, 0x18, 0xab, 0x75, 0x67,
+ 0xbe, 0x28, 0x7c, 0x9e, 0x88, 0x2d, 0x42, 0xc8, 0xe2, 0xe0, 0x61, 0x62, 0xe0, 0x84, 0x69, 0xef,
+ 0xdf, 0x35, 0x5a, 0xf9, 0xfd, 0x19, 0x17, 0x4d, 0xf2, 0x37, 0x29, 0xfc, 0xe0, 0x39, 0x17, 0x6f,
+ 0xab, 0xff, 0x8d, 0x8a, 0x2d, 0xa2, 0xd6, 0x55, 0x37, 0x8c, 0xa1, 0x43, 0xb9, 0x9f, 0x90, 0x8d,
+ 0x7c, 0x1c, 0xb7, 0xa5, 0x5e, 0x10, 0xdf, 0xab, 0x75, 0x49, 0xc1, 0xc9, 0xd4, 0xcf, 0xaf, 0x63,
+ 0x24, 0x99, 0xab, 0x07, 0xef, 0x51, 0x9b, 0xdb, 0xfa, 0xc2, 0xe3, 0x5f, 0xa6, 0x19, 0x21, 0x83,
+ 0x04, 0xed, 0x00, 0x92, 0x47, 0xa6, 0xd5, 0xc0, 0x7f, 0x9c, 0x30, 0x13, 0x78, 0x16, 0x44, 0x40,
+ 0xaa, 0xae, 0xef, 0xf0, 0x4b, 0x13, 0x46, 0x1f, 0x05, 0x64, 0x11, 0xd3, 0x13, 0xdb, 0x66, 0x86,
+ 0x30, 0x31, 0x77, 0x4d, 0xf0, 0x32, 0x88, 0xa4, 0x8d, 0x9c, 0xf7, 0xef, 0x57, 0x80, 0xc3, 0x84,
+ 0x27, 0x34, 0x9c, 0x1b, 0x6d, 0x9f, 0x98, 0x11, 0xf8, 0x63, 0xc9, 0xfd, 0x2c, 0x29, 0xf1, 0xa8,
+ 0x4e, 0x19, 0x5c, 0x41, 0x00, 0xa5, 0x17, 0xcc, 0x0c, 0x91, 0x5a, 0xbe, 0x93, 0x06, 0x84, 0xdb,
+ 0x0c, 0xa3, 0x35, 0x4f, 0xdc, 0xc5, 0x35, 0xa7, 0x61, 0x45, 0xf7, 0x84, 0xd3, 0xe1, 0xae, 0x6c,
+ 0x02, 0x55, 0x94, 0x30, 0x79, 0xc3, 0xaa, 0x87, 0xab, 0x6e, 0xf8, 0x70, 0x80, 0x7b, 0xea, 0xa3,
+ 0xd7, 0xb5, 0x92, 0x2c, 0xd5, 0x83, 0xac, 0x68, 0xb6, 0x03, 0xfe, 0xb2, 0x5c, 0xd7, 0xa1, 0x85,
+ 0x04, 0x04, 0x54, 0x42, 0x1a, 0xc7, 0x80, 0x76, 0xaa, 0x7b, 0x30, 0x08, 0xcb, 0x0c, 0x87, 0x08,
+ 0x2e, 0x19, 0x10, 0x60, 0x05, 0x53, 0xd9, 0xa9, 0xe0, 0xc8, 0xb4, 0x49, 0x51, 0xc5, 0xd0, 0x8e,
+ 0x33, 0x8c, 0xc0, 0x9c, 0x70, 0x02, 0x9b, 0x58, 0xdb, 0xf0, 0x43, 0x99, 0x75, 0x39, 0xb6, 0x78,
+ 0x99, 0xd1, 0xe3, 0xe9, 0x8f, 0x80, 0x92, 0x12, 0x9b, 0xa0, 0xc1, 0x60, 0xdf, 0x01, 0x64, 0x7c,
+ 0x1f, 0x07, 0xc4, 0x3e, 0xe3, 0xbb, 0x00, 0x58, 0x0f, 0x00, 0x49, 0x3b, 0x41, 0x44, 0xa4, 0x54,
+ 0x88, 0xd5, 0xd7, 0xad, 0xcd, 0x0c, 0x2a, 0x26, 0x50, 0xaa, 0x8b, 0x0b, 0xf2, 0xbb, 0x16, 0x74,
+ 0xcb, 0x6a, 0x37, 0xe0, 0x72, 0x2d, 0x23, 0x11, 0xb2, 0xae, 0x28, 0xa4, 0x30, 0xc0, 0x18, 0x0b,
+ 0xda, 0x55, 0x63, 0x69, 0xc5, 0x95, 0xce, 0xa2, 0x7d, 0xc8, 0xb5, 0x2a, 0x75, 0xad, 0x00, 0x49,
+ 0x89, 0x6e, 0x0e, 0x4a, 0x38, 0xe6, 0x24, 0x88, 0xab, 0x07, 0xef, 0x51, 0xb5, 0x5f, 0x80, 0xec,
+ 0x87, 0xdb, 0x87, 0x0a, 0xb6, 0xcf, 0xc0, 0x20, 0x1c, 0x10, 0x87, 0x01, 0x18, 0x05, 0xd3, 0x8c,
+ 0x02, 0x6c, 0x43, 0x0c, 0x18, 0x32, 0x3f, 0xb7, 0x45, 0xb6, 0x24, 0xb8, 0xe1, 0x61, 0x1b, 0x73,
+ 0xd7, 0x3c, 0x67, 0x95, 0x57, 0x69, 0x3c, 0x39, 0x5e, 0x3a, 0xc6, 0x44, 0x28, 0xc4, 0x95, 0x0e,
+ 0x5d, 0x33, 0x85, 0x43, 0x8d, 0xd8, 0xc6, 0xf1, 0x2d, 0x51, 0x31, 0x3c, 0x7b, 0xdb, 0xb6, 0xb5,
+ 0x94, 0xe6, 0xbd, 0x75, 0xd6, 0x05, 0x2a, 0xf4, 0xfa, 0x6b, 0xbc, 0x0a, 0xa7, 0xda, 0x54, 0xe4,
+ 0x6b, 0xc9, 0x72, 0x71, 0x8b, 0x54, 0xa3, 0x93, 0x79, 0x0a, 0x7d, 0xd5, 0x81, 0x9f, 0xc2, 0x82,
+ 0x77, 0x1f, 0xd8, 0xe5, 0x5f, 0xd2, 0xee, 0xbe, 0x84, 0x19, 0x10, 0x04, 0xfc, 0x6c, 0x71, 0xa6,
+ 0xc2, 0x2d, 0xd3, 0xed, 0x1c, 0xbd, 0x9e, 0xc6, 0x97, 0x82, 0xb8, 0x10, 0xb7, 0xae, 0x9a, 0xc0,
+ 0x65, 0x3e, 0x6f, 0x6d, 0xce, 0x81, 0xc6, 0xbc, 0x96, 0xfc, 0x67, 0xd2, 0xfc, 0x0d, 0x95, 0x9e,
+ 0x05, 0xbd, 0xfb, 0xe6, 0x74, 0x3a, 0x56, 0x36, 0xec, 0x0f, 0x69, 0xca, 0xcf, 0xcd, 0xa9, 0xef,
+ 0xb3, 0x86, 0x63, 0xb3, 0xed, 0xde, 0x0b, 0x66, 0x5f, 0x3f, 0xaf, 0x80, 0x7f, 0xce, 0x92, 0x4d,
+ 0xaf, 0x83, 0x11, 0xf6, 0x83, 0xac, 0x4f, 0xc1, 0x49, 0x2b, 0x16, 0x40, 0x8f, 0x0b, 0xcb, 0xec,
+ 0x6e, 0xfc, 0xe4, 0x8c, 0xcf, 0xe0, 0x94, 0xd3, 0xac, 0x1c, 0xcd, 0x46, 0x58, 0x0e, 0xa6, 0x44,
+ 0x47, 0x00, 0xb6, 0x94, 0x9f, 0xa7, 0x25, 0x9a, 0xb8, 0x6b, 0xd6, 0x93, 0x5b, 0xb5, 0xb7, 0x59,
+ 0xf0, 0x2c, 0x2c, 0x90, 0x61, 0x4a, 0xbd, 0x52, 0xea, 0x19, 0x97, 0x0a, 0x91, 0xb1, 0x75, 0x05,
+ 0xd4, 0xdd, 0x3d, 0x64, 0x5b, 0x50, 0x70, 0x7c, 0xb7, 0x45, 0x01, 0xdf, 0x37, 0x83, 0x1a, 0xdf,
+ 0xc0, 0x76, 0x81, 0x2b, 0xc1, 0x63, 0x62, 0x5b, 0x35, 0xb1, 0x89, 0xa7, 0xf2, 0x17, 0xc3, 0xd7,
+ 0x16, 0xf8, 0x7c, 0x61, 0x96, 0x4b, 0x86, 0x93, 0x7c, 0x0d, 0x1c, 0x6c, 0x3e, 0x87, 0x27, 0xb5,
+ 0x09, 0xb0, 0xf7, 0x2c, 0x88, 0xef, 0x50, 0xc9, 0x4a, 0x36, 0xc6, 0x47, 0xfa, 0xcb, 0xa6, 0x3f,
+ 0x70, 0xc6, 0xbf, 0xe8, 0xed, 0xae, 0x38, 0x0d, 0xa4, 0xe0, 0x4a, 0xcb, 0xe1, 0x6a, 0xa3, 0x0d,
+ 0x78, 0x5a, 0x93, 0x43, 0x6a, 0x96, 0x52, 0xad, 0x23, 0x80, 0x5d, 0x10, 0x5d, 0x34, 0xa5, 0x6c,
+ 0xb5, 0xca, 0xcb, 0x7c, 0x23, 0xbf, 0x04, 0xa9, 0xde, 0xe0, 0x72, 0xbc, 0x32, 0x5b, 0xc0, 0x09,
+ 0x4b, 0x46, 0x42, 0x0e, 0x94, 0x93, 0x8c, 0x9d, 0x9e, 0xa3, 0xdf, 0xa7, 0xf8, 0x7a, 0xc5, 0x79,
+ 0x39, 0x53, 0xe9, 0x42, 0xe9, 0x56, 0xff, 0xcf, 0x48, 0x5a, 0x8a, 0xc0, 0x31, 0x79, 0x95, 0x36,
+ 0xf4, 0x3e, 0x4e, 0xdb, 0x6b, 0x3f, 0x42, 0x22, 0xd3, 0x73, 0xc0, 0xdd, 0x31, 0x4b, 0xad, 0x87,
+ 0x6f, 0xf0, 0xdf, 0x3c, 0xff, 0xb5, 0xb0, 0xdc, 0x3d, 0xe5, 0x36, 0x05, 0x07, 0xf7, 0xf2, 0x7a,
+ 0x08, 0x8b, 0xc6, 0xfd, 0x89, 0x50, 0xa6, 0xbd, 0xfc, 0x27, 0x5b, 0x2c, 0x0b, 0xec, 0x25, 0x35,
+ 0x49, 0x83, 0x1a, 0xc0, 0x11, 0x9a, 0x34, 0x4e, 0x12, 0x3c, 0x88, 0x87, 0xf3, 0xde, 0x60, 0x1e,
+ 0xbe, 0x38, 0xf5, 0x8c, 0x24, 0x9a, 0x37, 0x07, 0xc7, 0xf7, 0x94, 0xa9, 0x17, 0x3d, 0xac, 0x77,
+ 0xbc, 0x88, 0x78, 0x16, 0x3d, 0x43, 0x9a, 0xf6, 0x72, 0x51, 0x1a, 0xb0, 0x95, 0xfb, 0xae, 0x03,
+ 0xc0, 0x26, 0x91, 0x60, 0x5d, 0x40, 0xd3, 0x61, 0xaa, 0x21, 0x01, 0x18, 0xd5, 0x86, 0xb5, 0x78,
+ 0x01, 0x4c, 0xf8, 0x4f, 0x52, 0xbd, 0xe8, 0x7d, 0x99, 0x03, 0x7d, 0x8d, 0xce, 0x1a, 0x7d, 0xce,
+ 0xc2, 0xb2, 0xfb, 0x02, 0xfc, 0x67, 0xbf, 0x1b, 0xaa, 0x8c, 0x35, 0x26, 0x15, 0x2d, 0x84, 0x96,
+ 0xc4, 0xac, 0xf6, 0x5b, 0xc0, 0x03, 0x77, 0x6f, 0xc2, 0xe4, 0xbd, 0xe1, 0x25, 0xa6, 0x84, 0xaf,
+ 0x20, 0xab, 0x54, 0xf1, 0x71, 0x05, 0x83, 0x91, 0x98, 0x81, 0x7b, 0x77, 0xaa, 0xbd, 0x2e, 0xae,
+ 0x3f, 0xd6, 0x27, 0x2e, 0xcd, 0x3d, 0x61, 0x19, 0xb1, 0x24, 0xc0, 0x2f, 0xbd, 0x2b, 0x36, 0x05,
+ 0xd7, 0x06, 0x3d, 0xcf, 0x27, 0x8e, 0x50, 0x82, 0x16, 0xa6, 0xc0, 0x09, 0xa3, 0x9b, 0x8f, 0x4b,
+ 0x4b, 0x6c, 0x56, 0x0e, 0x97, 0xb3, 0xf5, 0x3a, 0xe0, 0x38, 0xcf, 0x72, 0x93, 0x28, 0xa3, 0x85,
+ 0x6b, 0x5f, 0xfe, 0x61, 0x10, 0x77, 0xb0, 0x15, 0x92, 0x4c, 0x00, 0x86, 0x92, 0xc3, 0x09, 0x68,
+ 0xb9, 0xc8, 0xc5, 0x78, 0x01, 0xcb, 0x9e, 0x2f, 0xf4, 0xf3, 0xd8, 0x41, 0xcd, 0x88, 0xd6, 0x8b,
+ 0xae, 0x5b, 0x1e, 0x54, 0x7e, 0xf1, 0xec, 0xa0, 0xef, 0x75, 0xd6, 0xd9, 0xce, 0x1f, 0x6c, 0x8e,
+ 0xe6, 0x5a, 0x15, 0x46, 0x1e, 0x88, 0x2e, 0x2b, 0xbb, 0xb9, 0xb4, 0xbf, 0x4f, 0x63, 0xf9, 0x5e,
+ 0x8e, 0xcd, 0xa3, 0xfd, 0x11, 0x53, 0x2c, 0xf3, 0x54, 0x57, 0x3a, 0xf7, 0x88, 0x18, 0x57, 0x11,
+ 0x9d, 0x89, 0xb5, 0xff, 0xca, 0xb1, 0x66, 0x22, 0xbe, 0x24, 0x78, 0x13, 0x69, 0x47, 0x16, 0xa3,
+ 0xc0, 0x09, 0x6e, 0x9f, 0x0f, 0xed, 0x5f, 0x2f, 0xab, 0x9c, 0x95, 0xaa, 0x6f, 0xea, 0x00, 0xcf,
+ 0x55, 0xde, 0xbd, 0x8f, 0xc9, 0x18, 0xc7, 0xc1, 0x41, 0x9b, 0xb0, 0x72, 0x35, 0x1a, 0x0f, 0xb9,
+ 0x19, 0x11, 0x97, 0x85, 0x07, 0xa5, 0xe1, 0xc0, 0xb2, 0xb3, 0x0c, 0x74, 0x2f, 0x33, 0xb0, 0xc0,
+ 0xe9, 0xe2, 0x48, 0xe0, 0x42, 0xb0, 0x23, 0xe5, 0x58, 0x93, 0x60, 0x17, 0x30, 0xa8, 0x13, 0x2f,
+ 0x3c, 0x48, 0x18, 0x3b, 0xb1, 0x1b, 0x16, 0xc1, 0x57, 0xd6, 0xed, 0xd5, 0x75, 0x78, 0x01, 0xc1,
+ 0x23, 0x2f, 0x8e, 0xf3, 0x91, 0xcd, 0x72, 0x5e, 0x12, 0x53, 0x8d, 0xfa, 0xc0, 0x7d, 0xc5, 0x93,
+ 0x3f, 0xcf, 0xff, 0xf1, 0xf5, 0xc3, 0x23, 0xeb, 0x2e, 0x4b, 0x92, 0x9a, 0xe5, 0xb8, 0x2f, 0x6c,
+ 0xc3, 0x47, 0x07, 0xec, 0x83, 0x0d, 0xff, 0x9d, 0xa9, 0x4d, 0x09, 0x9d, 0x75, 0xb4, 0x24, 0x16,
+ 0xaf, 0x00, 0xe7, 0xc6, 0x1a, 0x8f, 0xaf, 0x64, 0x47, 0xa9, 0x50, 0xbf, 0x08, 0xfb, 0x2c, 0xf8,
+ 0x77, 0xff, 0x14, 0x6d, 0x58, 0xe0, 0x74, 0xb3, 0x02, 0x50, 0xa6, 0x0c, 0xaa, 0xb1, 0x0b, 0x2b,
+ 0x1d, 0x15, 0xa0, 0x4d, 0xfc, 0x88, 0xb7, 0x0f, 0x57, 0xf4, 0x92, 0xcc, 0x50, 0x3e, 0x35, 0x09,
+ 0x0a, 0x18, 0xab, 0xcc, 0xf8, 0x72, 0xfd, 0xf7, 0x9f, 0x1b, 0xdd, 0x5d, 0x2b, 0xcb, 0xcd, 0xbd,
+ 0xb7, 0x1d, 0x96, 0xdd, 0xb0, 0xd3, 0xdb, 0x64, 0xbe, 0x33, 0xa8, 0x92, 0x01, 0x0f, 0x2c, 0xe5,
+ 0x85, 0xd2, 0x79, 0x9d, 0x23, 0xfe, 0xf8, 0xda, 0x1d, 0x34, 0xd6, 0x95, 0x7f, 0x93, 0x4d, 0x7e,
+ 0xec, 0x4f, 0x03, 0xfe, 0xc1, 0x9d, 0xc0, 0x54, 0xe0, 0xca, 0xea, 0x95, 0x4d, 0x34, 0x82, 0x8c,
+ 0x94, 0xd7, 0x87, 0xd2, 0x24, 0x5a, 0x1f, 0x00, 0x9e, 0xd8, 0x85, 0xe3, 0xf3, 0xe0, 0x1c, 0xfb,
+ 0x9b, 0xf0, 0x63, 0xb8, 0x64, 0x45, 0x70, 0x32, 0x3d, 0x69, 0x9a, 0xf6, 0x72, 0x59, 0x1a, 0xb0,
+ 0x3a, 0xb5, 0xfb, 0x60, 0x38, 0x05, 0x0e, 0x52, 0x17, 0x3f, 0xfc, 0x09, 0x14, 0xee, 0x18, 0x04,
+ 0xe3, 0x76, 0x13, 0xad, 0x09, 0x5c, 0x2c, 0x2c, 0x5c, 0xed, 0x5d, 0xd6, 0xae, 0xe0, 0xfb, 0x2d,
+ 0x18, 0x47, 0x11, 0xb2, 0x15, 0x74, 0x67, 0x94, 0x05, 0x83, 0x9f, 0xe3, 0xd5, 0x53, 0x55, 0x9d,
+ 0x72, 0xbe, 0xf0, 0x2f, 0x69, 0x48, 0x6f, 0x63, 0xf9, 0x5e, 0xf2, 0xc0, 0xb0, 0xee, 0x6f, 0x66,
+ 0x51, 0x53, 0xbb, 0x4d, 0x28, 0xb6, 0x11, 0x36, 0x16, 0xc8, 0xea, 0xfd, 0x5e, 0xba, 0xda, 0x1e,
+ 0x76, 0x99, 0xd0, 0x65, 0x54, 0xea, 0xc0, 0x72, 0x6e, 0x77, 0xe7, 0xee, 0xdb, 0xd7, 0xfb, 0x9b,
+ 0x4d, 0xda, 0x37, 0x30, 0x6e, 0xf8, 0xc5, 0xef, 0x60, 0x13, 0x0e, 0x18, 0x58, 0x9c, 0x79, 0xda,
+ 0xd0, 0xc2, 0xa3, 0x2c, 0x66, 0xb2, 0x8b, 0xa3, 0x73, 0x3b, 0x35, 0x5a, 0xb1, 0x39, 0x09, 0x26,
+ 0x0d, 0xc0, 0x24, 0x89, 0xaf, 0x00, 0x53, 0xc4, 0xaa, 0x5c, 0x5e, 0xdd, 0x03, 0xb4, 0xf5, 0xfa,
+ 0x91, 0x66, 0xac, 0x1c, 0xad, 0x46, 0x38, 0x0e, 0x80, 0xa8, 0xba, 0x74, 0xf5, 0xf5, 0x60, 0xbf,
+ 0xfe, 0x7f, 0x0d, 0xb7, 0xad, 0x38, 0x3d, 0xb4, 0x23, 0xa3, 0xbc, 0x63, 0xc2, 0x08, 0xde, 0x9a,
+ 0x00, 0x88, 0xbf, 0x83, 0xe6, 0xec, 0xfc, 0x57, 0xf0, 0xff, 0xd5, 0xb9, 0x07, 0x3d, 0x42, 0x4d,
+ 0x82, 0xcb, 0xf9, 0x3d, 0xc8, 0x70, 0xea, 0xb5, 0x50, 0xb3, 0x11, 0x7c, 0x82, 0x3f, 0xfe, 0x57,
+ 0xf0, 0x0e, 0xf3, 0x8a, 0xbd, 0x9f, 0x93, 0xb4, 0x96, 0xe5, 0xf1, 0x97, 0x96, 0x0c, 0xd1, 0x79,
+ 0xdf, 0xf9, 0x6f, 0xc0, 0xd5, 0x54, 0x81, 0xbb, 0x97, 0x5f, 0xfb, 0xb6, 0x2e, 0x15, 0xb1, 0x7c,
+ 0x5b, 0x8b, 0x4b, 0xa3, 0x9a, 0x30, 0xf5, 0x82, 0x1a, 0x7d, 0x1c, 0x16, 0x6c, 0x08, 0xf2, 0x5c,
+ 0x17, 0x52, 0xbe, 0xff, 0x52, 0x3e, 0xf7, 0xbb, 0x25, 0x80, 0x5c, 0x46, 0x89, 0xe5, 0xc7, 0x62,
+ 0x74, 0xea, 0xdc, 0xa0, 0xda, 0xa0, 0x3f, 0x08, 0xdf, 0xcf, 0xaf, 0x9b, 0xdf, 0x78, 0x91, 0x6b,
+ 0x7c, 0x00, 0x77, 0x74, 0xb0, 0x3e, 0x0c, 0xd4, 0x6c, 0xaf, 0xdd, 0xed, 0xc7, 0x71, 0xa7, 0x16,
+ 0x3f, 0x33, 0x8f, 0x5a, 0xc7, 0xbd, 0x47, 0x76, 0x07, 0x24, 0x11, 0xd7, 0xa6, 0x9a, 0x56, 0x69,
+ 0x3b, 0x12, 0xb0, 0xe0, 0xd0, 0x12, 0x23, 0xc4, 0x8c, 0x32, 0xc4, 0x3a, 0x00, 0xba, 0x6e, 0xc3,
+ 0x89, 0x7c, 0x96, 0x48, 0x0a, 0x08, 0x24, 0x30, 0x8d, 0x2c, 0x0b, 0x56, 0xe6, 0xd5, 0x55, 0x39,
+ 0x5e, 0xf5, 0xed, 0x3c, 0xc0, 0x5b, 0x59, 0x0b, 0xe9, 0xbe, 0x2e, 0xb9, 0xb5, 0x7e, 0xff, 0xbd,
+ 0x6f, 0x80, 0x1e, 0xc4, 0xe4, 0x1b, 0xaf, 0xfc, 0x55, 0x1f, 0x19, 0x7d, 0x4c, 0x4f, 0xcc, 0xbc,
+ 0xee, 0xb2, 0x67, 0x02, 0xe9, 0x2f, 0x1b, 0xe4, 0xfa, 0x1b, 0xc5, 0xfc, 0x9a, 0x2e, 0x41, 0x82,
+ 0xc6, 0xfe, 0x01, 0x8f, 0x4b, 0x1b, 0x79, 0x1b, 0x2b, 0x85, 0xe9, 0x5f, 0x92, 0xe1, 0xba, 0x97,
+ 0xae, 0x9b, 0x68, 0x7c, 0xd2, 0x4c, 0x8d, 0xdc, 0xb2, 0xc0, 0x46, 0xd2, 0xe1, 0x5e, 0x6b, 0xf3,
+ 0x79, 0x7a, 0xf3, 0xcb, 0x3c, 0x5d, 0x23, 0xb0, 0x93, 0x47, 0x39, 0xfd, 0x4e, 0x1a, 0xe5, 0x95,
+ 0xc1, 0x47, 0x5f, 0xf9, 0xed, 0x0b, 0xdc, 0xcc, 0x75, 0x2a, 0x6a, 0x06, 0x00, 0x91, 0x19, 0x8c,
+ 0x56, 0xfd, 0x00, 0x93, 0x18, 0xfc, 0xd2, 0x30, 0xbd, 0xa2, 0xa2, 0xa6, 0xd8, 0x96, 0x78, 0xf1,
+ 0x8e, 0x7c, 0x46, 0xc8, 0x79, 0xf8, 0xda, 0xcb, 0x3b, 0x02, 0x6d, 0x5e, 0x01, 0x32, 0xf4, 0x86,
+ 0x7f, 0xe6, 0x7c, 0xfd, 0xcf, 0x08, 0x0f, 0x09, 0x6f, 0x03, 0xfa, 0x11, 0x96, 0x7b, 0x73, 0x75,
+ 0x90, 0xdc, 0xfe, 0x5e, 0x62, 0x61, 0x67, 0x1b, 0xc8, 0x8c, 0xb9, 0x32, 0x98, 0x4d, 0x9a, 0xd4,
+ 0xa0, 0x39, 0x5b, 0xd6, 0x0b, 0x56, 0x56, 0xcf, 0x55, 0x43, 0x2f, 0x6f, 0xb8, 0xf6, 0x83, 0xff,
+ 0xe7, 0x62, 0x7b, 0x73, 0xf9, 0x4e, 0xea, 0xec, 0x3e, 0x1e, 0xa6, 0xbf, 0xbf, 0x87, 0xdb, 0x1a,
+ 0xdb, 0xca, 0xb4, 0xc7, 0xa5, 0x30, 0x2b, 0xcd, 0x79, 0xef, 0x9b, 0x58, 0xdc, 0x30, 0xf8, 0x70,
+ 0x8e, 0x2f, 0x42, 0xde, 0x83, 0x44, 0x25, 0xf7, 0xdd, 0x55, 0x3e, 0x12, 0x55, 0x4e, 0x15, 0x5f,
+ 0x37, 0x91, 0xe9, 0xe3, 0x1f, 0x20, 0xda, 0x51, 0xcb, 0xff, 0xfd, 0x6d, 0x72, 0xfc, 0x3f, 0x5b,
+ 0x0f, 0xc7, 0x70, 0xcd, 0x84, 0xd9, 0x8e, 0x36, 0x92, 0x1d, 0x4a, 0x61, 0x70, 0x9b, 0x9b, 0x68,
+ 0x9b, 0x27, 0xc6, 0x99, 0x10, 0xa3, 0xce, 0x53, 0x21, 0xf4, 0x31, 0x3c, 0x87, 0x84, 0x69, 0x81,
+ 0x9d, 0xa5, 0xef, 0x0f, 0xf1, 0xca, 0xae, 0xf0, 0x63, 0x1c, 0x84, 0x5b, 0x8f, 0x77, 0xe5, 0x6b,
+ 0x11, 0xec, 0x26, 0x59, 0x9f, 0x16, 0x89, 0xe1, 0xc2, 0xad, 0x56, 0xb8, 0x2e, 0x31, 0x68, 0x5d,
+ 0x2a, 0x83, 0xf6, 0xef, 0xfe, 0x61, 0x76, 0x9d, 0x60, 0x2a, 0x87, 0xc5, 0x85, 0xff, 0x22, 0xe4,
+ 0x4b, 0x08, 0x48, 0x13, 0x8a, 0x00, 0x3b, 0x48, 0xc9, 0x21, 0x06, 0xc1, 0xbb, 0xd9, 0xd1, 0x3d,
+ 0x52, 0x49, 0x6a, 0x44, 0x93, 0x09, 0xc8, 0x8b, 0x8a, 0x5e, 0x7e, 0x8d, 0x0b, 0x26, 0xc3, 0x59,
+ 0xbb, 0xad, 0x92, 0xaa, 0x46, 0x0b, 0xbe, 0xd6, 0xaa, 0xa0, 0x36, 0x5f, 0x34, 0x6a, 0x88, 0x84,
+ 0x0a, 0xfc, 0xa8, 0xb8, 0xbd, 0xb4, 0xa4, 0xf4, 0xc6, 0xe1, 0x88, 0x55, 0x5d, 0x4e, 0xc9, 0xdc,
+ 0x7d, 0xa2, 0x71, 0x0d, 0x18, 0x1e, 0x16, 0x1d, 0x17, 0x11, 0xb3, 0x91, 0x92, 0xf0, 0xc6, 0x1b,
+ 0x3a, 0x54, 0x80, 0x8f, 0x11, 0x71, 0x9b, 0x02, 0x16, 0xf4, 0x8f, 0xf0, 0x37, 0xf2, 0xea, 0xa8,
+ 0x95, 0x61, 0x8e, 0x8f, 0x22, 0x22, 0xc0, 0xef, 0x51, 0x0b, 0x18, 0x8d, 0xd8, 0xe8, 0x0b, 0x76,
+ 0x3e, 0xa5, 0x28, 0xc3, 0x6f, 0xde, 0xf1, 0xf4, 0x55, 0x7d, 0x48, 0xfd, 0xe3, 0xa5, 0x64, 0x45,
+ 0x70, 0x3c, 0xbe, 0x0f, 0x06, 0x22, 0xc8, 0x95, 0x89, 0x0a, 0x56, 0xd6, 0x8a, 0x36, 0x42, 0xbe,
+ 0xe6, 0x20, 0x00, 0x5c, 0xaa, 0xc6, 0x2e, 0xea, 0x19, 0x11, 0xfc, 0x07, 0x38, 0x08, 0x30, 0x7f,
+ 0xb1, 0xe7, 0xfd, 0x71, 0x1c, 0x37, 0xc1, 0xd1, 0x4c, 0x3f, 0x16, 0x4c, 0x4d, 0x06, 0x69, 0xca,
+ 0x3b, 0x8b, 0x79, 0xfd, 0x05, 0x0c, 0x8c, 0x60, 0xee, 0xaa, 0x91, 0x16, 0xf1, 0xab, 0x8a, 0x55,
+ 0xf1, 0xb2, 0x85, 0xfc, 0xa7, 0xde, 0x6f, 0x32, 0xd3, 0x1f, 0xfd, 0xc2, 0x0d, 0xc7, 0x74, 0x4d,
+ 0xcb, 0xae, 0x77, 0x96, 0xd3, 0xf3, 0x0a, 0xa0, 0x97, 0xd1, 0xf5, 0x54, 0xb8, 0xba, 0x45, 0x63,
+ 0x1f, 0xe4, 0xef, 0x80, 0x63, 0xd4, 0xef, 0xef, 0x74, 0x56, 0x93, 0xf3, 0xfe, 0x60, 0x97, 0xcb,
+ 0xf5, 0x55, 0x89, 0x0b, 0x92, 0x4e, 0xb5, 0x22, 0xe3, 0x0e, 0xc4, 0x5e, 0xc9, 0x0b, 0xc8, 0x52,
+ 0xc1, 0x43, 0x0a, 0x6e, 0x6e, 0xee, 0xe9, 0xd2, 0x58, 0xe1, 0x08, 0xd5, 0x93, 0xdd, 0x96, 0x57,
+ 0x8b, 0x06, 0x2f, 0xb4, 0x3b, 0x0a, 0x00, 0x5f, 0x9d, 0x55, 0x14, 0x57, 0xfe, 0xee, 0xbe, 0x19,
+ 0x61, 0xa5, 0x63, 0x81, 0x6a, 0xf0, 0x1e, 0xf8, 0xdc, 0xa0, 0xf4, 0x98, 0xaa, 0x0b, 0x40, 0xfa,
+ 0xea, 0xb1, 0xb7, 0xce, 0xb7, 0x80, 0x3b, 0x56, 0x09, 0xb6, 0xa5, 0x92, 0x84, 0x0b, 0x01, 0xca,
+ 0x51, 0x86, 0xad, 0xd5, 0x1a, 0xc5, 0x9f, 0xba, 0x2b, 0xc5, 0x30, 0x66, 0xd2, 0xbc, 0xa5, 0xb1,
+ 0xcd, 0x3a, 0x73, 0x29, 0x49, 0x47, 0x58, 0xe3, 0xb7, 0x55, 0xeb, 0x15, 0x7f, 0x0d, 0xf8, 0x12,
+ 0x55, 0x02, 0x92, 0x3a, 0xe7, 0x60, 0xdf, 0xfa, 0x3a, 0x3a, 0x01, 0x35, 0xf0, 0x06, 0xe5, 0x85,
+ 0xdd, 0x21, 0xef, 0xe7, 0x84, 0xda, 0x08, 0x22, 0xa2, 0xab, 0x83, 0x92, 0x25, 0x15, 0x8b, 0x00,
+ 0x4f, 0x6a, 0xc9, 0x01, 0xa4, 0xc1, 0x62, 0xf6, 0x07, 0x24, 0x19, 0xbb, 0x5d, 0xe0, 0x36, 0x69,
+ 0xf5, 0x6a, 0xef, 0x22, 0x73, 0xc7, 0xb6, 0xc2, 0x03, 0xc9, 0x53, 0x9f, 0x4d, 0xd5, 0x1e, 0x03,
+ 0x00, 0xd9, 0xa4, 0x44, 0x44, 0x45, 0x15, 0x2e, 0xdb, 0x91, 0x09, 0xf0, 0xd8, 0x30, 0x0b, 0x08,
+ 0x29, 0x55, 0x1e, 0xd2, 0x58, 0xa1, 0xed, 0xda, 0xe0, 0x64, 0xec, 0x83, 0x2b, 0x5b, 0x30, 0x7a,
+ 0x90, 0xb0, 0x5f, 0x1a, 0x55, 0x38, 0xa6, 0x5d, 0x6f, 0xaa, 0x4e, 0x03, 0x6e, 0x00, 0x0b, 0xc6,
+ 0x35, 0x5d, 0x37, 0x23, 0xea, 0xa9, 0x81, 0xa2, 0x52, 0x0e, 0x9c, 0xd5, 0x7e, 0xaa, 0x98, 0x05,
+ 0x5c, 0x0c, 0xf3, 0x41, 0x07, 0x3e, 0x81, 0x6b, 0xf1, 0x7f, 0x50, 0xef, 0x9b, 0x8f, 0xc2, 0xf0,
+ 0x97, 0xaf, 0xbf, 0x00, 0x52, 0x02, 0x57, 0x59, 0xfc, 0x75, 0x0c, 0x90, 0x1a, 0x47, 0x17, 0x0e,
+ 0xf0, 0x0d, 0x3f, 0x6e, 0x97, 0x80, 0x99, 0x60, 0x37, 0x6a, 0xcc, 0xe9, 0xd9, 0x11, 0x09, 0xc4,
+ 0x09, 0x60, 0x00, 0x25, 0x06, 0x2f, 0xb6, 0x8e, 0xaf, 0x68, 0xa9, 0x29, 0xab, 0xa9, 0xaa, 0xa7,
+ 0x45, 0xcb, 0x0c, 0xe4, 0x85, 0xbc, 0x27, 0xd5, 0xa6, 0x00, 0x72, 0xa5, 0xc0, 0x72, 0xf1, 0xef,
+ 0x71, 0x42, 0x0c, 0x1b, 0x02, 0xdb, 0x44, 0x40, 0x0b, 0xde, 0x15, 0x7c, 0x43, 0xdf, 0xe2, 0x52,
+ 0x0b, 0x2c, 0x9f, 0xf5, 0x24, 0xab, 0xc4, 0x69, 0xaa, 0xa2, 0xe0, 0x39, 0xe0, 0x2e, 0x11, 0x2e,
+ 0x11, 0x39, 0x0f, 0x38, 0x5e, 0x6f, 0x2a, 0x70, 0xa3, 0x5e, 0x9c, 0xdc, 0xe8, 0xd5, 0x63, 0x6b,
+ 0x70, 0x05, 0xf0, 0x27, 0xbd, 0x70, 0x0d, 0x4b, 0xf5, 0x54, 0xe0, 0x79, 0x11, 0x4a, 0x16, 0xb9,
+ 0x03, 0x2f, 0x58, 0xf5, 0x39, 0xbc, 0xa9, 0xc9, 0xff, 0xc5, 0x94, 0x6a, 0xa8, 0x51, 0x05, 0x0b,
+ 0x82, 0xfe, 0xa0, 0xd7, 0xd5, 0xc4, 0xae, 0xb7, 0x45, 0xfc, 0x4a, 0x2f, 0x07, 0x72, 0x87, 0x70,
+ 0x1c, 0x88, 0x97, 0x8d, 0x59, 0x30, 0x3d, 0xfa, 0x80, 0xd3, 0xd8, 0x09, 0xaa, 0x8f, 0xbc, 0x03,
+ 0xfc, 0x0a, 0xaf, 0x00, 0x70, 0x16, 0xa4, 0xec, 0xaa, 0xa3, 0xe3, 0x76, 0xd2, 0x85, 0x11, 0xef,
+ 0x91, 0x91, 0x1c, 0xc0, 0x67, 0xbc, 0x50, 0xf8, 0x67, 0xbc, 0x32, 0x78, 0xf5, 0xde, 0xed, 0x27,
+ 0x67, 0x01, 0x12, 0xf0, 0x46, 0x7d, 0x49, 0xe3, 0x75, 0xfc, 0x3a, 0x54, 0xe2, 0xf0, 0xe6, 0x71,
+ 0xbf, 0x55, 0x14, 0xaa, 0x28, 0xe0, 0xec, 0x65, 0x5e, 0x7f, 0x16, 0x44, 0x97, 0x02, 0x92, 0x13,
+ 0x34, 0x9f, 0x4b, 0xc4, 0xd3, 0x78, 0xe5, 0x6b, 0x99, 0x29, 0xa3, 0xa4, 0xad, 0xd1, 0xe5, 0x39,
+ 0xc9, 0x07, 0x00, 0x24, 0x65, 0x03, 0x6b, 0x27, 0xb7, 0xb1, 0x48, 0xbf, 0x56, 0x0e, 0xe6, 0xa3,
+ 0xb9, 0x46, 0x42, 0x18, 0xe8, 0xfa, 0x07, 0x80, 0x87, 0xee, 0xc8, 0x88, 0xc0, 0x21, 0x89, 0x8f,
+ 0x58, 0xe9, 0x08, 0xb4, 0x6b, 0xbc, 0x79, 0xac, 0x56, 0x5f, 0xa6, 0x4b, 0x89, 0x6f, 0x88, 0xe2,
+ 0xc0, 0x69, 0x93, 0x51, 0x1f, 0x63, 0xda, 0xaa, 0xe7, 0x8b, 0xfe, 0xf4, 0xf6, 0x92, 0x34, 0xb5,
+ 0x55, 0x0a, 0x41, 0x5d, 0x8c, 0x48, 0x2d, 0x22, 0x64, 0x44, 0xf0, 0x22, 0xc0, 0x77, 0x44, 0x67,
+ 0xb4, 0xc4, 0x2b, 0x97, 0x85, 0xe0, 0x4b, 0xe1, 0x77, 0x0e, 0x83, 0x04, 0x74, 0xe8, 0x6d, 0x4c,
+ 0xf0, 0xcb, 0x84, 0xe9, 0x60, 0x4b, 0x21, 0x6a, 0x73, 0xa6, 0x49, 0x1d, 0x2c, 0x22, 0x72, 0xae,
+ 0xd7, 0xb8, 0xc5, 0xf8, 0x22, 0x00, 0x76, 0xf2, 0x85, 0x7c, 0x8e, 0x30, 0x92, 0x1f, 0x02, 0xe1,
+ 0x12, 0x83, 0xc5, 0x80, 0xc1, 0xc4, 0x0d, 0x53, 0x5b, 0xd8, 0xe8, 0x95, 0x4d, 0x24, 0x81, 0xc0,
+ 0x2a, 0x34, 0x24, 0x6a, 0x47, 0x7f, 0xf3, 0x8c, 0x15, 0x6d, 0xda, 0xf8, 0x1d, 0xe1, 0x6d, 0x1c,
+ 0x00, 0xb8, 0x4c, 0x74, 0xfa, 0xd1, 0xaa, 0x35, 0xce, 0xba, 0x51, 0xa8, 0xc3, 0x87, 0x22, 0x10,
+ 0x21, 0xf2, 0xbc, 0xbc, 0xa6, 0x8d, 0x6f, 0x6d, 0x74, 0x66, 0xb8, 0x64, 0xe6, 0x7f, 0xe3, 0x50,
+ 0xef, 0x59, 0x02, 0x31, 0xeb, 0x0c, 0x69, 0x2a, 0x5a, 0xe3, 0x73, 0xe4, 0x8d, 0xfe, 0xcd, 0xab,
+ 0x00, 0x4b, 0x46, 0x06, 0x0d, 0xbf, 0x57, 0xb2, 0xe2, 0x4d, 0x69, 0xb0, 0xda, 0x69, 0x22, 0x17,
+ 0xde, 0x65, 0xdf, 0xe4, 0x3b, 0x98, 0x18, 0x6b, 0xda, 0xd3, 0x25, 0xbd, 0x36, 0x1c, 0xa5, 0x56,
+ 0x8e, 0x2c, 0x60, 0x17, 0x38, 0x70, 0x3b, 0xf6, 0x64, 0x44, 0x5e, 0x34, 0xd8, 0xe3, 0x6d, 0x74,
+ 0xd8, 0xcd, 0xe1, 0x16, 0x31, 0xc2, 0x5c, 0x2d, 0xb6, 0x34, 0xb7, 0x95, 0x6e, 0x8e, 0x2e, 0x31,
+ 0x02, 0xac, 0x20, 0x9e, 0x05, 0x45, 0x86, 0x01, 0x10, 0x54, 0xe3, 0x91, 0xad, 0xf0, 0x9e, 0x3d,
+ 0x96, 0xda, 0x7d, 0xe1, 0x25, 0x06, 0x45, 0x00, 0x48, 0xe4, 0xcd, 0xe0, 0xec, 0x06, 0x4e, 0x2d,
+ 0x92, 0x74, 0xa1, 0x26, 0x5e, 0xe9, 0x26, 0x8a, 0x30, 0x21, 0x34, 0x47, 0x44, 0x67, 0xea, 0xd6,
+ 0x59, 0xa4, 0x39, 0xb5, 0x87, 0x22, 0x3f, 0x63, 0x52, 0xe3, 0xda, 0xbc, 0x80, 0x01, 0x45, 0x17,
+ 0xdd, 0x32, 0xcd, 0x89, 0x8c, 0x22, 0xc2, 0xc8, 0x16, 0xa8, 0x44, 0x61, 0x18, 0x56, 0x15, 0x99,
+ 0x66, 0x46, 0x64, 0x61, 0x18, 0x56, 0x22, 0xd5, 0xce, 0x8c, 0xe7, 0x0a, 0xcc, 0x8e, 0xba, 0xf2,
+ 0x2d, 0x91, 0xd7, 0xd6, 0x37, 0xc7, 0xbb, 0xe1, 0xc9, 0x3d, 0xf1, 0xbf, 0x93, 0x8f, 0x28, 0xdb,
+ 0xf4, 0x28, 0x32, 0x0e, 0xa2, 0xb3, 0x35, 0x5f, 0x02, 0x4e, 0xda, 0xb0, 0xf7, 0xe8, 0xcb, 0x50,
+ 0x9a, 0xf6, 0xe7, 0x1a, 0xe3, 0x80, 0x4f, 0x29, 0xb5, 0x04, 0xfd, 0x8a, 0x95, 0x8c, 0x09, 0xa4,
+ 0x0e, 0x58, 0x13, 0x47, 0xa8, 0x13, 0x34, 0xec, 0xf6, 0x7f, 0x2b, 0x30, 0xf2, 0xe2, 0xca, 0xcd,
+ 0x44, 0xff, 0x75, 0xeb, 0xfd, 0xa7, 0x8f, 0x6e, 0x6f, 0xf4, 0x6e, 0x7c, 0x0f, 0x75, 0x5b, 0x9f,
+ 0x97, 0x5d, 0xc6, 0x38, 0xaa, 0xe3, 0x2d, 0x5a, 0x22, 0x8f, 0xcc, 0xb0, 0x82, 0xcc, 0xa6, 0xbd,
+ 0x00, 0xe6, 0xcf, 0x2a, 0x50, 0xd0, 0x0e, 0xca, 0x4d, 0xb8, 0x27, 0xec, 0x86, 0x8c, 0xe4, 0xaa,
+ 0xc1, 0xec, 0xd9, 0x7e, 0x87, 0x4d, 0x51, 0xa3, 0x1d, 0x94, 0x88, 0xf0, 0x30, 0xac, 0x20, 0xfb,
+ 0xbe, 0x76, 0xf2, 0xbb, 0x1f, 0xca, 0x0e, 0x83, 0x13, 0x78, 0x6c, 0xf0, 0x97, 0x4a, 0x62, 0x53,
+ 0xd0, 0x21, 0xa5, 0xc8, 0x5f, 0x3b, 0xe0, 0x1a, 0x17, 0xdf, 0x9b, 0x01, 0x68, 0x1b, 0x6a, 0xcf,
+ 0xa6, 0x41, 0xe3, 0x46, 0x70, 0x1c, 0xfb, 0x3c, 0xb0, 0x1c, 0x3b, 0xe5, 0x7c, 0xf4, 0x21, 0x77,
+ 0x62, 0x2c, 0x2a, 0x5d, 0xee, 0xd2, 0xec, 0x70, 0x88, 0x57, 0x11, 0xc8, 0x42, 0xf8, 0x67, 0x8e,
+ 0xc8, 0x8c, 0xd4, 0x1e, 0xce, 0x0d, 0xdb, 0x03, 0xf4, 0x73, 0x43, 0x05, 0xbf, 0xad, 0xa1, 0x4c,
+ 0x6e, 0xa4, 0x55, 0x00, 0x0b, 0x5d, 0x07, 0xbc, 0x19, 0x6f, 0x3d, 0x4f, 0x80, 0xe4, 0x53, 0x7f,
+ 0xdf, 0xd5, 0xc2, 0x0f, 0xc5, 0xde, 0xfa, 0x78, 0xf5, 0xd6, 0xfb, 0xda, 0xaa, 0xba, 0xae, 0xfe,
+ 0xf3, 0xce, 0x8a, 0xa4, 0x41, 0x0b, 0xe3, 0xc7, 0x01, 0x1b, 0x35, 0xdb, 0x83, 0xfc, 0x91, 0x4d,
+ 0xf2, 0xe7, 0x76, 0x0f, 0xc0, 0xaf, 0x68, 0xe1, 0x81, 0x18, 0xb3, 0xf0, 0x02, 0x8d, 0xcd, 0x36,
+ 0x01, 0x4a, 0x94, 0xe2, 0x7e, 0xaa, 0xc2, 0x91, 0x44, 0xa5, 0xd5, 0x50, 0x45, 0x87, 0xf5, 0xe4,
+ 0x3b, 0xc0, 0xd9, 0x81, 0x1b, 0x24, 0x29, 0x98, 0xd4, 0x9e, 0x7f, 0xe7, 0xea, 0xa9, 0x83, 0xab,
+ 0xf7, 0xb4, 0x88, 0x98, 0x87, 0x9c, 0xf6, 0xb7, 0x35, 0xf8, 0xd8, 0x35, 0x4b, 0xfb, 0xde, 0xd1,
+ 0x81, 0xc6, 0x6e, 0x0e, 0x9c, 0x76, 0x8e, 0x03, 0x95, 0x27, 0x74, 0x10, 0xc2, 0x9f, 0x82, 0x8f,
+ 0x4d, 0x75, 0x78, 0xf3, 0x91, 0xeb, 0x8e, 0x1d, 0x91, 0xfd, 0x80, 0x80, 0x39, 0xc9, 0xb1, 0x07,
+ 0xbe, 0x03, 0x63, 0x65, 0x58, 0x5f, 0x74, 0x2e, 0x4d, 0x35, 0xe6, 0xb4, 0x55, 0x5c, 0x62, 0xe7,
+ 0x3e, 0x71, 0x55, 0x5a, 0x03, 0xe7, 0x6d, 0xf3, 0x6b, 0xd9, 0x0e, 0x56, 0x88, 0xe6, 0x35, 0x50,
+ 0x09, 0x52, 0xdf, 0x41, 0xad, 0xbb, 0xad, 0x9f, 0xf4, 0xc1, 0x07, 0xfa, 0x84, 0x0f, 0x9e, 0x5e,
+ 0xa0, 0xe3, 0x3c, 0xa5, 0x6e, 0x02, 0x6f, 0x11, 0xc1, 0x35, 0xc8, 0xc1, 0xce, 0xe2, 0x5f, 0x3c,
+ 0x13, 0x58, 0xac, 0xa9, 0xc5, 0xf9, 0xc3, 0xb4, 0x8e, 0xcf, 0x71, 0xf4, 0x38, 0x0e, 0xeb, 0x1e,
+ 0xe8, 0x21, 0x39, 0xad, 0x9a, 0xe5, 0x36, 0x68, 0x9d, 0xe0, 0xac, 0x76, 0x1c, 0x3b, 0xa5, 0x8d,
+ 0xfe, 0xb8, 0x84, 0xf7, 0xf6, 0xd2, 0xc3, 0x89, 0x0c, 0xb2, 0x1c, 0xcb, 0x9a, 0x40, 0x83, 0x98,
+ 0x97, 0xe4, 0xfa, 0xdb, 0x77, 0x39, 0x17, 0x69, 0xc1, 0x9d, 0x4d, 0xaa, 0x54, 0x7f, 0xff, 0xd5,
+ 0xe9, 0x4a, 0x1c, 0x92, 0x84, 0x4d, 0x41, 0x0b, 0xb3, 0xc7, 0x19, 0x6f, 0xa5, 0x92, 0xe3, 0x46,
+ 0x15, 0x8a, 0x6c, 0xdd, 0x66, 0x08, 0xbc, 0x68, 0xa7, 0x80, 0xea, 0xf3, 0xec, 0x70, 0x9c, 0x8f,
+ 0x6f, 0x89, 0x5f, 0x05, 0x42, 0xd2, 0xfb, 0xfb, 0x0b, 0x3b, 0xf3, 0x3b, 0xb2, 0xdc, 0x8f, 0xb1,
+ 0x6e, 0x1f, 0xe8, 0x89, 0xef, 0xc2, 0xfe, 0x02, 0x85, 0x3e, 0x72, 0x4b, 0x21, 0x34, 0x01, 0xce,
+ 0x63, 0xc7, 0x04, 0x6d, 0x33, 0xbc, 0x7c, 0xa7, 0x55, 0x7a, 0x0f, 0x0f, 0x45, 0x04, 0xf3, 0xa5,
+ 0xe5, 0xc0, 0xfb, 0x2e, 0xb1, 0xd9, 0x73, 0x1f, 0x7f, 0x96, 0x40, 0xe3, 0xc0, 0x76, 0xf6, 0xaf,
+ 0x2b, 0x2b, 0x0a, 0x7b, 0x7f, 0xde, 0x05, 0xbd, 0xbf, 0x7e, 0x17, 0x23, 0x25, 0x2e, 0x62, 0x5b,
+ 0xf0, 0x27, 0x55, 0x4e, 0xc5, 0x7d, 0x25, 0xf2, 0x9a, 0x3a, 0xe7, 0x14, 0xe3, 0x80, 0xea, 0x31,
+ 0x0b, 0x80, 0x8b, 0xc0, 0x05, 0x5d, 0xdd, 0x1e, 0xe3, 0x93, 0x6b, 0xcb, 0x79, 0x7b, 0x3f, 0xb5,
+ 0x06, 0x52, 0x2b, 0xe6, 0x3a, 0xaa, 0xf1, 0xaf, 0x1d, 0x96, 0x6b, 0x0e, 0x52, 0x04, 0xd7, 0x7e,
+ 0x69, 0xf7, 0x2b, 0x58, 0x69, 0xb6, 0xf5, 0x50, 0xbc, 0x7a, 0x85, 0x79, 0x42, 0x9c, 0x95, 0x5e,
+ 0x60, 0x5c, 0x72, 0x1b, 0xe4, 0xaa, 0xb6, 0xf1, 0xe6, 0x77, 0xec, 0xb4, 0x5f, 0x6c, 0xd1, 0xe9,
+ 0x28, 0xb0, 0x25, 0x40, 0xc2, 0x5e, 0xbe, 0x73, 0x06, 0xcb, 0xd2, 0x3c, 0xd0, 0x71, 0x75, 0x20,
+ 0xb9, 0xaa, 0x90, 0x1d, 0xc8, 0x88, 0xe0, 0x4a, 0xf0, 0x48, 0x07, 0x8a, 0x1c, 0xcc, 0x41, 0x92,
+ 0x27, 0xd9, 0xa9, 0xd0, 0x2f, 0x78, 0x64, 0x6d, 0x79, 0x5f, 0x06, 0xbf, 0xa1, 0xf6, 0xe3, 0xc1,
+ 0xf7, 0xd6, 0xb8, 0x69, 0xac, 0x1e, 0xdf, 0x9f, 0x17, 0x00, 0xd1, 0xb9, 0x63, 0xaf, 0x46, 0x7f,
+ 0x2e, 0x44, 0x7e, 0x01, 0xf6, 0x96, 0x34, 0x75, 0xdd, 0x01, 0xf7, 0xc0, 0x2f, 0x80, 0x15, 0x14,
+ 0x1c, 0xe4, 0x32, 0x8e, 0x01, 0xce, 0x20, 0xc7, 0x5f, 0x22, 0x3e, 0x02, 0xd9, 0x6f, 0x01, 0x6c,
+ 0x18, 0x4f, 0x5a, 0xfe, 0x6d, 0x55, 0xa1, 0xce, 0xc3, 0x82, 0x48, 0x31, 0xe4, 0x44, 0xe0, 0x28,
+ 0x3c, 0x19, 0xc0, 0x39, 0x91, 0x83, 0xc0, 0xe5, 0x81, 0x77, 0xa8, 0x1f, 0xf6, 0xea, 0x2f, 0xb4,
+ 0xd1, 0xc6, 0x38, 0x9c, 0x1c, 0x07, 0x88, 0x83, 0x07, 0x4c, 0xc6, 0x9e, 0xe3, 0x5e, 0x08, 0xb1,
+ 0x98, 0xf8, 0x3e, 0xaa, 0xc9, 0x6e, 0xc3, 0x9e, 0x1c, 0x61, 0x99, 0x11, 0xdc, 0x01, 0x1c, 0x07,
+ 0xf6, 0x97, 0x18, 0xb5, 0x13, 0xa2, 0xe9, 0x58, 0xef, 0xfb, 0xe2, 0xe5, 0x97, 0xff, 0xea, 0xa9,
+ 0x34, 0xca, 0xcc, 0x2f, 0x7f, 0xb1, 0x1c, 0xe0, 0x05, 0x70, 0x64, 0x44, 0xf0, 0x0c, 0xe0, 0x19,
+ 0xc0, 0x63, 0x2a, 0x10, 0x9c, 0x44, 0xdc, 0x6b, 0xaa, 0x57, 0xbc, 0xef, 0x78, 0x00, 0x39, 0xc4,
+ 0xc7, 0x5e, 0x8a, 0x81, 0x8c, 0x88, 0xde, 0x00, 0x8c, 0x06, 0xbe, 0xc3, 0xc9, 0xae, 0x51, 0x60,
+ 0xd3, 0x8a, 0x78, 0xc0, 0x0e, 0x25, 0xff, 0xfd, 0xdb, 0x8f, 0x09, 0xd7, 0x52, 0xac, 0x4d, 0xd5,
+ 0x5c, 0xa9, 0xe3, 0xad, 0xc1, 0x80, 0x60, 0x39, 0xc3, 0x87, 0x70, 0xe1, 0x52, 0x38, 0x15, 0xc0,
+ 0x70, 0xe2, 0x1c, 0x38, 0x87, 0x0e, 0x05, 0x23, 0x03, 0x9c, 0x38, 0x76, 0x0e, 0x1c, 0x23, 0x87,
+ 0x9c, 0x05, 0x76, 0x03, 0x1c, 0x38, 0x87, 0x0e, 0x05, 0x23, 0x03, 0x9c, 0x38, 0x76, 0x0e, 0x1c,
+ 0x23, 0x87, 0x9c, 0x05, 0x76, 0x03, 0x1c, 0x38, 0x87, 0x0e, 0x05, 0x23, 0x03, 0x9c, 0x38, 0x76,
+ 0x0e, 0x1c, 0x23, 0x87, 0x9c, 0x05, 0x76, 0x03, 0x1c, 0x38, 0x87, 0x0e, 0x05, 0x23, 0x03, 0x9c,
+ 0x38, 0x76, 0x0e, 0x1c, 0x23, 0x87, 0x9c, 0x05, 0x76, 0x03, 0x1c, 0x38, 0x87, 0x0e, 0x05, 0x23,
+ 0x03, 0x9c, 0x38, 0x76, 0x0e, 0x1c, 0x23, 0x87, 0x9c, 0x05, 0x76, 0x03, 0x1c, 0x38, 0x87, 0x0e,
+ 0x05, 0x23, 0x03, 0x9c, 0x38, 0x76, 0x0e, 0x1c, 0x23, 0x87, 0x9c, 0x05, 0x76, 0x03, 0x1c, 0x38,
+ 0x87, 0x0e, 0x05, 0x23, 0x0f, 0xfe, 0xf6, 0xa7, 0xbf, 0x78, 0xfb, 0x2d, 0xfb, 0xc5, 0x00, 0x00,
+ 0x00, 0x00, 0x45, 0x49, 0x44, 0x4e, 0x42, 0xae, 0x82, 0x60,
+ ],
+ disp: function()
+ {
+ // Do Nothing
+
+ throw "Does Nothing!";
+ }
+
+};
+
+try
+{
+ LOGO.disp();
+}
+catch(e)
+{
+ alert("Error: " + e + "\n");
+}
+
diff --git a/jetty-servlets/src/test/resources/big_script.js.sha1 b/jetty-servlets/src/test/resources/big_script.js.sha1
new file mode 100644
index 00000000000..5ac71c8b8b3
--- /dev/null
+++ b/jetty-servlets/src/test/resources/big_script.js.sha1
@@ -0,0 +1 @@
+77634b336741a98d2ef79484281245b12e9db939 big_script.js
diff --git a/jetty-servlets/src/test/resources/small_script.js b/jetty-servlets/src/test/resources/small_script.js
new file mode 100644
index 00000000000..207de2be410
--- /dev/null
+++ b/jetty-servlets/src/test/resources/small_script.js
@@ -0,0 +1,29 @@
+//----------------------------------------------------------------------
+//
+// Silly / Pointless Javascript to test GZIP compression.
+//
+//----------------------------------------------------------------------
+
+var LOGO = {
+ dat: [
+ 0x50, 0x89, 0x47, 0x4e, 0x0a, 0x0d, 0x0a, 0x1a, 0x00, 0x00, 0x0d, 0x00, 0x48, 0x49, 0x52, 0x44,
+ 0x00, 0x00, 0x45, 0x49, 0x44, 0x4e, 0x42, 0xae, 0x82, 0x60,
+ ],
+ disp: function()
+ {
+ // Do Nothing
+
+ throw "Does Nothing!";
+ }
+
+};
+
+try
+{
+ LOGO.disp();
+}
+catch(e)
+{
+ alert("Error: " + e + "\n");
+}
+
diff --git a/jetty-servlets/src/test/resources/small_script.js.sha1 b/jetty-servlets/src/test/resources/small_script.js.sha1
new file mode 100644
index 00000000000..ca4c476094a
--- /dev/null
+++ b/jetty-servlets/src/test/resources/small_script.js.sha1
@@ -0,0 +1 @@
+b8455ea37194b938cfc1773a73ecee2c994fa98e small_script.js
diff --git a/jetty-start/pom.xml b/jetty-start/pom.xml
index 223482fb80e..9fcfa2c2cc8 100644
--- a/jetty-start/pom.xml
+++ b/jetty-start/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty
jetty-project
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
4.0.0
jetty-start
diff --git a/jetty-util/pom.xml b/jetty-util/pom.xml
index ba57b47dd8d..9e5dc45445a 100644
--- a/jetty-util/pom.xml
+++ b/jetty-util/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty
jetty-project
- 7.5.4-SNAPSHOT
+ 7.6.0-SNAPSHOT
4.0.0
jetty-util
@@ -29,7 +29,7 @@