From fae4f3fda93cbe2b0fe6dec42c1dec54a491c69a Mon Sep 17 00:00:00 2001 From: Alexander Kurtakov Date: Fri, 13 Jan 2012 23:35:13 +0200 Subject: [PATCH 01/32] Get rid of javax.activation. Java activation framework (JAF) or javax.activation:activation(maven) is an API that is integral part of every Java 5 level virtual machine. As such there is no point in still referencing/downloading/including or making any other operation with it. Simply removing references to it in build scripts makes it use the JVM provided one. Signed-off-by: Jesse McConnell --- jetty-aggregate/jetty-all-server/pom.xml | 9 --------- jetty-aggregate/jetty-all/pom.xml | 9 --------- jetty-aggregate/jetty-plus/pom.xml | 9 --------- jetty-distribution/pom.xml | 2 -- jetty-osgi/test-jetty-osgi/pom.xml | 2 -- pom.xml | 6 ------ 6 files changed, 37 deletions(-) diff --git a/jetty-aggregate/jetty-all-server/pom.xml b/jetty-aggregate/jetty-all-server/pom.xml index 072ff23321e..ed343ae1360 100644 --- a/jetty-aggregate/jetty-all-server/pom.xml +++ b/jetty-aggregate/jetty-all-server/pom.xml @@ -163,10 +163,6 @@ javax.mail mail - - javax.activation - activation - @@ -237,11 +233,6 @@ mail compile - - javax.activation - activation - compile - org.apache.geronimo.specs geronimo-jaspic_1.0_spec diff --git a/jetty-aggregate/jetty-all/pom.xml b/jetty-aggregate/jetty-all/pom.xml index 3a6eee3ac51..a59ba910ca0 100644 --- a/jetty-aggregate/jetty-all/pom.xml +++ b/jetty-aggregate/jetty-all/pom.xml @@ -147,10 +147,6 @@ javax.mail mail - - javax.activation - activation - @@ -221,11 +217,6 @@ mail compile - - javax.activation - activation - compile - org.apache.geronimo.specs geronimo-jaspic_1.0_spec diff --git a/jetty-aggregate/jetty-plus/pom.xml b/jetty-aggregate/jetty-plus/pom.xml index ff9bf1f74c9..e265fb4cb04 100644 --- a/jetty-aggregate/jetty-plus/pom.xml +++ b/jetty-aggregate/jetty-plus/pom.xml @@ -96,10 +96,6 @@ javax.mail mail - - javax.activation - activation - @@ -117,10 +113,5 @@ mail compile - - javax.activation - activation - compile - diff --git a/jetty-distribution/pom.xml b/jetty-distribution/pom.xml index 173d546d426..53351fd1e15 100644 --- a/jetty-distribution/pom.xml +++ b/jetty-distribution/pom.xml @@ -12,7 +12,6 @@ http://download.eclipse.org/jetty/orbit target/distribution 3.6 - ${javax-activation-version}.0.v201005080500 1.0.0.v20100513-0750 2.1.0.v201004190952 ${javax-mail-version}.v201005082020 @@ -69,7 +68,6 @@ - diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml index eedcb97f358..8a67c0316b8 100644 --- a/jetty-osgi/test-jetty-osgi/pom.xml +++ b/jetty-osgi/test-jetty-osgi/pom.xml @@ -14,7 +14,6 @@ http://download.eclipse.org/jetty/orbit/ target/distribution 3.6 - ${javax-activation-version}.0.v201005080500 1.0.0.v20100513-0750 2.1.0.v201004190952 ${javax-mail-version}.v201005082020 @@ -198,7 +197,6 @@ - diff --git a/pom.xml b/pom.xml index 63315d4c21c..534c7e60ef2 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,6 @@ ${jetty.url} pom - 1.1 1.4.1 2.1.v20100127 1.1.1 @@ -402,11 +401,6 @@ mail ${javax-mail-version} - - javax.activation - activation - ${javax-activation-version} - junit junit From d4a23c2a65f966aefcd714ebc19512d1e73ccc6d Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Mon, 16 Jan 2012 13:58:44 +1100 Subject: [PATCH 02/32] 368633 fixed configure.dtd resource mappings --- .../src/test/resources/contexts/foo.xml | 2 +- .../org/eclipse/jetty/xml/XmlConfiguration.java | 17 +++++++++-------- .../eclipse/jetty/xml/XmlConfigurationTest.java | 8 ++++++++ .../org/eclipse/jetty/xml/configure.xml | 2 +- .../resources/org/eclipse/jetty/xml/mortbay.xml | 4 ++++ .../webapp-contexts/RFC2616/rfc2616-webapp.xml | 2 +- 6 files changed, 24 insertions(+), 11 deletions(-) create mode 100644 jetty-xml/src/test/resources/org/eclipse/jetty/xml/mortbay.xml diff --git a/jetty-deploy/src/test/resources/contexts/foo.xml b/jetty-deploy/src/test/resources/contexts/foo.xml index cb3e7ddbb94..4c730f0b490 100644 --- a/jetty-deploy/src/test/resources/contexts/foo.xml +++ b/jetty-deploy/src/test/resources/contexts/foo.xml @@ -1,5 +1,5 @@ - + /foo diff --git a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java index d5f4df3915c..3945d9c5933 100644 --- a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java +++ b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java @@ -111,21 +111,22 @@ public class XmlConfiguration try { URL config60 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_6_0.dtd",true); - URL config71 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_7_1.dtd",true); - __parser.redirectEntity("configure.dtd",config71); + URL config76 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_7_6.dtd",true); + __parser.redirectEntity("configure.dtd",config76); __parser.redirectEntity("configure_1_0.dtd",config60); __parser.redirectEntity("configure_1_1.dtd",config60); __parser.redirectEntity("configure_1_2.dtd",config60); __parser.redirectEntity("configure_1_3.dtd",config60); __parser.redirectEntity("configure_6_0.dtd",config60); - __parser.redirectEntity("configure_7_1.dtd",config71); + __parser.redirectEntity("configure_7_6.dtd",config76); - __parser.redirectEntity("http://jetty.mortbay.org/configure.dtd",config71); - __parser.redirectEntity("http://jetty.eclipse.org/configure.dtd",config71); - __parser.redirectEntity("http://www.eclipse.org/jetty/configure.dtd",config71); + + __parser.redirectEntity("http://jetty.mortbay.org/configure.dtd",config76); + __parser.redirectEntity("http://jetty.eclipse.org/configure.dtd",config76); + __parser.redirectEntity("http://www.eclipse.org/jetty/configure.dtd",config76); - __parser.redirectEntity("-//Mort Bay Consulting//DTD Configure//EN",config71); - __parser.redirectEntity("-//Jetty//Configure//EN",config71); + __parser.redirectEntity("-//Mort Bay Consulting//DTD Configure//EN",config76); + __parser.redirectEntity("-//Jetty//Configure//EN",config76); } catch (ClassNotFoundException e) { diff --git a/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java b/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java index 700d7508805..16965d4201f 100644 --- a/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java +++ b/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java @@ -25,6 +25,14 @@ import org.junit.Test; public class XmlConfigurationTest { protected String _configure="org/eclipse/jetty/xml/configure.xml"; + + @Test + public void testMortBay() throws Exception + { + URL url = XmlConfigurationTest.class.getClassLoader().getResource("org/eclipse/jetty/xml/mortbay.xml"); + XmlConfiguration configuration = new XmlConfiguration(url); + Object o=configuration.configure(); + } @Test public void testPassedObject() throws Exception diff --git a/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configure.xml b/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configure.xml index fd0316bff67..32cda2bcff4 100644 --- a/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configure.xml +++ b/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configure.xml @@ -1,5 +1,5 @@ - + diff --git a/jetty-xml/src/test/resources/org/eclipse/jetty/xml/mortbay.xml b/jetty-xml/src/test/resources/org/eclipse/jetty/xml/mortbay.xml new file mode 100644 index 00000000000..2607bf8a191 --- /dev/null +++ b/jetty-xml/src/test/resources/org/eclipse/jetty/xml/mortbay.xml @@ -0,0 +1,4 @@ + + + + diff --git a/tests/test-integration/src/test/resources/webapp-contexts/RFC2616/rfc2616-webapp.xml b/tests/test-integration/src/test/resources/webapp-contexts/RFC2616/rfc2616-webapp.xml index 3cd2269a190..9ed47d422b9 100644 --- a/tests/test-integration/src/test/resources/webapp-contexts/RFC2616/rfc2616-webapp.xml +++ b/tests/test-integration/src/test/resources/webapp-contexts/RFC2616/rfc2616-webapp.xml @@ -1,5 +1,5 @@ - + /rfc2616-webapp From ef9ac7760daf460e6201e3daab35815aa1f6aa8e Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Mon, 16 Jan 2012 15:24:31 +1100 Subject: [PATCH 03/32] 368635 moved lifecycle state reporting from toString to dump --- .../eclipse/jetty/io/nio/SelectorManager.java | 5 ++- .../jetty/server/AbstractConnector.java | 5 ++- .../jetty/server/handler/AbstractHandler.java | 2 +- .../util/component/AbstractLifeCycle.java | 5 --- .../util/component/AggregateLifeCycle.java | 33 ++++++++++--------- .../jetty/util/ssl/SslContextFactory.java | 5 ++- .../jetty/util/thread/QueuedThreadPool.java | 2 +- 7 files changed, 25 insertions(+), 32 deletions(-) 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 a28b46ab824..212a6e264c0 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 @@ -372,7 +372,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa /* ------------------------------------------------------------ */ public void dump(Appendable out, String indent) throws IOException { - out.append(String.valueOf(this)).append("\n"); + AggregateLifeCycle.dumpObject(out,this); AggregateLifeCycle.dump(out,indent,TypeUtil.asList(_selectSet)); } @@ -983,9 +983,8 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa public String toString() { Selector selector=_selector; - return String.format("%s %s keys=%d selected=%d", + return String.format("%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-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java index 2dd058a615a..e36ee95331b 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 @@ -889,11 +889,10 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht @Override public String toString() { - return String.format("%s@%s:%d %s", + return String.format("%s@%s:%d", getClass().getSimpleName(), getHost()==null?"0.0.0.0":getHost(), - getLocalPort()<=0?getPort():getLocalPort(), - AbstractLifeCycle.getState(this)); + getLocalPort()<=0?getPort():getLocalPort()); } /* ------------------------------------------------------------ */ diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AbstractHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AbstractHandler.java index c17da968245..975e7991e53 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AbstractHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AbstractHandler.java @@ -94,7 +94,7 @@ public abstract class AbstractHandler extends AggregateLifeCycle implements Hand /* ------------------------------------------------------------ */ public void dumpThis(Appendable out) throws IOException { - out.append(toString()).append(' ').append(getState()).append('\n'); + out.append(toString()).append(" - ").append(getState()).append('\n'); } } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/component/AbstractLifeCycle.java b/jetty-util/src/main/java/org/eclipse/jetty/util/component/AbstractLifeCycle.java index b0ef41ce86c..e99b87555e2 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/component/AbstractLifeCycle.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/component/AbstractLifeCycle.java @@ -209,9 +209,4 @@ public abstract class AbstractLifeCycle implements LifeCycle public void lifeCycleStopped(LifeCycle event) {} public void lifeCycleStopping(LifeCycle event) {} } - - public String toString() - { - return super.toString()+"#"+getState(); - } } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java b/jetty-util/src/main/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java index 05448362f92..33796a2ba7c 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java @@ -339,7 +339,16 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable /* ------------------------------------------------------------ */ protected void dumpThis(Appendable out) throws IOException { - out.append(String.valueOf(this)).append("\n"); + out.append(String.valueOf(this)).append(" - ").append(getState()).append("\n"); + } + + /* ------------------------------------------------------------ */ + public static void dumpObject(Appendable out,Object o) throws IOException + { + if (o instanceof LifeCycle) + out.append(String.valueOf(o)).append(" - ").append((AbstractLifeCycle.getState((LifeCycle)o))).append("\n"); + else + out.append(String.valueOf(o)).append("\n"); } /* ------------------------------------------------------------ */ @@ -359,15 +368,11 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable out.append(indent).append(" +- "); if (b._bean instanceof Dumpable) ((Dumpable)b._bean).dump(out,indent+(i==size?" ":" | ")); - else - out.append(String.valueOf(b._bean)).append("\n"); + else + dumpObject(out,b._bean); } - else - { - out.append(indent).append(" +~ "); - out.append(String.valueOf(b._bean)).append("\n"); - } - + else + dumpObject(out,b._bean); } if (i!=size) @@ -395,16 +400,12 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable if (o instanceof Dumpable) ((Dumpable)o).dump(out,indent+(i==size?" ":" | ")); - else - out.append(String.valueOf(o)).append("\n"); + else + dumpObject(out,o); } if (i!=size) - out.append(indent).append(" |\n"); - + out.append(indent).append(" |\n"); } } - - - } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java index 956c294b885..94c0d93cf65 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java @@ -1524,11 +1524,10 @@ public class SslContextFactory extends AbstractLifeCycle /* ------------------------------------------------------------ */ public String toString() { - return String.format("%s@%x(%s,%s)#%s", + return String.format("%s@%x(%s,%s)", getClass().getSimpleName(), hashCode(), _keyStorePath, - _trustStorePath, - getState()); + _trustStorePath); } } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java index 1efec3536d0..981faa607c0 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java @@ -508,7 +508,7 @@ public class QueuedThreadPool extends AbstractLifeCycle implements SizedThreadPo @Override public String toString() { - return _name+"{"+getMinThreads()+"<="+getIdleThreads()+"<="+getThreads()+"/"+getMaxThreads()+","+(_jobs==null?-1:_jobs.size())+"}#"+getState(); + return _name+"{"+getMinThreads()+"<="+getIdleThreads()+"<="+getThreads()+"/"+getMaxThreads()+","+(_jobs==null?-1:_jobs.size())+"}"; } /* ------------------------------------------------------------ */ From 81c48518b63d7535a370befd95d1c5dcaf7a6443 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Mon, 16 Jan 2012 15:37:32 +1100 Subject: [PATCH 04/32] 368635 moved lifecycle state reporting from toString to dump --- .../src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java | 2 +- .../src/main/java/org/eclipse/jetty/servlet/Holder.java | 3 ++- .../java/org/eclipse/jetty/util/thread/QueuedThreadPool.java | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) 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 475a2da3a73..f833cef3ab5 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 @@ -337,7 +337,7 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste public void dump(Appendable out, String indent) throws IOException { - out.append(toString()).append("\n"); + AggregateLifeCycle.dumpObject(out,this); AggregateLifeCycle.dump(out, indent, _beans.entrySet()); } 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 cbbbb02ec9b..0622de2b65e 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 @@ -260,7 +260,8 @@ public class Holder extends AbstractLifeCycle implements Dumpable /* ------------------------------------------------------------ */ public void dump(Appendable out, String indent) throws IOException { - out.append(_name).append("==").append(_className).append("\n"); + out.append(_name).append("==").append(_className) + .append(" - ").append(AbstractLifeCycle.getState(this)).append("\n"); AggregateLifeCycle.dump(out,indent,_initParams.entrySet()); } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java index 981faa607c0..e3cccc09dd8 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java @@ -498,7 +498,7 @@ public class QueuedThreadPool extends AbstractLifeCycle implements SizedThreadPo } } - out.append(String.valueOf(this)).append("\n"); + AggregateLifeCycle.dumpObject(out,this); AggregateLifeCycle.dump(out,indent,dump); } From 50fe23882aa937bfde6efa765aaefe20ce883efd Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Tue, 17 Jan 2012 15:24:52 +1100 Subject: [PATCH 05/32] 368787 always set token view to new header buffers in httpparser --- .../org/eclipse/jetty/http/HttpParser.java | 39 ++---- .../jetty/server/HttpConnectionTest.java | 4 +- .../jetty/server/HttpServerTestBase.java | 74 ++++++++++- .../eclipse/jetty/server/UnreadInputTest.java | 118 ------------------ 4 files changed, 85 insertions(+), 150 deletions(-) delete mode 100644 jetty-server/src/test/java/org/eclipse/jetty/server/UnreadInputTest.java diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java index f7327177407..485eb4307f4 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java @@ -63,8 +63,8 @@ public class HttpParser implements Parser private Buffer _body; // Buffer for large content private Buffer _buffer; // The current buffer in use (either _header or _content) private CachedBuffer _cached; - private View.CaseInsensitive _tok0; // Saved token: header name, request method or response version - private View.CaseInsensitive _tok1; // Saved token: header value, request URI or response code + private final View.CaseInsensitive _tok0; // Saved token: header name, request method or response version + private final View.CaseInsensitive _tok1; // Saved token: header value, request URI or response code private String _multiLineValue; private int _responseStatus; // If >0 then we are parsing a response private boolean _forceContentBuffer; @@ -93,13 +93,8 @@ public class HttpParser implements Parser _buffer=buffer; _handler=handler; - if (buffer != null) - { - _tok0=new View.CaseInsensitive(buffer); - _tok1=new View.CaseInsensitive(buffer); - _tok0.setPutIndex(_tok0.getIndex()); - _tok1.setPutIndex(_tok1.getIndex()); - } + _tok0=new View.CaseInsensitive(_header); + _tok1=new View.CaseInsensitive(_header); } /* ------------------------------------------------------------------------------- */ @@ -114,6 +109,8 @@ public class HttpParser implements Parser _buffers=buffers; _endp=endp; _handler=handler; + _tok0=new View.CaseInsensitive(); + _tok1=new View.CaseInsensitive(); } /* ------------------------------------------------------------------------------- */ @@ -256,17 +253,7 @@ public class HttpParser implements Parser return 0; if (_buffer==null) - { - if (_header == null) - { - _header=_buffers.getHeader(); - } - _buffer=_header; - _tok0=new View.CaseInsensitive(_header); - _tok1=new View.CaseInsensitive(_header); - _tok0.setPutIndex(_tok0.getIndex()); - _tok1.setPutIndex(_tok1.getIndex()); - } + _buffer=getHeaderBuffer(); if (_state == STATE_CONTENT && _contentPosition == _contentLength) @@ -1013,11 +1000,7 @@ public class HttpParser implements Parser { // Do we have a buffer? if (_buffer==null) - { - _buffer=_header=getHeaderBuffer(); - _tok0=new View.CaseInsensitive(_buffer); - _tok1=new View.CaseInsensitive(_buffer); - } + _buffer=getHeaderBuffer(); // Is there unconsumed content in body buffer if (_state>STATE_END && _buffer==_header && _header!=null && !_header.hasContent() && _body!=null && _body.hasContent()) @@ -1086,9 +1069,7 @@ public class HttpParser implements Parser // This is probably a pipelined header of the next request, so we need to // copy it to the header buffer. if (_header==null) - { - _header=_buffers.getHeader(); - } + getHeaderBuffer(); else { _header.setMarkIndex(-1); @@ -1165,6 +1146,8 @@ public class HttpParser implements Parser if (_header == null) { _header=_buffers.getHeader(); + _tok0.update(_header); + _tok1.update(_header); } return _header; } 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 67207366582..1e258f33a9b 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 @@ -448,8 +448,8 @@ public class HttpConnectionTest PrintWriter writer = response.getWriter(); writer.write("

