From 3cd6d90e9fae53e6841c69a29c3ae955794d73cd Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 4 Apr 2013 15:36:16 +1100 Subject: [PATCH 1/3] removed verbose output --- .../main/java/org/eclipse/jetty/server/ShutdownMonitor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ShutdownMonitor.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ShutdownMonitor.java index 70347e036c5..6fe64a80a56 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ShutdownMonitor.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ShutdownMonitor.java @@ -156,7 +156,8 @@ public class ShutdownMonitor { return; } - System.err.println("Starting ShutdownMonitorThread"); + if (DEBUG) + System.err.println("Starting ShutdownMonitorThread"); super.start(); } From df6e18cc0037d91b5986c5b689eec7bf5f13066f Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 4 Apr 2013 15:36:37 +1100 Subject: [PATCH 2/3] 404517 Close connection if request received after half close --- .../jetty/io/nio/SelectChannelEndPoint.java | 126 ++++++++++++------ 1 file changed, 84 insertions(+), 42 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 7b0816b7d3f..9bafc0171e7 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 @@ -63,11 +63,13 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo */ private volatile AsyncConnection _connection; - /** true if a thread has been dispatched to handle this endpoint */ - private boolean _dispatched = false; - - /** true if a non IO dispatch (eg async resume) is outstanding */ - private boolean _asyncDispatch = false; + private static final int STATE_NEEDS_DISPATCH=-1; + private static final int STATE_UNDISPATCHED=0; + private static final int STATE_DISPATCHED=1; + private static final int STATE_ASYNC=2; + private int _state; + + private boolean _onIdle; /** true if the last write operation succeed and wrote all offered bytes */ private volatile boolean _writable = true; @@ -83,6 +85,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo private boolean _open; private volatile long _idleTimestamp; + private volatile boolean _checkIdle; private boolean _ishut; @@ -94,8 +97,8 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo _manager = selectSet.getManager(); _selectSet = selectSet; - _dispatched = false; - _asyncDispatch = false; + _state=STATE_UNDISPATCHED; + _onIdle=false; _open=true; _key = key; @@ -169,7 +172,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo // we are not interested in further selecting _key.interestOps(0); - if (!_dispatched) + if (_state=STATE_DISPATCHED) _key.interestOps(0); else { // other wise do the dispatch dispatch(); - if (_dispatched && !_selectSet.getManager().isDeferringInterestedOps0()) + if (_state>=STATE_DISPATCHED && !_selectSet.getManager().isDeferringInterestedOps0()) { _key.interestOps(0); } @@ -203,10 +206,18 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo { synchronized(this) { - if (_dispatched) - _asyncDispatch=true; - else - dispatch(); + switch(_state) + { + case STATE_NEEDS_DISPATCH: + case STATE_UNDISPATCHED: + dispatch(); + break; + + case STATE_DISPATCHED: + case STATE_ASYNC: + _state=STATE_ASYNC; + break; + } } } @@ -215,15 +226,20 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo { synchronized(this) { - if (!_dispatched) + if (_state<=STATE_UNDISPATCHED) { - _dispatched = true; - boolean dispatched = _manager.dispatch(_handler); - if(!dispatched) + if (_onIdle) + _state = STATE_NEEDS_DISPATCH; + else { - _dispatched = false; - LOG.warn("Dispatched Failed! "+this+" to "+_manager); - updateKey(); + _state = STATE_DISPATCHED; + boolean dispatched = _manager.dispatch(_handler); + if(!dispatched) + { + _state = STATE_UNDISPATCHED; + LOG.warn("Dispatched Failed! "+this+" to "+_manager); + updateKey(); + } } } } @@ -240,15 +256,18 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo { synchronized (this) { - if (_asyncDispatch) + switch(_state) { - _asyncDispatch=false; - return false; + case STATE_ASYNC: + _state=STATE_DISPATCHED; + return false; + + default: + _state=STATE_UNDISPATCHED; + updateKey(); + return true; } - _dispatched = false; - updateKey(); } - return true; } /* ------------------------------------------------------------ */ @@ -266,30 +285,33 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo /* ------------------------------------------------------------ */ public void setCheckForIdle(boolean check) { - _idleTimestamp=check?System.currentTimeMillis():0; + if (check) + { + _idleTimestamp=System.currentTimeMillis(); + _checkIdle=true; + } + else + _checkIdle=false; } /* ------------------------------------------------------------ */ public boolean isCheckForIdle() { - return _idleTimestamp!=0; + return _checkIdle; } /* ------------------------------------------------------------ */ protected void notIdle() { - if (_idleTimestamp!=0) - _idleTimestamp=System.currentTimeMillis(); + _idleTimestamp=System.currentTimeMillis(); } /* ------------------------------------------------------------ */ public void checkIdleTimestamp(long now) { - long idleTimestamp=_idleTimestamp; - - if (idleTimestamp!=0 && _maxIdleTime>0) + if (isCheckForIdle() && _maxIdleTime>0) { - final long idleForMs=now-idleTimestamp; + final long idleForMs=now-_idleTimestamp; if (idleForMs>_maxIdleTime) { @@ -316,7 +338,27 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo /* ------------------------------------------------------------ */ public void onIdleExpired(long idleForMs) { - _connection.onIdleExpired(idleForMs); + System.err.println("ON IDLE EXPIRED"); + try + { + synchronized (this) + { + _onIdle=true; + } + + if (_maxIdleTime>0 && (System.currentTimeMillis()-_idleTimestamp)>_maxIdleTime) + _connection.onIdleExpired(idleForMs); + + } + finally + { + synchronized (this) + { + _onIdle=false; + if (_state==STATE_NEEDS_DISPATCH) + dispatch(); + } + } } /* ------------------------------------------------------------ */ @@ -341,7 +383,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo synchronized (this) { _writable=false; - if (!_dispatched) + if (_stater(%s),d=%b,open=%b,ishut=%b,oshut=%b,rb=%b,wb=%b,w=%b,i=%d%s}-{%s}", + return String.format("SCEP@%x{l(%s)<->r(%s),s=%d,open=%b,ishut=%b,oshut=%b,rb=%b,wb=%b,w=%b,i=%d%s}-{%s}", hashCode(), _socket.getRemoteSocketAddress(), _socket.getLocalSocketAddress(), - _dispatched, + _state, isOpen(), isInputShutdown(), isOutputShutdown(), From 060389147bbdec48a3a9e24fb07b8c2db148a6f8 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 4 Apr 2013 16:05:27 +1100 Subject: [PATCH 3/3] 404128 Add Vary headers rather than set them --- .../http/gzip/AbstractCompressedStream.java | 9 ++++- .../eclipse/jetty/servlet/DefaultServlet.java | 2 +- .../jetty/servlets/IncludableGzipFilter.java | 37 +++++-------------- 3 files changed, 18 insertions(+), 30 deletions(-) diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/AbstractCompressedStream.java b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/AbstractCompressedStream.java index 8317914d9ce..3094d3a4661 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/AbstractCompressedStream.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/AbstractCompressedStream.java @@ -234,7 +234,7 @@ public abstract class AbstractCompressedStream extends ServletOutputStream setHeader("Content-Encoding", _encoding); if (_response.containsHeader("Content-Encoding")) { - setHeader("Vary",_vary); + addHeader("Vary",_vary); _out=_compressedOutputStream=createStream(); if (_out!=null) { @@ -269,7 +269,7 @@ public abstract class AbstractCompressedStream extends ServletOutputStream if (_out == null || _bOut != null) { if (sendVary) - setHeader("Vary",_vary); + addHeader("Vary",_vary); if (_wrapper.getETag()!=null) setHeader("ETag",_wrapper.getETag()); @@ -341,6 +341,11 @@ public abstract class AbstractCompressedStream extends ServletOutputStream return encoding == null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding)); } + protected void addHeader(String name,String value) + { + _response.addHeader(name, value); + } + protected void setHeader(String name,String value) { _response.setHeader(name, value); diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java index 3c31e08e78d..5b5f32b8992 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java @@ -454,7 +454,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory if (resource!=null && resource.exists() && !resource.isDirectory()) { // Tell caches that response may vary by accept-encoding - response.setHeader(HttpHeaders.VARY,HttpHeaders.ACCEPT_ENCODING); + response.addHeader(HttpHeaders.VARY,HttpHeaders.ACCEPT_ENCODING); // Does the client accept gzip? String accept=request.getHeader(HttpHeaders.ACCEPT_ENCODING); diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java index 5ba2be0022f..d07787f7b84 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java @@ -84,15 +84,6 @@ public class IncludableGzipFilter extends GzipFilter { return null; } - - @Override - protected void setHeader(String name, String value) - { - super.setHeader(name, value); - HttpServletResponse response = (HttpServletResponse)getResponse(); - if (!response.containsHeader(name)) - response.setHeader("org.eclipse.jetty.server.include." + name, value); - } }; } }; @@ -111,15 +102,6 @@ public class IncludableGzipFilter extends GzipFilter { return new GZIPOutputStream(_response.getOutputStream(),_bufferSize); } - - @Override - protected void setHeader(String name, String value) - { - super.setHeader(name, value); - HttpServletResponse response = (HttpServletResponse)getResponse(); - if (!response.containsHeader(name)) - response.setHeader("org.eclipse.jetty.server.include." + name, value); - } }; } }; @@ -138,15 +120,6 @@ public class IncludableGzipFilter extends GzipFilter { return new DeflaterOutputStream(_response.getOutputStream(),new Deflater(_deflateCompressionLevel, _deflateNoWrap)); } - - @Override - protected void setHeader(String name, String value) - { - super.setHeader(name, value); - HttpServletResponse response = (HttpServletResponse)getResponse(); - if (!response.containsHeader(name)) - response.setHeader("org.eclipse.jetty.server.include." + name, value); - } }; } }; @@ -176,6 +149,16 @@ public class IncludableGzipFilter extends GzipFilter if (!response.containsHeader(name)) response.setHeader("org.eclipse.jetty.server.include."+name,value); } + + @Override + public void addHeader(String name, String value) + { + super.addHeader(name, value); + HttpServletResponse response = (HttpServletResponse)getResponse(); + if (!response.containsHeader(name)) + setHeader(name,value); + } + @Override protected PrintWriter newWriter(OutputStream out, String encoding) throws UnsupportedEncodingException {