diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocket.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocket.java index 958d6a8eaed..e4667f0a2a9 100644 --- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocket.java +++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocket.java @@ -112,6 +112,10 @@ public interface WebSocket void disconnect(); boolean isOpen(); + /* ------------------------------------------------------------ */ + /** + * @param ms The time in ms that the connection can be idle before closing + */ void setMaxIdleTime(int ms); /** @@ -124,6 +128,12 @@ public interface WebSocket */ void setMaxBinaryMessageSize(int size); + /* ------------------------------------------------------------ */ + /** + * @return The time in ms that the connection can be idle before closing + */ + int getMaxIdleTime(); + /** * Size in characters of the maximum text message to be received * @return size <0 No aggregation of frames to messages, >=0 max size of text frame aggregation buffer in characters diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD00.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD00.java index 0c2b2ee6423..445fd0dc6e7 100644 --- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD00.java +++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD00.java @@ -434,6 +434,11 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc return -1; } + public int getMaxIdleTime() + { + return _endp.getMaxIdleTime(); + } + public int getMaxBinaryMessageSize() { return -1; @@ -554,13 +559,10 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc public void setFakeFragments(boolean fake) { - // TODO Auto-generated method stub - } public boolean isFakeFragments() { - // TODO Auto-generated method stub return false; } } diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD06.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD06.java index a16a37057f6..74395a0a2f1 100644 --- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD06.java +++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD06.java @@ -418,6 +418,12 @@ public class WebSocketConnectionD06 extends AbstractConnection implements WebSoc return _maxTextMessage; } + /* ------------------------------------------------------------ */ + public int getMaxIdleTime() + { + return _endp.getMaxIdleTime(); + } + /* ------------------------------------------------------------ */ public int getMaxBinaryMessageSize() { diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD12.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD12.java index 908902ce2a2..d94ae7c6fc3 100644 --- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD12.java +++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD12.java @@ -95,10 +95,9 @@ public class WebSocketConnectionD12 extends AbstractConnection implements WebSoc private volatile String _closeMessage; private volatile boolean _closedIn; private volatile boolean _closedOut; - private int _maxTextMessageSize; + private int _maxTextMessageSize=-1; private int _maxBinaryMessageSize=-1; - static { try @@ -113,9 +112,6 @@ public class WebSocketConnectionD12 extends AbstractConnection implements WebSoc private final WebSocketParser.FrameHandler _frameHandler= new WSFrameHandler(); - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ private final WebSocket.FrameConnection _connection = new WSFrameConnection(); @@ -190,9 +186,6 @@ public class WebSocketConnectionD12 extends AbstractConnection implements WebSoc {} }; } - - _maxTextMessageSize=buffers.getBufferSize(); - _maxBinaryMessageSize=-1; } /* ------------------------------------------------------------ */ @@ -410,8 +403,6 @@ public class WebSocketConnectionD12 extends AbstractConnection implements WebSoc private class WSFrameConnection implements WebSocket.FrameConnection { volatile boolean _disconnecting; - int _maxTextMessage=WebSocketConnectionD12.this._maxTextMessageSize; - int _maxBinaryMessage=WebSocketConnectionD12.this._maxBinaryMessageSize; /* ------------------------------------------------------------ */ public void sendMessage(String content) throws IOException @@ -491,25 +482,31 @@ public class WebSocketConnectionD12 extends AbstractConnection implements WebSoc /* ------------------------------------------------------------ */ public void setMaxTextMessageSize(int size) { - _maxTextMessage=size; + _maxTextMessageSize=size; } /* ------------------------------------------------------------ */ public void setMaxBinaryMessageSize(int size) { - _maxBinaryMessage=size; + _maxBinaryMessageSize=size; } + /* ------------------------------------------------------------ */ + public int getMaxIdleTime() + { + return _endp.getMaxIdleTime(); + } + /* ------------------------------------------------------------ */ public int getMaxTextMessageSize() { - return _maxTextMessage; + return _maxTextMessageSize; } /* ------------------------------------------------------------ */ public int getMaxBinaryMessageSize() { - return _maxBinaryMessage; + return _maxBinaryMessageSize; } /* ------------------------------------------------------------ */ @@ -728,7 +725,13 @@ public class WebSocketConnectionD12 extends AbstractConnection implements WebSoc // No size limit, so handle only final frames if (lastFrame) _onTextMessage.onMessage(buffer.toString(StringUtil.__UTF8)); + else + { + LOG.warn("Frame discarded. Text aggregation disabed for {}",_endp); + _connection.close(WebSocketConnectionD12.CLOSE_BADDATA,"Text frame aggregation disabled"); + } } + // append bytes to message buffer (if they fit) else if (_utf8.append(buffer.array(),buffer.getIndex(),buffer.length(),_connection.getMaxTextMessageSize())) { if (lastFrame) @@ -764,6 +767,11 @@ public class WebSocketConnectionD12 extends AbstractConnection implements WebSoc _aggregate=new ByteArrayBuffer(_connection.getMaxBinaryMessageSize()); _aggregate.put(buffer); } + else + { + LOG.warn("Frame discarded. Binary aggregation disabed for {}",_endp); + _connection.close(WebSocketConnectionD12.CLOSE_BADDATA,"Binary frame aggregation disabled"); + } } } } diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketFactory.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketFactory.java index 04b3dcd824f..87bcc610cae 100644 --- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketFactory.java +++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketFactory.java @@ -68,6 +68,8 @@ public class WebSocketFactory private final Acceptor _acceptor; private WebSocketBuffers _buffers; private int _maxIdleTime = 300000; + private int _maxTextMessageSize = 16*1024; + private int _maxBinaryMessageSize = -1; public WebSocketFactory(Acceptor acceptor) { @@ -130,6 +132,42 @@ public class WebSocketFactory _buffers = new WebSocketBuffers(bufferSize); } + /** + * @return The initial maximum text message size (in characters) for a connection + */ + public int getMaxTextMessageSize() + { + return _maxTextMessageSize; + } + + /** + * Set the initial maximum text message size for a connection. This can be changed by + * the application calling {@link WebSocket.Connection#setMaxTextMessageSize(int)}. + * @param maxTextMessageSize The default maximum text message size (in characters) for a connection + */ + public void setMaxTextMessageSize(int maxTextMessageSize) + { + _maxTextMessageSize = maxTextMessageSize; + } + + /** + * @return The initial maximum binary message size (in bytes) for a connection + */ + public int getMaxBinaryMessageSize() + { + return _maxBinaryMessageSize; + } + + /** + * Set the initial maximum binary message size for a connection. This can be changed by + * the application calling {@link WebSocket.Connection#setMaxBinaryMessageSize(int)}. + * @param maxTextMessageSize The default maximum binary message size (in bytes) for a connection + */ + public void setMaxBinaryMessageSize(int maxBinaryMessageSize) + { + _maxBinaryMessageSize = maxBinaryMessageSize; + } + /** * Upgrade the request/response to a WebSocket Connection. *

This method will not normally return, but will instead throw a @@ -191,6 +229,10 @@ public class WebSocketFactory throw new HttpException(400, "Unsupported draft specification: " + draft); } + // Set the defaults + connection.getConnection().setMaxBinaryMessageSize(_maxBinaryMessageSize); + connection.getConnection().setMaxTextMessageSize(_maxTextMessageSize); + // Let the connection finish processing the handshake connection.handshake(request, response, protocol); response.flushBuffer(); diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketHandler.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketHandler.java index 870fd702018..eb0eefbc3b1 100644 --- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketHandler.java +++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketHandler.java @@ -24,70 +24,11 @@ import org.eclipse.jetty.server.handler.HandlerWrapper; public abstract class WebSocketHandler extends HandlerWrapper implements WebSocketFactory.Acceptor { - private WebSocketFactory _webSocketFactory; - private int _bufferSize=64*1024; - private int _maxIdleTime=-1; + private final WebSocketFactory _webSocketFactory=new WebSocketFactory(this,32*1024); - /* ------------------------------------------------------------ */ - /** Get the bufferSize. - * @return the bufferSize - */ - public int getBufferSize() + public WebSocketFactory getWebSocketFactory() { - return _bufferSize; - } - - /* ------------------------------------------------------------ */ - /** Set the bufferSize. - * @param bufferSize the bufferSize to set - */ - public void setBufferSize(int bufferSize) - { - _bufferSize = bufferSize; - } - - /* ------------------------------------------------------------ */ - /** Get the maxIdleTime. - * @return the maxIdleTime - */ - public int getMaxIdleTime() - { - return (int)(_webSocketFactory==null?_maxIdleTime:_webSocketFactory.getMaxIdleTime()); - } - - /* ------------------------------------------------------------ */ - /** Set the maxIdleTime. - * @param maxIdleTime the maxIdleTime to set - */ - public void setMaxIdleTime(int maxIdleTime) - { - _maxIdleTime = maxIdleTime; - if (_webSocketFactory!=null) - _webSocketFactory.setMaxIdleTime(maxIdleTime); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.server.handler.HandlerWrapper#doStart() - */ - @Override - protected void doStart() throws Exception - { - _webSocketFactory=new WebSocketFactory(this,_bufferSize); - if (_maxIdleTime>=0) - _webSocketFactory.setMaxIdleTime(_maxIdleTime); - super.doStart(); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.server.handler.HandlerWrapper#doStop() - */ - @Override - protected void doStop() throws Exception - { - super.doStop(); - _webSocketFactory=null; + return _webSocketFactory; } /* ------------------------------------------------------------ */ diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketServlet.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketServlet.java index b3e9ede719c..562c50cd871 100644 --- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketServlet.java +++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketServlet.java @@ -32,7 +32,13 @@ import javax.servlet.http.HttpServletResponse; * which is also the max frame byte size (default 8192). *