FOO

"); writer.flush(); - writer.close(); - throw new RuntimeException("SHOULD NOT GET HERE"); + if (!writer.checkError()) + throw new RuntimeException("SHOULD NOT GET HERE"); } 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 bb0d105a99f..78814183440 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 @@ -31,16 +31,21 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import junit.framework.Assert; + +import org.eclipse.jetty.http.HttpParser; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.StdErrLog; import org.junit.Test; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertThat; /** * @@ -492,7 +497,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture } finally { - System.err.println("Got "+total+" of "+(512*1024)); + //System.err.println("Got "+total+" of "+(512*1024)); client.close(); } } @@ -739,7 +744,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture IO.copy(is,bout); byte[] b=bout.toByteArray(); - System.err.println("OUTPUT: "+new String(b)); + //System.err.println("OUTPUT: "+new String(b)); int i=0; while (b[i]!='Z') i++; @@ -1205,4 +1210,69 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture + @Test + public void testUnreadInput () throws Exception + { + configureServer(new NoopHandler()); + final int REQS=5; + String content="This is a loooooooooooooooooooooooooooooooooo"+ + "ooooooooooooooooooooooooooooooooooooooooooooo"+ + "ooooooooooooooooooooooooooooooooooooooooooooo"+ + "ooooooooooooooooooooooooooooooooooooooooooooo"+ + "ooooooooooooooooooooooooooooooooooooooooooooo"+ + "ooooooooooooooooooooooooooooooooooooooooooooo"+ + "ooooooooooooooooooooooooooooooooooooooooooooo"+ + "ooooooooooooooooooooooooooooooooooooooooooooo"+ + "ooooooooooooooooooooooooooooooooooooooooooooo"+ + "oooooooooooonnnnnnnnnnnnnnnnggggggggg content"+ + new String(new char[65*1024]); + final byte[] bytes = content.getBytes(); + + Socket client=newSocket(HOST,_connector.getLocalPort()); + final OutputStream out=client.getOutputStream(); + + new Thread() + { + public void run() + { + try + { + for (int i=0; i Date: Tue, 17 Jan 2012 22:53:53 +1100 Subject: [PATCH 06/32] 368773 process data constraints without realm --- .../security/ConstraintSecurityHandler.java | 11 +- .../jetty/security/SecurityHandler.java | 37 +++- .../jetty/security/DataConstraintsTest.java | 178 ++++++++++++++++++ .../handler/AbstractHandlerContainer.java | 2 +- 4 files changed, 215 insertions(+), 13 deletions(-) create mode 100644 jetty-security/src/test/java/org/eclipse/jetty/security/DataConstraintsTest.java 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 44280872b43..e6356026ce2 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 @@ -358,7 +358,7 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr { if (connector.isIntegral(request)) return true; - if (connector.getConfidentialPort() > 0) + if (connector.getIntegralPort() > 0) { String url = connector.getIntegralScheme() + "://" + request.getServerName() + ":" + connector.getIntegralPort() + request.getRequestURI(); if (request.getQueryString() != null) @@ -440,6 +440,13 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr public void dump(Appendable out,String indent) throws IOException { dumpThis(out); - dump(out,indent,TypeUtil.asList(getHandlers()),getBeans(),Collections.singleton(_roles),_constraintMap.entrySet()); + dump(out,indent, + Collections.singleton(getLoginService()), + Collections.singleton(getIdentityService()), + Collections.singleton(getAuthenticator()), + Collections.singleton(_roles), + _constraintMap.entrySet(), + getBeans(), + TypeUtil.asList(getHandlers())); } } diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java b/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java index 7e4232c5795..da34f2d6337 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java @@ -244,16 +244,19 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti return _initParameters.put(key,value); } - /* ------------------------------------------------------------ */ protected LoginService findLoginService() { List list = getServer().getBeans(LoginService.class); - for (LoginService service : list) - if (service.getName()!=null && service.getName().equals(getRealmName())) - return service; - if (list.size()>0) + String realm=getRealmName(); + if (realm!=null) + { + for (LoginService service : list) + if (service.getName()!=null && service.getName().equals(realm)) + return service; + } + else if (list.size()==1) return list.get(0); return null; } @@ -414,7 +417,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti final Authenticator authenticator = _authenticator; - if (authenticator!=null && checkSecurity(baseRequest)) + if (checkSecurity(baseRequest)) { Object constraintInfo = prepareConstraintInfo(pathInContext, baseRequest); @@ -433,13 +436,24 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti boolean isAuthMandatory = isAuthMandatory(baseRequest, base_response, constraintInfo); + if (isAuthMandatory && authenticator==null) + { + LOG.warn("No authenticator for: "+constraintInfo); + if (!baseRequest.isHandled()) + { + response.sendError(Response.SC_FORBIDDEN); + baseRequest.setHandled(true); + } + return; + } + // check authentication Object previousIdentity = null; try { Authentication authentication = baseRequest.getAuthentication(); if (authentication==null || authentication==Authentication.NOT_CHECKED) - authentication=authenticator.validateRequest(request, response, isAuthMandatory); + authentication=authenticator==null?Authentication.UNAUTHENTICATED:authenticator.validateRequest(request, response, isAuthMandatory); if (authentication instanceof Authentication.Wrapped) { @@ -500,9 +514,11 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti else { baseRequest.setAuthentication(authentication); - previousIdentity = _identityService.associate(null); + if (_identityService!=null) + previousIdentity = _identityService.associate(null); handler.handle(pathInContext, baseRequest, request, response); - authenticator.secureResponse(request, response, isAuthMandatory, null); + if (authenticator!=null) + authenticator.secureResponse(request, response, isAuthMandatory, null); } } catch (ServerAuthException e) @@ -513,7 +529,8 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti } finally { - _identityService.disassociate(previousIdentity); + if (_identityService!=null) + _identityService.disassociate(previousIdentity); } } else diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/DataConstraintsTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/DataConstraintsTest.java new file mode 100644 index 00000000000..8b3ab580418 --- /dev/null +++ b/jetty-security/src/test/java/org/eclipse/jetty/security/DataConstraintsTest.java @@ -0,0 +1,178 @@ +// ======================================================================== +// 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.security; + +import static org.junit.Assert.assertThat; +import static org.junit.matchers.JUnitMatchers.containsString; + +import java.io.IOException; +import java.util.Arrays; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.http.HttpSchemes; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.LocalConnector; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.AbstractHandler; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.server.session.SessionHandler; +import org.eclipse.jetty.util.security.Constraint; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * @version $Revision: 1441 $ $Date: 2010-04-02 12:28:17 +0200 (Fri, 02 Apr 2010) $ + */ +public class DataConstraintsTest +{ + private Server _server; + private LocalConnector _connector; + private LocalConnector _connectorS; + private SessionHandler _session; + private ConstraintSecurityHandler _security; + + @Before + public void startServer() + { + _server = new Server(); + _connector = new LocalConnector(); + _connector.setIntegralPort(9998); + _connector.setIntegralScheme("FTP"); + _connector.setConfidentialPort(9999); + _connector.setConfidentialScheme("SPDY"); + _connectorS = new LocalConnector() + { + @Override + public void customize(EndPoint endpoint, Request request) throws IOException + { + super.customize(endpoint,request); + request.setScheme(HttpSchemes.HTTPS); + } + + @Override + public boolean isIntegral(Request request) + { + return true; + } + + @Override + public boolean isConfidential(Request request) + { + return true; + } + }; + _server.setConnectors(new Connector[]{_connector,_connectorS}); + + ContextHandler _context = new ContextHandler(); + _session = new SessionHandler(); + + _context.setContextPath("/ctx"); + _server.setHandler(_context); + _context.setHandler(_session); + + _security = new ConstraintSecurityHandler(); + _session.setHandler(_security); + + _security.setHandler(new AbstractHandler() + { + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + { + baseRequest.setHandled(true); + response.sendError(404); + } + }); + + } + + @After + public void stopServer() throws Exception + { + if (_server.isRunning()) + { + _server.stop(); + _server.join(); + } + } + + @Test + public void testIntegral() throws Exception + { + Constraint constraint0 = new Constraint(); + constraint0.setAuthenticate(false); + constraint0.setName("integral"); + constraint0.setDataConstraint(Constraint.DC_INTEGRAL); + ConstraintMapping mapping0 = new ConstraintMapping(); + mapping0.setPathSpec("/integral/*"); + mapping0.setConstraint(constraint0); + + _security.setConstraintMappings(Arrays.asList(new ConstraintMapping[] + { + mapping0 + })); + + _server.start(); + + String response; + response = _connector.getResponses("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 404 Not Found")); + + response = _connector.getResponses("GET /ctx/integral/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 302 Found")); + assertThat(response, containsString("Location: FTP://")); + assertThat(response, containsString(":9998")); + + response = _connectorS.getResponses("GET /ctx/integral/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 404 Not Found")); + + } + + @Test + public void testConfidential() throws Exception + { + Constraint constraint0 = new Constraint(); + constraint0.setAuthenticate(false); + constraint0.setName("confid"); + constraint0.setDataConstraint(Constraint.DC_CONFIDENTIAL); + ConstraintMapping mapping0 = new ConstraintMapping(); + mapping0.setPathSpec("/confid/*"); + mapping0.setConstraint(constraint0); + + _security.setConstraintMappings(Arrays.asList(new ConstraintMapping[] + { + mapping0 + })); + + _server.start(); + + String response; + response = _connector.getResponses("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 404 Not Found")); + + response = _connector.getResponses("GET /ctx/confid/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 302 Found")); + assertThat(response, containsString("Location: SPDY://")); + assertThat(response, containsString(":9999")); + + response = _connectorS.getResponses("GET /ctx/confid/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 404 Not Found")); + + } + +} diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AbstractHandlerContainer.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AbstractHandlerContainer.java index 263a948ce1b..345c23a035c 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AbstractHandlerContainer.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AbstractHandlerContainer.java @@ -113,6 +113,6 @@ public abstract class AbstractHandlerContainer extends AbstractHandler implement public void dump(Appendable out,String indent) throws IOException { dumpThis(out); - dump(out,indent,TypeUtil.asList(getHandlers()),getBeans()); + dump(out,indent,getBeans(),TypeUtil.asList(getHandlers())); } } From 1537433b8199a412149619cdc372c484594ba9c0 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Tue, 17 Jan 2012 23:59:12 +1100 Subject: [PATCH 07/32] 368821 Only do SSL asyncDispatch for temp buffer fills --- .../eclipse/jetty/io/nio/SslConnection.java | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) 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 index d531dc606e9..942b7f29652 100644 --- 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 @@ -274,40 +274,55 @@ public class SslConnection extends AbstractConnection implements AsyncConnection boolean some_progress=false; try { + // We need buffers to progress allocateBuffers(); + + // if we don't have a buffer to put received data into if (toFill==null) { + // use the unwrapbuffer to hold received data. _unwrapBuf.compact(); toFill=_unwrapBuf; } + // Else if the fill buffer is too small for the SSL session else if (toFill.capacity()<_session.getApplicationBufferSize()) { + // fill to the temporary unwrapBuffer boolean progress=process(null,toFlush); + + // if we received any data, if (_unwrapBuf!=null && _unwrapBuf.hasContent()) { + // transfer from temp buffer to fill buffer _unwrapBuf.skip(toFill.put(_unwrapBuf)); return true; } else + // return progress from recursive call return progress; } + // Else if there is some temporary data else if (_unwrapBuf!=null && _unwrapBuf.hasContent()) { + // transfer from temp buffer to fill buffer _unwrapBuf.skip(toFill.put(_unwrapBuf)); return true; } + // If we are here, we have a buffer ready into which we can put some read data. + // If we have no data to flush, flush the empty buffer if (toFlush==null) toFlush=__ZERO_BUFFER; + // While we are making progress processing SSL engine boolean progress=true; - while (progress) { progress=false; + + // Do any real IO int filled=0,flushed=0; - try { // Read any available data @@ -356,20 +371,6 @@ public class SslConnection extends AbstractConnection implements AsyncConnection 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; @@ -401,10 +402,12 @@ public class SslConnection extends AbstractConnection implements AsyncConnection if (_endp.isOpen() && _engine.isOutboundDone() && !_outbound.hasContent()) _endp.shutdownOutput(); + // remember if any progress has been made some_progress|=progress; } - if (toFill.hasContent()) + // If we are reading into the temp buffer and it has some content, then we should be dispatched. + if (toFill==_unwrapBuf && _unwrapBuf.hasContent()) _aEndp.asyncDispatch(); } finally From 6da9a22c092d470ff9f639e1ea38036040b3a548 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Tue, 17 Jan 2012 11:21:18 -0700 Subject: [PATCH 08/32] Minor update to VERSION.txt format --- VERSION.txt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/VERSION.txt b/VERSION.txt index 4ff3219db23..f3131428efd 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -9,11 +9,9 @@ jetty-7.6.0.RC4 - 13 January 2012 + 368035 WebSocketClientFactory does not invoke super.doStop(). + 368060 do not encode sendRedirect URLs + 368114 Protect against non-Strings in System properties for Log - + 368189 WebSocketClientFactory should not manage external thread pool. 368240 - - Improve AggregateLifeCycle handling of shared lifecycles + + 368189 WebSocketClientFactory should not manage external thread pool. + 368215 Remove debug from jaspi - + 368240 Better handling of locally created ThreadPool. Forgot to null out - field. + + 368240 Improve AggregateLifeCycle handling of shared lifecycles + 368291 Change warning to info for NoSuchFieldException on BeanELResolver.properties From fc3d2f059949897fe35bf0fe25f1e45369d7ee8a Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Tue, 17 Jan 2012 12:16:55 -0700 Subject: [PATCH 09/32] Setting TRACE tests to @Ignore pending review of changes for realmless security constraints that have rendered the TRACE tests invalid for integration testing of the default configuration --- .../java/org/eclipse/jetty/test/rfcs/RFC2616BaseTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BaseTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BaseTest.java index 60cc571af76..d480494e936 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BaseTest.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BaseTest.java @@ -16,8 +16,8 @@ package org.eclipse.jetty.test.rfcs; -import static org.junit.Assert.assertThat; -import static org.junit.matchers.JUnitMatchers.containsString; +import static org.junit.Assert.*; +import static org.junit.matchers.JUnitMatchers.*; import java.io.File; import java.io.IOException; @@ -42,6 +42,7 @@ import org.eclipse.jetty.toolchain.test.StringAssert; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; /** @@ -955,6 +956,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 9.8) */ @Test + @Ignore("Introduction of fix for realm-less security constraints has rendered this test invalid due to default configuration preventing use of TRACE in webdefault.xml") public void test9_8() throws Exception { From b6a51f0c065f1991963868b33fedb117bfdecfc8 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Tue, 17 Jan 2012 13:33:41 -0700 Subject: [PATCH 10/32] Updating testcase to indicate reason of failure (when testing on OSX) --- .../jetty/websocket/WebSocketMessageRFC6455Test.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageRFC6455Test.java b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageRFC6455Test.java index 3fe9942cb63..175ef6bf014 100644 --- a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageRFC6455Test.java +++ b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageRFC6455Test.java @@ -15,6 +15,9 @@ *******************************************************************************/ package org.eclipse.jetty.websocket; +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; + import java.io.EOFException; import java.io.IOException; import java.io.InputStream; @@ -28,9 +31,9 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import java.util.zip.Deflater; import java.util.zip.Inflater; + import javax.servlet.http.HttpServletRequest; -import junit.framework.Assert; import org.eclipse.jetty.io.Buffer; import org.eclipse.jetty.io.ByteArrayEndPoint; import org.eclipse.jetty.server.Connector; @@ -41,13 +44,10 @@ import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.Utf8StringBuilder; import org.junit.AfterClass; +import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - public class WebSocketMessageRFC6455Test { private static Server __server; @@ -606,7 +606,7 @@ public class WebSocketMessageRFC6455Test Thread.sleep(100); assertEquals(count*(mesg.length()+2),totalB.get()); // all messages - assertTrue(max>1000); // was blocked + Assert.assertThat("Was blocked (max time)", max, greaterThan(1000L)); // was blocked } @Test From 1ac71de645c5ba3013bfae1f9f8d3a7c0e571d76 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Wed, 18 Jan 2012 07:41:16 +1100 Subject: [PATCH 11/32] 368632 Remove superfluous removal of org.apache.catalina.jsp_file --- .../src/main/java/org/eclipse/jetty/server/Dispatcher.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 99c9ec33127..1102b491c8f 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 @@ -131,7 +131,7 @@ public class Dispatcher implements RequestDispatcher public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException { 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)) request = new ServletRequestHttpWrapper(request); @@ -215,7 +215,7 @@ public class Dispatcher implements RequestDispatcher Response base_response=baseRequest.getResponse(); response.resetBuffer(); base_response.fwdReset(); - request.removeAttribute(__JSP_FILE); // TODO remove when glassfish 1044 is fixed + if (!(request instanceof HttpServletRequest)) request = new ServletRequestHttpWrapper(request); From 6e38a97d7f2493d304e4a68afc3bcf03fa04136c Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Tue, 17 Jan 2012 23:00:34 +0100 Subject: [PATCH 12/32] When dumping the selector, we should take the keys only once, otherwise the set of keys may change between calls. --- .../java/org/eclipse/jetty/io/nio/SelectorManager.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) 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 a28b46ab824..ba6422a24fa 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 @@ -24,6 +24,7 @@ import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.ArrayList; import java.util.List; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentMap; @@ -303,7 +304,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa } }); - + if (!selecting) throw new IllegalStateException("!Selecting"); } @@ -960,7 +961,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa { LOG.ignore(e); } - + AggregateLifeCycle.dump(out,indent,dump); } } @@ -969,8 +970,9 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa public void dumpKeyState(List dumpto) { Selector selector=_selector; - dumpto.add(selector+" keys="+selector.keys().size()); - for (SelectionKey key: selector.keys()) + Set keys = selector.keys(); + dumpto.add(selector + " keys=" + keys.size()); + for (SelectionKey key: keys) { if (key.isValid()) dumpto.add(key.attachment()+" iOps="+key.interestOps()+" rOps="+key.readyOps()); From e609a65e61335d767fc919f5615cd4a8cd0fcdd2 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Tue, 17 Jan 2012 23:05:41 +0100 Subject: [PATCH 13/32] 368821 - SSL Spin on asyncDispatch. Test (for now ignored) that reproduces the problem. --- .../jetty/client/SslBytesServerTest.java | 173 +++++++++++++++++- 1 file changed, 172 insertions(+), 1 deletion(-) diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java index 618639ee058..5e32dc0f6c9 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java @@ -10,6 +10,7 @@ import java.net.SocketTimeoutException; import java.nio.channels.SocketChannel; import java.util.Arrays; import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; @@ -47,6 +48,7 @@ import org.junit.After; import org.junit.Assert; import org.junit.Assume; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import static org.hamcrest.Matchers.greaterThan; @@ -61,8 +63,10 @@ public class SslBytesServerTest extends SslBytesTest private final int idleTimeout = 2000; private ExecutorService threadPool; private Server server; + private int serverPort; private SSLContext sslContext; private SimpleProxy proxy; + private Runnable idleHook; @Before public void init() throws Exception @@ -98,6 +102,15 @@ public class SslBytesServerTest extends SslBytesTest } }; } + + @Override + public void onIdleExpired(long idleForMs) + { + final Runnable idleHook = SslBytesServerTest.this.idleHook; + if (idleHook != null) + idleHook.run(); + super.onIdleExpired(idleForMs); + } }; } @@ -166,7 +179,7 @@ public class SslBytesServerTest extends SslBytesTest } }); server.start(); - int serverPort = connector.getLocalPort(); + serverPort = connector.getLocalPort(); sslContext = cf.getSslContext(); @@ -1512,6 +1525,164 @@ public class SslBytesServerTest extends SslBytesTest Assert.assertFalse(serverEndPoint.get().isOpen()); } + @Test + public void testPlainText() throws Exception + { + final SSLSocket client = newClient(); + + threadPool.submit(new Callable() + { + public Object call() throws Exception + { + client.startHandshake(); + return null; + } + }); + + // Instead of passing the Client Hello, we simulate plain text was passed in + proxy.flushToServer(0, "GET / HTTP/1.1\r\n".getBytes("UTF-8")); + + // We expect that the server closes the connection immediately + TLSRecord record = proxy.readFromServer(); + Assert.assertNull(String.valueOf(record), record); + + // Check that we did not spin + TimeUnit.MILLISECONDS.sleep(500); + Assert.assertThat(sslHandles.get(), lessThan(20)); + Assert.assertThat(sslFlushes.get(), lessThan(20)); + Assert.assertThat(httpParses.get(), lessThan(50)); + + client.close(); + } + + @Ignore + @Test + public void testRequestConcurrentWithIdleExpiration() throws Exception + { + final SSLSocket client = newClient(); + final OutputStream clientOutput = client.getOutputStream(); + final CountDownLatch latch = new CountDownLatch(1); + + idleHook = new Runnable() + { + public void run() + { + try + { + // Send request + clientOutput.write(("" + + "GET / HTTP/1.1\r\n" + + "Host: localhost\r\n" + + "\r\n").getBytes("UTF-8")); + clientOutput.flush(); + latch.countDown(); + } + catch (Exception x) + { + // Latch won't trigger and test will + // fail, just print the stack trace + x.printStackTrace(); + } + } + }; + + SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow(); + client.startHandshake(); + Assert.assertTrue(automaticProxyFlow.stop(5, TimeUnit.SECONDS)); + + Assert.assertTrue(latch.await(idleTimeout * 2, TimeUnit.MILLISECONDS)); + + // Be sure that the server sent a SSL close alert + TLSRecord record = proxy.readFromServer(); + Assert.assertNotNull(record); + Assert.assertEquals(TLSRecord.Type.ALERT, record.getType()); + + // Write the request to the server, to simulate a request + // concurrent with the SSL close alert + record = proxy.readFromClient(); + Assert.assertEquals(TLSRecord.Type.APPLICATION, record.getType()); + proxy.flushToServer(record, 0); + + // Check that we did not spin + TimeUnit.MILLISECONDS.sleep(500); + Assert.assertThat(sslHandles.get(), lessThan(20)); + Assert.assertThat(sslFlushes.get(), lessThan(20)); + Assert.assertThat(httpParses.get(), lessThan(50)); + + closeClient(client); + } +/* + @Test + public void testRequestWriteBlockedWithPipelinedRequest() throws Exception + { + final SSLSocket client = newClient(); + final OutputStream clientOutput = client.getOutputStream(); + + SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow(); + client.startHandshake(); + Assert.assertTrue(automaticProxyFlow.stop(5, TimeUnit.SECONDS)); + + byte[] data = new byte[128 * 1024]; + Arrays.fill(data, (byte)'X'); + final String content = new String(data, "UTF-8"); + Future request = threadPool.submit(new Callable() + { + public Object call() throws Exception + { + clientOutput.write(("" + + "POST /echo HTTP/1.1\r\n" + + "Host: localhost\r\n" + + "Content-Length: " + content.length() + "\r\n" + + "\r\n" + + content).getBytes("UTF-8")); + clientOutput.flush(); + return null; + } + }); + + // Nine TLSRecords will be generated for the request + for (int i = 0; i < 9; ++i) + { + // Application data + TLSRecord record = proxy.readFromClient(); + Assert.assertEquals(TLSRecord.Type.APPLICATION, record.getType()); + proxy.flushToServer(record, 0); + } + Assert.assertNull(request.get(5, TimeUnit.SECONDS)); + + // We do not read the big request to cause a write blocked on the server + TimeUnit.MILLISECONDS.sleep(500); + + // Now send the pipelined request + Future pipelined = threadPool.submit(new Callable() + { + public Object call() throws Exception + { + clientOutput.write(("" + + "GET /pipelined HTTP/1.1\r\n" + + "Host: localhost\r\n" + + "\r\n").getBytes("UTF-8")); + clientOutput.flush(); + return null; + } + }); + + TLSRecord record = proxy.readFromClient(); + Assert.assertEquals(TLSRecord.Type.APPLICATION, record.getType()); + proxy.flushToServer(record, 0); + Assert.assertNull(pipelined.get(5, TimeUnit.SECONDS)); + + // Check that we did not spin + TimeUnit.MILLISECONDS.sleep(500); + Assert.assertThat(sslHandles.get(), lessThan(20)); + Assert.assertThat(sslFlushes.get(), lessThan(20)); + Assert.assertThat(httpParses.get(), lessThan(50)); + + Thread.sleep(5000); + +// closeClient(client); + } +*/ private void assumeJavaVersionSupportsTLSRenegotiations() { // Due to a security bug, TLS renegotiations were disabled in JDK 1.6.0_19-21 From 9ff8633554fd7fc6874e50329b4f0ed3fb70b473 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 18 Jan 2012 13:39:24 +1100 Subject: [PATCH 14/32] 368821 SslConnection.handle always calls wrapped Connection.handle, so state can be processed --- .../jetty/client/SslBytesServerTest.java | 6 +- .../org/eclipse/jetty/http/HttpParser.java | 2 +- .../eclipse/jetty/io/nio/SslConnection.java | 24 ++--- .../jetty/server/AsyncHttpConnection.java | 4 + .../websocket/WebSocketClientFactory.java | 101 +++++++++--------- 5 files changed, 71 insertions(+), 66 deletions(-) diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java index 5e32dc0f6c9..982b0740893 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java @@ -619,10 +619,10 @@ public class SslBytesServerTest extends SslBytesTest } // Check that we did not spin - TimeUnit.MILLISECONDS.sleep(500); + TimeUnit.MILLISECONDS.sleep(1000); Assert.assertThat(sslHandles.get(), lessThan(750)); Assert.assertThat(sslFlushes.get(), lessThan(750)); - Assert.assertThat(httpParses.get(), lessThan(150)); + Assert.assertThat(httpParses.get(), lessThan(1000)); client.close(); @@ -1555,7 +1555,6 @@ public class SslBytesServerTest extends SslBytesTest client.close(); } - @Ignore @Test public void testRequestConcurrentWithIdleExpiration() throws Exception { @@ -1609,7 +1608,6 @@ public class SslBytesServerTest extends SslBytesTest Assert.assertThat(sslFlushes.get(), lessThan(20)); Assert.assertThat(httpParses.get(), lessThan(50)); - closeClient(client); } /* @Test diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java index 485eb4307f4..c7d7d39f88a 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java @@ -194,7 +194,7 @@ public class HttpParser implements Parser public void setPersistent(boolean persistent) { _persistent = persistent; - if (_state==STATE_END) + if (!_persistent &&(_state==STATE_END || _state==STATE_START)) _state=STATE_SEEKING_EOF; } 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 index 942b7f29652..db9436e7fee 100644 --- 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 @@ -182,22 +182,17 @@ public class SslConnection extends AbstractConnection implements AsyncConnection 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) { - // handle the delegate connection - AsyncConnection next = (AsyncConnection)_connection.handle(); - if (next!=_connection && next!=null) - { - _connection=next; - progress=true; - } - // TODO: consider moving here hasProgressed() - it's only used in SSL + _connection=next; + progress=true; } LOG.debug("{} handle {} progress={}", _session, this, progress); @@ -389,6 +384,11 @@ public class SslConnection extends AbstractConnection implements AsyncConnection // The SSL needs to receive some handshake data from the other side if (_handshook && !_allowRenegotiate) _endp.close(); + else if (!_inbound.hasContent()&&filled==-1) + { + // No more input coming + _endp.shutdownInput(); + } else if (unwrap(toFill)) progress=true; } 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 cbd9b7ecf39..a482da34583 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 @@ -177,6 +177,10 @@ public class AsyncHttpConnection extends AbstractHttpConnection implements Async // then no more can happen, so close. _endp.close(); } + + // Make idle parser seek EOF + if (_parser.isIdle()) + _parser.setPersistent(false); } } diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketClientFactory.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketClientFactory.java index e0ef62e2306..3fd58535b35 100644 --- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketClientFactory.java +++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketClientFactory.java @@ -354,7 +354,7 @@ public class WebSocketClientFactory extends AggregateLifeCycle private final HttpParser _parser; private String _accept; private String _error; - private boolean _handshaken; + private ByteArrayBuffer _handshake; public HandshakeConnection(AsyncEndPoint endpoint, WebSocketClient.WebSocketFuture future) { @@ -404,72 +404,75 @@ public class WebSocketClientFactory extends AggregateLifeCycle }); } - private void handshake() + private boolean handshake() { - String path = _future.getURI().getPath(); - if (path == null || path.length() == 0) - path = "/"; - - if (_future.getURI().getRawQuery() != null) - path += "?" + _future.getURI().getRawQuery(); - - String origin = _future.getOrigin(); - - StringBuilder request = new StringBuilder(512); - request.append("GET ").append(path).append(" HTTP/1.1\r\n") - .append("Host: ").append(_future.getURI().getHost()).append(":") - .append(_future.getURI().getPort()).append("\r\n") - .append("Upgrade: websocket\r\n") - .append("Connection: Upgrade\r\n") - .append("Sec-WebSocket-Key: ") - .append(_key).append("\r\n"); - - if (origin != null) - request.append("Origin: ").append(origin).append("\r\n"); - - request.append("Sec-WebSocket-Version: ").append(WebSocketConnectionRFC6455.VERSION).append("\r\n"); - - if (_future.getProtocol() != null) - request.append("Sec-WebSocket-Protocol: ").append(_future.getProtocol()).append("\r\n"); - - Map cookies = _future.getCookies(); - if (cookies != null && cookies.size() > 0) + if (_handshake==null) { - for (String cookie : cookies.keySet()) - request.append("Cookie: ") - .append(QuotedStringTokenizer.quoteIfNeeded(cookie, HttpFields.__COOKIE_DELIM)) - .append("=") - .append(QuotedStringTokenizer.quoteIfNeeded(cookies.get(cookie), HttpFields.__COOKIE_DELIM)) - .append("\r\n"); + String path = _future.getURI().getPath(); + if (path == null || path.length() == 0) + path = "/"; + + if (_future.getURI().getRawQuery() != null) + path += "?" + _future.getURI().getRawQuery(); + + String origin = _future.getOrigin(); + + StringBuilder request = new StringBuilder(512); + request.append("GET ").append(path).append(" HTTP/1.1\r\n") + .append("Host: ").append(_future.getURI().getHost()).append(":") + .append(_future.getURI().getPort()).append("\r\n") + .append("Upgrade: websocket\r\n") + .append("Connection: Upgrade\r\n") + .append("Sec-WebSocket-Key: ") + .append(_key).append("\r\n"); + + if (origin != null) + request.append("Origin: ").append(origin).append("\r\n"); + + request.append("Sec-WebSocket-Version: ").append(WebSocketConnectionRFC6455.VERSION).append("\r\n"); + + if (_future.getProtocol() != null) + request.append("Sec-WebSocket-Protocol: ").append(_future.getProtocol()).append("\r\n"); + + Map cookies = _future.getCookies(); + if (cookies != null && cookies.size() > 0) + { + for (String cookie : cookies.keySet()) + request.append("Cookie: ") + .append(QuotedStringTokenizer.quoteIfNeeded(cookie, HttpFields.__COOKIE_DELIM)) + .append("=") + .append(QuotedStringTokenizer.quoteIfNeeded(cookies.get(cookie), HttpFields.__COOKIE_DELIM)) + .append("\r\n"); + } + + request.append("\r\n"); + + _handshake=new ByteArrayBuffer(request.toString(), false); } - - request.append("\r\n"); - + // TODO extensions try { - Buffer handshake = new ByteArrayBuffer(request.toString(), false); - int len = handshake.length(); - if (len != _endp.flush(handshake)) - throw new IOException("incomplete"); + int len = _handshake.length(); + int flushed = _endp.flush(_handshake); + if (flushed<0) + throw new IOException("incomplete handshake"); } catch (IOException e) { _future.handshakeFailed(e); } - finally - { - _handshaken = true; - } + return _handshake.length()==0; } public Connection handle() throws IOException { while (_endp.isOpen() && !_parser.isComplete()) { - if (!_handshaken) - handshake(); + if (_handshake==null || _handshake.length()>0) + if (!handshake()) + return this; if (!_parser.parseAvailable()) { From 3e04cac272886b4913a2273cb43014a92bc77da6 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 18 Jan 2012 14:16:09 +1100 Subject: [PATCH 15/32] JETTY-1475 made output state fields volatile to provide memory barrier for non dispatched thread IO --- .../eclipse/jetty/server/AbstractHttpConnection.java | 10 +++++----- .../main/java/org/eclipse/jetty/server/Response.java | 9 +++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java index c4e9e3e266d..116fbc37738 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java @@ -102,14 +102,14 @@ public abstract class AbstractHttpConnection extends AbstractConnection protected final Parser _parser; protected final HttpFields _requestFields; protected final Request _request; - protected ServletInputStream _in; + protected volatile ServletInputStream _in; protected final Generator _generator; protected final HttpFields _responseFields; protected final Response _response; - protected Output _out; - protected OutputWriter _writer; - protected PrintWriter _printWriter; + protected volatile Output _out; + protected volatile OutputWriter _writer; + protected volatile PrintWriter _printWriter; int _include; @@ -122,7 +122,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection private boolean _expect102Processing = false; private boolean _head = false; private boolean _host = false; - private boolean _delayedHandling=false; + private boolean _delayedHandling=false; /* ------------------------------------------------------------ */ public static AbstractHttpConnection getCurrentConnection() 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 1befeff5ad7..883e62d0caf 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 @@ -81,7 +81,7 @@ public class Response implements HttpServletResponse private String _characterEncoding; private boolean _explicitEncoding; private String _contentType; - private int _outputState; + private volatile int _outputState; private PrintWriter _writer; /* ------------------------------------------------------------ */ @@ -108,8 +108,8 @@ public class Response implements HttpServletResponse _characterEncoding=null; _explicitEncoding=false; _contentType=null; - _outputState=NONE; _writer=null; + _outputState=NONE; } /* ------------------------------------------------------------ */ @@ -646,8 +646,9 @@ public class Response implements HttpServletResponse if (_outputState!=NONE && _outputState!=STREAM) throw new IllegalStateException("WRITER"); + ServletOutputStream out = _connection.getOutputStream(); _outputState=STREAM; - return _connection.getOutputStream(); + return out; } /* ------------------------------------------------------------ */ @@ -1065,8 +1066,8 @@ public class Response implements HttpServletResponse { resetBuffer(); - _outputState=NONE; _writer=null; + _outputState=NONE; } /* ------------------------------------------------------------ */ From c696f144503072477f088d58ff77797931b44dec Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 18 Jan 2012 15:24:20 +1100 Subject: [PATCH 16/32] 368821 improved test harness --- .../jetty/client/SslBytesServerTest.java | 37 +++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java index 982b0740893..0d0f44d3da6 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java @@ -43,16 +43,18 @@ import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.ssl.SslSelectChannelConnector; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.OS; +import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.junit.After; import org.junit.Assert; import org.junit.Assume; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.lessThan; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; public class SslBytesServerTest extends SslBytesTest { @@ -1566,6 +1568,8 @@ public class SslBytesServerTest extends SslBytesTest { public void run() { + if (latch.getCount()==0) + return; try { // Send request @@ -1578,8 +1582,7 @@ public class SslBytesServerTest extends SslBytesTest } catch (Exception x) { - // Latch won't trigger and test will - // fail, just print the stack trace + // Latch won't trigger and test will fail x.printStackTrace(); } } @@ -1608,6 +1611,15 @@ public class SslBytesServerTest extends SslBytesTest Assert.assertThat(sslFlushes.get(), lessThan(20)); Assert.assertThat(httpParses.get(), lessThan(50)); + //System.err.println(((Dumpable)server.getConnectors()[0]).dump()); + Assert.assertThat(((Dumpable)server.getConnectors()[0]).dump(),containsString("SCEP@")); + + completeClose(client); + + TimeUnit.MILLISECONDS.sleep(200); + //System.err.println(((Dumpable)server.getConnectors()[0]).dump()); + Assert.assertThat(((Dumpable)server.getConnectors()[0]).dump(),not(containsString("SCEP@"))); + } /* @Test @@ -1718,9 +1730,28 @@ public class SslBytesServerTest extends SslBytesTest // Close Alert record = proxy.readFromServer(); proxy.flushToClient(record); + // Socket close record = proxy.readFromServer(); Assert.assertNull(String.valueOf(record), record); proxy.flushToClient(record); } + + private void completeClose(SSLSocket client) throws Exception + { + client.close(); + + // Close Alert + TLSRecord record = proxy.readFromClient(); + proxy.flushToServer(record); + // Socket close + record = proxy.readFromClient(); + Assert.assertNull(String.valueOf(record), record); + proxy.flushToServer(record); + + // Close Alert + record = proxy.readFromServer(); + proxy.flushToClient(record); + + } } From 7f1de41953f339de1881dcbaa322048edfec6c38 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 18 Jan 2012 10:03:18 +0100 Subject: [PATCH 17/32] 368920 - JettyAwareLogger always formats the arguments. --- .../jetty/util/log/JettyAwareLogger.java | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/log/JettyAwareLogger.java b/jetty-util/src/main/java/org/eclipse/jetty/util/log/JettyAwareLogger.java index 52bb112079c..65fa4d44cb7 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/log/JettyAwareLogger.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/log/JettyAwareLogger.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.util.log; @@ -19,20 +19,20 @@ import org.slf4j.helpers.MessageFormatter; /** * JettyAwareLogger is used to fix a FQCN bug that arises from how Jetty * Log uses an indirect slf4j implementation. - * + * * https://bugs.eclipse.org/bugs/show_bug.cgi?id=276670 */ -class JettyAwareLogger implements org.slf4j.Logger +class JettyAwareLogger implements org.slf4j.Logger { private static final int DEBUG = org.slf4j.spi.LocationAwareLogger.DEBUG_INT; private static final int ERROR = org.slf4j.spi.LocationAwareLogger.ERROR_INT; private static final int INFO = org.slf4j.spi.LocationAwareLogger.INFO_INT; private static final int TRACE = org.slf4j.spi.LocationAwareLogger.TRACE_INT; private static final int WARN = org.slf4j.spi.LocationAwareLogger.WARN_INT; - + private static final String FQCN = Slf4jLog.class.getName(); private final org.slf4j.spi.LocationAwareLogger _logger; - + public JettyAwareLogger(org.slf4j.spi.LocationAwareLogger logger) { _logger = logger; @@ -586,26 +586,33 @@ class JettyAwareLogger implements org.slf4j.Logger { log(marker, ERROR, msg, null, t); } - + @Override public String toString() { return _logger.toString(); } - + private void log(Marker marker, int level, String msg, Object[] argArray, Throwable t) { if (argArray == null) { // Simple SLF4J Message (no args) - _logger.log(marker,FQCN,level,msg,null,t); + _logger.log(marker, FQCN, level, msg, null, t); } else { - // Don't assume downstream handles argArray properly. - // Do it the SLF4J way here to eliminate that as a bug. - FormattingTuple ft = MessageFormatter.arrayFormat(msg,argArray); - _logger.log(marker,FQCN,level,ft.getMessage(),null,t); + int loggerLevel = _logger.isTraceEnabled() ? TRACE : + _logger.isDebugEnabled() ? DEBUG : + _logger.isInfoEnabled() ? INFO : + _logger.isWarnEnabled() ? WARN : ERROR; + if (loggerLevel <= level) + { + // Don't assume downstream handles argArray properly. + // Do it the SLF4J way here to eliminate that as a bug. + FormattingTuple ft = MessageFormatter.arrayFormat(msg, argArray); + _logger.log(marker, FQCN, level, ft.getMessage(), null, t); + } } } } From f039d009106dc21b5f505e8c6691958f3feca629 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 18 Jan 2012 10:05:35 +0100 Subject: [PATCH 18/32] Made SslConnection logger a per-instance variable, to avoid lock contention with other SslConnection instances. --- .../eclipse/jetty/io/nio/SslConnection.java | 53 ++++++++++--------- .../io/nio/SelectChannelEndPointSslTest.java | 35 ++++++------ 2 files changed, 44 insertions(+), 44 deletions(-) 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 index db9436e7fee..bcf7d74be7e 100644 --- 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 @@ -42,7 +42,7 @@ import org.eclipse.jetty.util.thread.Timeout.Task; */ public class SslConnection extends AbstractConnection implements AsyncConnection { - static final Logger LOG=Log.getLogger("org.eclipse.jetty.io.nio.ssl"); + private final Logger _logger = Log.getLogger("org.eclipse.jetty.io.nio.ssl"); private static final NIOBuffer __ZERO_BUFFER=new IndirectNIOBuffer(0); @@ -182,11 +182,11 @@ public class SslConnection extends AbstractConnection implements AsyncConnection while (progress) { progress=false; - + // If we are handshook let the delegate connection if (_engine.getHandshakeStatus()!=HandshakeStatus.NOT_HANDSHAKING) progress=process(null,null); - + // handle the delegate connection AsyncConnection next = (AsyncConnection)_connection.handle(); if (next!=_connection && next!=null) @@ -195,7 +195,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection progress=true; } - LOG.debug("{} handle {} progress={}", _session, this, progress); + _logger.debug("{} handle {} progress={}", _session, this, progress); } } finally @@ -211,9 +211,10 @@ public class SslConnection extends AbstractConnection implements AsyncConnection } catch(Throwable x) { - LOG.warn("onInputShutdown failed", x); + _logger.warn("onInputShutdown failed", x); try{_sslEndPoint.close();} - catch(IOException e2){LOG.ignore(e2);} + catch(IOException e2){ + _logger.ignore(e2);} } } } @@ -244,7 +245,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection { try { - LOG.debug("onIdleExpired {}ms on {}",idleForMs,this); + _logger.debug("onIdleExpired {}ms on {}",idleForMs,this); if (_endp.isOutputShutdown()) _sslEndPoint.close(); else @@ -252,7 +253,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection } catch (IOException e) { - LOG.warn(e); + _logger.warn(e); super.onIdleExpired(idleForMs); } } @@ -271,7 +272,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection { // We need buffers to progress allocateBuffers(); - + // if we don't have a buffer to put received data into if (toFill==null) { @@ -284,7 +285,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection { // fill to the temporary unwrapBuffer boolean progress=process(null,toFlush); - + // if we received any data, if (_unwrapBuf!=null && _unwrapBuf.hasContent()) { @@ -315,7 +316,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection while (progress) { progress=false; - + // Do any real IO int filled=0,flushed=0; try @@ -335,7 +336,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection } finally { - LOG.debug("{} {} {} filled={}/{} flushed={}/{}",_session,this,_engine.getHandshakeStatus(),filled,_inbound.length(),flushed,_outbound.length()); + _logger.debug("{} {} {} filled={}/{} flushed={}/{}",_session,this,_engine.getHandshakeStatus(),filled,_inbound.length(),flushed,_outbound.length()); } // handle the current hand share status @@ -437,8 +438,8 @@ public class SslConnection extends AbstractConnection implements AsyncConnection 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={}", + if (_logger.isDebugEnabled()) + _logger.debug("{} wrap {} {} consumed={} produced={}", _session, result.getStatus(), result.getHandshakeStatus(), @@ -451,7 +452,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection } catch(SSLException e) { - LOG.warn(String.valueOf(_endp), e); + _logger.warn(String.valueOf(_endp), e); _endp.close(); throw e; } @@ -479,13 +480,13 @@ public class SslConnection extends AbstractConnection implements AsyncConnection break; case CLOSED: - LOG.debug("wrap CLOSE {} {}",this,result); + _logger.debug("wrap CLOSE {} {}",this,result); if (result.getHandshakeStatus()==HandshakeStatus.FINISHED) _endp.close(); break; default: - LOG.warn("{} wrap default {}",_session,result); + _logger.warn("{} wrap default {}",_session,result); throw new IOException(result.toString()); } @@ -513,8 +514,8 @@ public class SslConnection extends AbstractConnection implements AsyncConnection in_buffer.limit(_inbound.putIndex()); result=_engine.unwrap(in_buffer,bbuf); - if (LOG.isDebugEnabled()) - LOG.debug("{} unwrap {} {} consumed={} produced={}", + if (_logger.isDebugEnabled()) + _logger.debug("{} unwrap {} {} consumed={} produced={}", _session, result.getStatus(), result.getHandshakeStatus(), @@ -527,7 +528,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection } catch(SSLException e) { - LOG.warn(String.valueOf(_endp), e); + _logger.warn(String.valueOf(_endp), e); _endp.close(); throw e; } @@ -549,7 +550,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection break; case BUFFER_OVERFLOW: - LOG.debug("{} unwrap {} {}->{}",_session,result.getStatus(),_inbound.toDetailString(),buffer.toDetailString()); + _logger.debug("{} unwrap {} {}->{}",_session,result.getStatus(),_inbound.toDetailString(),buffer.toDetailString()); break; case OK: @@ -558,13 +559,13 @@ public class SslConnection extends AbstractConnection implements AsyncConnection break; case CLOSED: - LOG.debug("unwrap CLOSE {} {}",this,result); + _logger.debug("unwrap CLOSE {} {}",this,result); if (result.getHandshakeStatus()==HandshakeStatus.FINISHED) _endp.close(); break; default: - LOG.warn("{} wrap default {}",_session,result); + _logger.warn("{} wrap default {}",_session,result); throw new IOException(result.toString()); } @@ -613,7 +614,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection { synchronized (SslConnection.this) { - LOG.debug("{} ssl endp.oshut {}",_session,this); + _logger.debug("{} ssl endp.oshut {}",_session,this); _engine.closeOutbound(); _oshut=true; } @@ -630,7 +631,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection public void shutdownInput() throws IOException { - LOG.debug("{} ssl endp.ishut!",_session); + _logger.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. } @@ -647,7 +648,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection public void close() throws IOException { - LOG.debug("{} ssl endp.close",_session); + _logger.debug("{} ssl endp.close",_session); _endp.close(); } 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 index d6a6a46a06a..fbf3eae1ac7 100644 --- 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 @@ -5,7 +5,6 @@ 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; @@ -22,7 +21,7 @@ import org.junit.Test; public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest { static SslContextFactory __sslCtxFactory=new SslContextFactory(); - + @BeforeClass public static void initSslEngine() throws Exception { @@ -32,7 +31,7 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest __sslCtxFactory.setKeyManagerPassword("keypwd"); __sslCtxFactory.start(); } - + @Override protected Socket newClient() throws IOException { @@ -60,46 +59,46 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest 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(); - + + boolean debug=false; + 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()); @@ -133,16 +132,16 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest } 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(); @@ -164,11 +163,11 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest 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"); From 486af626354c423d9f946e8155aef6cbae252494 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 18 Jan 2012 12:38:28 +0100 Subject: [PATCH 19/32] Improved logging of exceptions; now stack traces are printed in debug mode, if the exception is rethrown. --- .../org/eclipse/jetty/io/nio/SelectChannelEndPoint.java | 3 +-- .../main/java/org/eclipse/jetty/io/nio/SslConnection.java | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) 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 ab5d9ff75c0..7b6ed38971c 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 @@ -280,7 +280,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo public void checkIdleTimestamp(long now) { long idleTimestamp=_idleTimestamp; - + if (idleTimestamp!=0 && _maxIdleTime>0) { long idleForMs=now-idleTimestamp; @@ -637,7 +637,6 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo catch (IOException e) { LOG.warn(e.toString()); - LOG.debug(e); try{close();} catch(IOException e2){LOG.ignore(e2);} } 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 index bcf7d74be7e..4b8e0a55d1d 100644 --- 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 @@ -452,7 +452,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection } catch(SSLException e) { - _logger.warn(String.valueOf(_endp), e); + _logger.debug(String.valueOf(_endp), e); _endp.close(); throw e; } @@ -486,7 +486,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection break; default: - _logger.warn("{} wrap default {}",_session,result); + _logger.debug("{} wrap default {}",_session,result); throw new IOException(result.toString()); } @@ -528,7 +528,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection } catch(SSLException e) { - _logger.warn(String.valueOf(_endp), e); + _logger.debug(String.valueOf(_endp), e); _endp.close(); throw e; } @@ -565,7 +565,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection break; default: - _logger.warn("{} wrap default {}",_session,result); + _logger.debug("{} wrap default {}",_session,result); throw new IOException(result.toString()); } From 6a55f2c88292af8d06eeb8b01d3524f14116d7d6 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 18 Jan 2012 13:24:35 +0100 Subject: [PATCH 20/32] 368948 - POM for jetty-jndi references unknown version for javax.activation. --- jetty-jndi/pom.xml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/jetty-jndi/pom.xml b/jetty-jndi/pom.xml index bd9764512d6..74a4faa0394 100644 --- a/jetty-jndi/pom.xml +++ b/jetty-jndi/pom.xml @@ -66,26 +66,26 @@ javax.mail mail - - - javax.activation - activation - - + + + javax.activation + activation + + below-jdk1.6 - !1.6 + (,1.6) - - javax.activation - activation - ${javax-activation-version} - + + javax.activation + activation + 1.1 + From fa24681df93084df1a6614e5e61cbdb89b5f5f39 Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Wed, 18 Jan 2012 07:57:25 -0600 Subject: [PATCH 21/32] [368593] remove profile altogether, javax.activation is part of all modern jvm and a separate dependency should not be required any longer --- jetty-jndi/pom.xml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/jetty-jndi/pom.xml b/jetty-jndi/pom.xml index 74a4faa0394..1e1dbe767ff 100644 --- a/jetty-jndi/pom.xml +++ b/jetty-jndi/pom.xml @@ -74,19 +74,4 @@ - - - below-jdk1.6 - - (,1.6) - - - - javax.activation - activation - 1.1 - - - - From dba80219b172f2747b346e4dee3fe2bd52149e3a Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Wed, 18 Jan 2012 08:29:43 -0600 Subject: [PATCH 22/32] [368593] javax.activation is _not_ present in 1.5.0_18 --- jetty-jndi/pom.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/jetty-jndi/pom.xml b/jetty-jndi/pom.xml index 1e1dbe767ff..2a37fb7f390 100644 --- a/jetty-jndi/pom.xml +++ b/jetty-jndi/pom.xml @@ -74,4 +74,19 @@ + + + below-jdk1.6 + + (,1.6) + + + + javax.activation + activation + 1.1 + + + + From ec7eb3348addb6de5902b4115e5ad6aea258c38b Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Wed, 18 Jan 2012 15:16:34 -0600 Subject: [PATCH 23/32] Revert "Get rid of javax.activation." this was not appropriate for jetty7 which needs to support java 1.5 which is not universally bundling javax.activation as previously understood. The original commit should stand for jetty 8 though which will be handled during that merge This reverts commit fae4f3fda93cbe2b0fe6dec42c1dec54a491c69a. --- jetty-aggregate/jetty-all-server/pom.xml | 9 +++++++++ jetty-aggregate/jetty-all/pom.xml | 9 +++++++++ jetty-aggregate/jetty-plus/pom.xml | 9 +++++++++ jetty-distribution/pom.xml | 2 ++ jetty-osgi/test-jetty-osgi/pom.xml | 2 ++ pom.xml | 6 ++++++ 6 files changed, 37 insertions(+) diff --git a/jetty-aggregate/jetty-all-server/pom.xml b/jetty-aggregate/jetty-all-server/pom.xml index ed343ae1360..072ff23321e 100644 --- a/jetty-aggregate/jetty-all-server/pom.xml +++ b/jetty-aggregate/jetty-all-server/pom.xml @@ -163,6 +163,10 @@ javax.mail mail + + javax.activation + activation + @@ -233,6 +237,11 @@ mail compile + + javax.activation + activation + compile + org.apache.geronimo.specs geronimo-jaspic_1.0_spec diff --git a/jetty-aggregate/jetty-all/pom.xml b/jetty-aggregate/jetty-all/pom.xml index a59ba910ca0..3a6eee3ac51 100644 --- a/jetty-aggregate/jetty-all/pom.xml +++ b/jetty-aggregate/jetty-all/pom.xml @@ -147,6 +147,10 @@ javax.mail mail + + javax.activation + activation + @@ -217,6 +221,11 @@ mail compile + + javax.activation + activation + compile + org.apache.geronimo.specs geronimo-jaspic_1.0_spec diff --git a/jetty-aggregate/jetty-plus/pom.xml b/jetty-aggregate/jetty-plus/pom.xml index e265fb4cb04..ff9bf1f74c9 100644 --- a/jetty-aggregate/jetty-plus/pom.xml +++ b/jetty-aggregate/jetty-plus/pom.xml @@ -96,6 +96,10 @@ javax.mail mail + + javax.activation + activation + @@ -113,5 +117,10 @@ mail compile + + javax.activation + activation + compile + diff --git a/jetty-distribution/pom.xml b/jetty-distribution/pom.xml index 53351fd1e15..173d546d426 100644 --- a/jetty-distribution/pom.xml +++ b/jetty-distribution/pom.xml @@ -12,6 +12,7 @@ http://download.eclipse.org/jetty/orbit target/distribution 3.6 + ${javax-activation-version}.0.v201005080500 1.0.0.v20100513-0750 2.1.0.v201004190952 ${javax-mail-version}.v201005082020 @@ -68,6 +69,7 @@ + diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml index 8a67c0316b8..eedcb97f358 100644 --- a/jetty-osgi/test-jetty-osgi/pom.xml +++ b/jetty-osgi/test-jetty-osgi/pom.xml @@ -14,6 +14,7 @@ http://download.eclipse.org/jetty/orbit/ target/distribution 3.6 + ${javax-activation-version}.0.v201005080500 1.0.0.v20100513-0750 2.1.0.v201004190952 ${javax-mail-version}.v201005082020 @@ -197,6 +198,7 @@ + diff --git a/pom.xml b/pom.xml index 534c7e60ef2..63315d4c21c 100644 --- a/pom.xml +++ b/pom.xml @@ -11,6 +11,7 @@ ${jetty.url} pom + 1.1 1.4.1 2.1.v20100127 1.1.1 @@ -401,6 +402,11 @@ mail ${javax-mail-version} + + javax.activation + activation + ${javax-activation-version} + junit junit From f79bdfaf2ea8f881fcd04442c4e12c2cff02772e Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 19 Jan 2012 12:39:45 +1100 Subject: [PATCH 24/32] 368992 clear interest ops for double dispatch even if no read/write blocked threads --- .../org/eclipse/jetty/io/nio/SelectChannelEndPoint.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) 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 ab5d9ff75c0..d440a1ba4ab 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 @@ -176,9 +176,12 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo _writable = true; // Once writable is in ops, only removed with dispatch. } - // Dispatch if we are not already - if (!_dispatched) + // If dispatched, then deregister interest + if (_dispatched) + _key.interestOps(0); + else { + // other wise do the dispatch dispatch(); if (_dispatched && !_selectSet.getManager().isDeferringInterestedOps0()) { From 5cd9dbc6d39fdafa5e7e2db75a90a8b2d34611bf Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 19 Jan 2012 23:08:54 +1100 Subject: [PATCH 25/32] removed unneeded imports --- .../src/main/java/org/eclipse/jetty/util/log/StdErrLog.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/log/StdErrLog.java b/jetty-util/src/main/java/org/eclipse/jetty/util/log/StdErrLog.java index c0a2e246ee8..4e628333566 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/log/StdErrLog.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/log/StdErrLog.java @@ -16,8 +16,6 @@ package org.eclipse.jetty.util.log; import java.io.PrintStream; import java.security.AccessControlException; import java.util.Properties; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import org.eclipse.jetty.util.DateCache; From 50e551de64f8a910f483270df1c16eccb4616f9a Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 19 Jan 2012 23:11:27 +1100 Subject: [PATCH 26/32] 368992: improved logging --- .../java/org/eclipse/jetty/servlets/ProxyServlet.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) 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 2b7ee1252ff..782d16765b1 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 @@ -739,8 +739,14 @@ public class ProxyServlet implements Servlet */ protected void handleOnException(Throwable ex, HttpServletRequest request, HttpServletResponse response) { - _log.warn(ex.toString()); - _log.debug(ex); + if (ex instanceof IOException) + { + _log.warn(ex.toString()); + _log.debug(ex); + } + else + _log.warn(ex); + if (!response.isCommitted()) { response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); From 8e262aca046c0696b36826e9cd44c6d04ba586b1 Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Thu, 19 Jan 2012 11:26:17 -0600 Subject: [PATCH 27/32] [369120] more descriptive test failure output --- .../org/eclipse/jetty/io/nio/SelectChannelEndPointTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 index 768f872258e..f7e672ed98c 100644 --- 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 @@ -196,7 +196,8 @@ public class SelectChannelEndPointTest } catch(SocketTimeoutException e) { - assertTrue(System.currentTimeMillis()-start>=400); + long duration = System.currentTimeMillis()-start; + Assert.assertThat("timeout duration", duration, greaterThanOrEqualTo(400L)); } // write then shutdown From 4fe85c9c1e7347f6f3f4cbbe10f27545507e6f89 Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Thu, 19 Jan 2012 13:42:07 -0600 Subject: [PATCH 28/32] additional more informative test error messages --- .../org/eclipse/jetty/io/nio/SelectChannelEndPointTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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 index f7e672ed98c..3b781cd3278 100644 --- 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 @@ -1,6 +1,8 @@ package org.eclipse.jetty.io.nio; import static org.hamcrest.Matchers.greaterThanOrEqualTo; +import static org.hamcrest.Matchers.greaterThan; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -207,8 +209,8 @@ public class SelectChannelEndPointTest for (char c : "Goodbye Cruel TLS".toCharArray()) { int b = client.getInputStream().read(); - assertTrue(b>0); - assertEquals(c,(char)b); + Assert.assertThat("expect valid char integer", b, greaterThan(0)); + assertEquals("expect characters to be same", c,(char)b); } client.close(); From cdba99aee5c36259bb51fda961b38203afc5426a Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Fri, 20 Jan 2012 08:01:35 +1100 Subject: [PATCH 29/32] 359329 Prevent reinvocation of LoginModule.login with jaspi for already authed user --- .../jaspi/modules/FormAuthModule.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) 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 bb813be6493..2f0c54a4525 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 @@ -211,11 +211,20 @@ public class FormAuthModule extends BaseAuthModule // Check if the session is already authenticated. FormCredential form_cred = (FormCredential) session.getAttribute(__J_AUTHENTICATED); if (form_cred != null) - { - //TODO: we would like the form auth module to be able to invoke the loginservice.validate() method to check the previously authed user - - boolean success = tryLogin(messageInfo, clientSubject, response, session, form_cred._jUserName, new Password(new String(form_cred._jPassword))); - if (success) { return AuthStatus.SUCCESS; } + { + //TODO: ideally we would like the form auth module to be able to invoke the + //loginservice.validate() method to check the previously authed user, but it is not visible + //to FormAuthModule + if (form_cred._subject == null) + return AuthStatus.SEND_FAILURE; + Set credentials = form_cred._subject.getPrivateCredentials(); + if (credentials == null || credentials.isEmpty()) + return AuthStatus.SEND_FAILURE; //if no private credentials, assume it cannot be authenticated + + clientSubject.getPrivateCredentials().addAll(credentials); + + //boolean success = tryLogin(messageInfo, clientSubject, response, session, form_cred._jUserName, new Password(new String(form_cred._jPassword))); + return AuthStatus.SUCCESS; } else if (ssoSource != null) { From 8e69edaf9ec3343cf038a561fb54451c024cd13c Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Fri, 20 Jan 2012 12:40:34 +1100 Subject: [PATCH 30/32] 368992 avoid non-blocking flush when writing to avoid setting !_writable without _writeblocked --- .../org/eclipse/jetty/io/nio/SelectChannelEndPoint.java | 9 +-------- .../main/java/org/eclipse/jetty/server/HttpOutput.java | 6 +++--- 2 files changed, 4 insertions(+), 11 deletions(-) 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 ff95a454ed3..ffbcc163e12 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 @@ -457,14 +457,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo } return true; } - - /* ------------------------------------------------------------ */ - /* short cut for busyselectChannelServerTest */ - public void clearWritable() - { - _writable=false; - } - + /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.io.AsyncEndPoint#scheduleWrite() 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 7f5d2628b4d..12bf46b6d73 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 @@ -135,8 +135,8 @@ public class HttpOutput extends ServletOutputStream // Add the _content if (_generator.addContent((byte)b)) - // Buffers are full so flush. - flush(); + // Buffers are full so commit. + _connection.commitResponse(Generator.MORE); if (_generator.isAllContentWritten()) { @@ -174,7 +174,7 @@ public class HttpOutput extends ServletOutputStream close(); } else if (_generator.isBufferFull()) - flush(); + _connection.commitResponse(Generator.MORE); // Block until our buffer is free while (buffer.length() > 0 && _generator.isOpen()) From a5947342411fb69f1ab0029c0882e1b24dac6428 Mon Sep 17 00:00:00 2001 From: Thomas Becker Date: Thu, 19 Jan 2012 11:13:22 +0100 Subject: [PATCH 31/32] 369048: more test cases for ConstraintSecurityHandler Signed-off-by: Greg Wilkins --- .../jetty/security/DataConstraintsTest.java | 280 +++++++++++++++++- 1 file changed, 269 insertions(+), 11 deletions(-) diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/DataConstraintsTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/DataConstraintsTest.java index 8b3ab580418..38a2bb0eb7c 100644 --- a/jetty-security/src/test/java/org/eclipse/jetty/security/DataConstraintsTest.java +++ b/jetty-security/src/test/java/org/eclipse/jetty/security/DataConstraintsTest.java @@ -23,12 +23,15 @@ 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.HttpSchemes; import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.security.authentication.BasicAuthenticator; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.LocalConnector; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.session.SessionHandler; @@ -53,6 +56,7 @@ public class DataConstraintsTest { _server = new Server(); _connector = new LocalConnector(); + _connector.setMaxIdleTime(300000); _connector.setIntegralPort(9998); _connector.setIntegralScheme("FTP"); _connector.setConfidentialPort(9999); @@ -89,7 +93,7 @@ public class DataConstraintsTest _security = new ConstraintSecurityHandler(); _session.setHandler(_security); - + _security.setHandler(new AbstractHandler() { public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException @@ -98,7 +102,7 @@ public class DataConstraintsTest response.sendError(404); } }); - + } @After @@ -121,14 +125,14 @@ public class DataConstraintsTest ConstraintMapping mapping0 = new ConstraintMapping(); mapping0.setPathSpec("/integral/*"); mapping0.setConstraint(constraint0); - + _security.setConstraintMappings(Arrays.asList(new ConstraintMapping[] { mapping0 })); - + _server.start(); - + String response; response = _connector.getResponses("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 404 Not Found")); @@ -137,12 +141,12 @@ public class DataConstraintsTest assertThat(response, containsString("HTTP/1.1 302 Found")); assertThat(response, containsString("Location: FTP://")); assertThat(response, containsString(":9998")); - + response = _connectorS.getResponses("GET /ctx/integral/info HTTP/1.0\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 404 Not Found")); } - + @Test public void testConfidential() throws Exception { @@ -153,14 +157,14 @@ public class DataConstraintsTest ConstraintMapping mapping0 = new ConstraintMapping(); mapping0.setPathSpec("/confid/*"); mapping0.setConstraint(constraint0); - + _security.setConstraintMappings(Arrays.asList(new ConstraintMapping[] { mapping0 })); - + _server.start(); - + String response; response = _connector.getResponses("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 404 Not Found")); @@ -169,10 +173,264 @@ public class DataConstraintsTest assertThat(response, containsString("HTTP/1.1 302 Found")); assertThat(response, containsString("Location: SPDY://")); assertThat(response, containsString(":9999")); - + response = _connectorS.getResponses("GET /ctx/confid/info HTTP/1.0\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 404 Not Found")); } + @Test + public void testConfidentialWithNoRolesSetAndNoMethodRestriction() throws Exception + { + Constraint constraint0 = new Constraint(); + constraint0.setName("confid"); + constraint0.setDataConstraint(Constraint.DC_CONFIDENTIAL); + ConstraintMapping mapping0 = new ConstraintMapping(); + mapping0.setPathSpec("/confid/*"); + mapping0.setConstraint(constraint0); + + _security.setConstraintMappings(Arrays.asList(new ConstraintMapping[] + { + mapping0 + })); + + _server.start(); + + String response; + + response = _connector.getResponses("GET /ctx/confid/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 302 Found")); + + response = _connectorS.getResponses("GET /ctx/confid/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 404 Not Found")); + + } + + @Test + public void testConfidentialWithNoRolesSetAndMethodRestriction() throws Exception + { + Constraint constraint0 = new Constraint(); + constraint0.setName("confid"); + constraint0.setDataConstraint(Constraint.DC_CONFIDENTIAL); + ConstraintMapping mapping0 = new ConstraintMapping(); + mapping0.setPathSpec("/confid/*"); + mapping0.setMethod(HttpMethods.POST); + mapping0.setConstraint(constraint0); + + _security.setConstraintMappings(Arrays.asList(new ConstraintMapping[] + { + mapping0 + })); + + _server.start(); + + String response; + + response = _connector.getResponses("GET /ctx/confid/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 404 Not Found")); + + response = _connectorS.getResponses("GET /ctx/confid/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 404 Not Found")); + + response = _connector.getResponses("POST /ctx/confid/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 302 Found")); + + response = _connectorS.getResponses("POST /ctx/confid/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 404 Not Found")); + + } + @Test + public void testConfidentialWithRolesSetAndMethodRestriction() throws Exception + { + Constraint constraint0 = new Constraint(); + constraint0.setRoles(new String[] { "admin" } ); + constraint0.setName("confid"); + constraint0.setDataConstraint(Constraint.DC_CONFIDENTIAL); + ConstraintMapping mapping0 = new ConstraintMapping(); + mapping0.setPathSpec("/confid/*"); + mapping0.setMethod(HttpMethods.POST); + mapping0.setConstraint(constraint0); + + _security.setConstraintMappings(Arrays.asList(new ConstraintMapping[] + { + mapping0 + })); + + _server.start(); + + String response; + + response = _connector.getResponses("GET /ctx/confid/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 404 Not Found")); + + response = _connectorS.getResponses("GET /ctx/confid/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 404 Not Found")); + + response = _connector.getResponses("POST /ctx/confid/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 302 Found")); + + response = _connectorS.getResponses("POST /ctx/confid/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 404 Not Found")); + + } + + @Test + public void testConfidentialWithRolesSetAndMethodRestrictionAndAuthenticationRequired() throws Exception + { + Constraint constraint0 = new Constraint(); + constraint0.setRoles(new String[] { "admin" } ); + constraint0.setAuthenticate(true); + constraint0.setName("confid"); + constraint0.setDataConstraint(Constraint.DC_CONFIDENTIAL); + ConstraintMapping mapping0 = new ConstraintMapping(); + mapping0.setPathSpec("/confid/*"); + mapping0.setMethod(HttpMethods.POST); + mapping0.setConstraint(constraint0); + + _security.setConstraintMappings(Arrays.asList(new ConstraintMapping[] + { + mapping0 + })); + DefaultIdentityService identityService = new DefaultIdentityService(); + _security.setLoginService(new CustomLoginService(identityService)); + _security.setIdentityService(identityService); + _security.setAuthenticator(new BasicAuthenticator()); + _server.start(); + + String response; + + response = _connector.getResponses("GET /ctx/confid/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 404 Not Found")); + + response = _connectorS.getResponses("GET /ctx/confid/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 404 Not Found")); + + response = _connector.getResponses("POST /ctx/confid/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 302 Found")); + + response = _connectorS.getResponses("POST /ctx/confid/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 401 Unauthorized")); + + response = _connector.getResponses("GET /ctx/confid/info HTTP/1.0\r\nAuthorization: Basic YWRtaW46cGFzc3dvcmQ=\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 404 Not Found")); + + response = _connector.getResponses("POST /ctx/confid/info HTTP/1.0\r\nAuthorization: Basic YWRtaW46cGFzc3dvcmQ=\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 302 Found")); + + response = _connectorS.getResponses("POST /ctx/confid/info HTTP/1.0\r\nAuthorization: Basic YWRtaW46cGFzc3dvcmQ=\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 404 Not Found")); + + } + + @Test + public void testRestrictedWithoutAuthenticator() throws Exception + { + Constraint constraint0 = new Constraint(); + constraint0.setAuthenticate(true); + constraint0.setRoles(new String[] { "admin" } ); + constraint0.setName("restricted"); + ConstraintMapping mapping0 = new ConstraintMapping(); + mapping0.setPathSpec("/restricted/*"); + mapping0.setMethod("GET"); + mapping0.setConstraint(constraint0); + + _security.setConstraintMappings(Arrays.asList(new ConstraintMapping[] + { + mapping0 + })); + _server.start(); + + String response; + + response = _connector.getResponses("GET /ctx/restricted/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 403 Forbidden")); + + response = _connectorS.getResponses("GET /ctx/restricted/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 403 Forbidden")); + + response = _connector.getResponses("GET /ctx/restricted/info HTTP/1.0\r\n Authorization: Basic YWRtaW46cGFzc3dvcmQ=\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 403 Forbidden")); + + response = _connectorS.getResponses("GET /ctx/restricted/info HTTP/1.0\r\n Authorization: Basic YWRtaW46cGFzc3dvcmQ=\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 403 Forbidden")); + + } + + @Test + public void testRestricted() throws Exception + { + Constraint constraint0 = new Constraint(); + constraint0.setAuthenticate(true); + constraint0.setRoles(new String[] { "admin" } ); + constraint0.setName("restricted"); + ConstraintMapping mapping0 = new ConstraintMapping(); + mapping0.setPathSpec("/restricted/*"); + mapping0.setMethod("GET"); + mapping0.setConstraint(constraint0); + + _security.setConstraintMappings(Arrays.asList(new ConstraintMapping[] + { + mapping0 + })); + DefaultIdentityService identityService = new DefaultIdentityService(); + _security.setLoginService(new CustomLoginService(identityService)); + _security.setIdentityService(identityService); + _security.setAuthenticator(new BasicAuthenticator()); + _server.start(); + + String response; + + response = _connector.getResponses("GET /ctx/restricted/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 401 Unauthorized")); + + response = _connectorS.getResponses("GET /ctx/restricted/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 401 Unauthorized")); + + response = _connector.getResponses("GET /ctx/restricted/info HTTP/1.0\nAuthorization: Basic YWRtaW46cGFzc3dvcmQ=\n\n"); + assertThat(response, containsString("HTTP/1.1 404 Not Found")); + + response = _connectorS.getResponses("GET /ctx/restricted/info HTTP/1.0\nAuthorization: Basic YWRtaW46cGFzc3dvcmQ=\n\n"); + assertThat(response, containsString("HTTP/1.1 404 Not Found")); + + } + + private class CustomLoginService implements LoginService{ + private IdentityService identityService; + + public CustomLoginService(IdentityService identityService) + { + this.identityService = identityService; + } + public String getName() + { + return "name"; + } + + public UserIdentity login(String username, Object credentials) + { + if("admin".equals(username) && "password".equals(credentials)) + return new DefaultUserIdentity(null,null,new String[] { "admin" } ); + return null; + } + + public boolean validate(UserIdentity user) + { + return false; + } + + public IdentityService getIdentityService() + { + return identityService; + } + + public void setIdentityService(IdentityService service) + { + } + + public void logout(UserIdentity user) + { + } + + } + } From de16f7672518ecf4dd61bf8957ecee49fa612fad Mon Sep 17 00:00:00 2001 From: Thomas Becker Date: Thu, 19 Jan 2012 11:20:37 +0100 Subject: [PATCH 32/32] 369048: one more test Signed-off-by: Greg Wilkins --- .../jetty/security/DataConstraintsTest.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/DataConstraintsTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/DataConstraintsTest.java index 38a2bb0eb7c..fd3ea0f92c4 100644 --- a/jetty-security/src/test/java/org/eclipse/jetty/security/DataConstraintsTest.java +++ b/jetty-security/src/test/java/org/eclipse/jetty/security/DataConstraintsTest.java @@ -324,6 +324,39 @@ public class DataConstraintsTest @Test public void testRestrictedWithoutAuthenticator() throws Exception + { + Constraint constraint0 = new Constraint(); + constraint0.setAuthenticate(true); + constraint0.setRoles(new String[] { "admin" } ); + constraint0.setName("restricted"); + ConstraintMapping mapping0 = new ConstraintMapping(); + mapping0.setPathSpec("/restricted/*"); + mapping0.setConstraint(constraint0); + + _security.setConstraintMappings(Arrays.asList(new ConstraintMapping[] + { + mapping0 + })); + _server.start(); + + String response; + + response = _connector.getResponses("GET /ctx/restricted/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 403 Forbidden")); + + response = _connectorS.getResponses("GET /ctx/restricted/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 403 Forbidden")); + + response = _connector.getResponses("GET /ctx/restricted/info HTTP/1.0\r\n Authorization: Basic YWRtaW46cGFzc3dvcmQ=\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 403 Forbidden")); + + response = _connectorS.getResponses("GET /ctx/restricted/info HTTP/1.0\r\n Authorization: Basic YWRtaW46cGFzc3dvcmQ=\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 403 Forbidden")); + + } + + @Test + public void testRestrictedWithoutAuthenticatorAndMethod() throws Exception { Constraint constraint0 = new Constraint(); constraint0.setAuthenticate(true);