* The initParameter "maxIdleTime" can be used to set the time in ms - * that a websocket may be idle before closing (default 300,000). + * that a websocket may be idle before closing. + *

+ * The initParameter "maxTextMessagesSize" can be used to set the size in characters + * that a websocket may be accept before closing. + *

+ * The initParameter "maxBinaryMessagesSize" can be used to set the size in bytes + * that a websocket may be accept before closing. * */ public abstract class WebSocketServlet extends HttpServlet implements WebSocketFactory.Acceptor @@ -48,9 +54,18 @@ public abstract class WebSocketServlet extends HttpServlet implements WebSocketF { String bs=getInitParameter("bufferSize"); _webSocketFactory = new WebSocketFactory(this,bs==null?8192:Integer.parseInt(bs)); - String mit=getInitParameter("maxIdleTime"); - if (mit!=null) - _webSocketFactory.setMaxIdleTime(Integer.parseInt(mit)); + String max=getInitParameter("maxIdleTime"); + if (max!=null) + _webSocketFactory.setMaxIdleTime(Integer.parseInt(max)); + + max=getInitParameter("maxTextMessageSize"); + if (max!=null) + _webSocketFactory.setMaxTextMessageSize(Integer.parseInt(max)); + + max=getInitParameter("maxBinaryMessageSize"); + if (max!=null) + _webSocketFactory.setMaxBinaryMessageSize(Integer.parseInt(max)); + } /* ------------------------------------------------------------ */ diff --git a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageD06Test.java b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageD06Test.java index 1521f1a608b..f0e8a4c5ea1 100644 --- a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageD06Test.java +++ b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageD06Test.java @@ -53,8 +53,8 @@ public class WebSocketMessageD06Test return _serverWebSocket; } }; - wsHandler.setBufferSize(8192); - wsHandler.setMaxIdleTime(1000); + wsHandler.getWebSocketFactory().setBufferSize(8192); + wsHandler.getWebSocketFactory().setMaxIdleTime(1000); wsHandler.setHandler(new DefaultHandler()); _server.setHandler(wsHandler); _server.start(); diff --git a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageD12Test.java b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageD12Test.java index b687c8b2b41..917eff18d13 100644 --- a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageD12Test.java +++ b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageD12Test.java @@ -64,8 +64,8 @@ public class WebSocketMessageD12Test return __serverWebSocket; } }; - wsHandler.setBufferSize(8192); - wsHandler.setMaxIdleTime(1000); + wsHandler.getWebSocketFactory().setBufferSize(8192); + wsHandler.getWebSocketFactory().setMaxIdleTime(1000); wsHandler.setHandler(new DefaultHandler()); __server.setHandler(wsHandler); __server.start();