103928aee4356845252ac6b662d5c72c29903813eJake Slack// 203928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 303928aee4356845252ac6b662d5c72c29903813eJake Slack// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. 403928aee4356845252ac6b662d5c72c29903813eJake Slack// ------------------------------------------------------------------------ 503928aee4356845252ac6b662d5c72c29903813eJake Slack// All rights reserved. This program and the accompanying materials 603928aee4356845252ac6b662d5c72c29903813eJake Slack// are made available under the terms of the Eclipse Public License v1.0 703928aee4356845252ac6b662d5c72c29903813eJake Slack// and Apache License v2.0 which accompanies this distribution. 803928aee4356845252ac6b662d5c72c29903813eJake Slack// 903928aee4356845252ac6b662d5c72c29903813eJake Slack// The Eclipse Public License is available at 1003928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.eclipse.org/legal/epl-v10.html 1103928aee4356845252ac6b662d5c72c29903813eJake Slack// 1203928aee4356845252ac6b662d5c72c29903813eJake Slack// The Apache License v2.0 is available at 1303928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.opensource.org/licenses/apache2.0.php 1403928aee4356845252ac6b662d5c72c29903813eJake Slack// 1503928aee4356845252ac6b662d5c72c29903813eJake Slack// You may elect to redistribute this code under either of these licenses. 1603928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 1703928aee4356845252ac6b662d5c72c29903813eJake Slack// 1803928aee4356845252ac6b662d5c72c29903813eJake Slack 1903928aee4356845252ac6b662d5c72c29903813eJake Slackpackage org.eclipse.jetty.websocket; 2003928aee4356845252ac6b662d5c72c29903813eJake Slack 2103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.IOException; 2203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.UnsupportedEncodingException; 2303928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.security.MessageDigest; 2403928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Collections; 2503928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.List; 2603928aee4356845252ac6b662d5c72c29903813eJake Slack 2703928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.AbstractConnection; 2803928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.AsyncEndPoint; 2903928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.Buffer; 3003928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.ByteArrayBuffer; 3103928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.Connection; 3203928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.EndPoint; 3303928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.B64Code; 3403928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.StringUtil; 3503928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.Utf8StringBuilder; 3603928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Log; 3703928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Logger; 3803928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.websocket.WebSocket.OnBinaryMessage; 3903928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.websocket.WebSocket.OnControl; 4003928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.websocket.WebSocket.OnFrame; 4103928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.websocket.WebSocket.OnTextMessage; 4203928aee4356845252ac6b662d5c72c29903813eJake Slack 4303928aee4356845252ac6b662d5c72c29903813eJake Slackpublic class WebSocketConnectionD08 extends AbstractConnection implements WebSocketConnection 4403928aee4356845252ac6b662d5c72c29903813eJake Slack{ 4503928aee4356845252ac6b662d5c72c29903813eJake Slack private static final Logger LOG = Log.getLogger(WebSocketConnectionD08.class); 4603928aee4356845252ac6b662d5c72c29903813eJake Slack 4703928aee4356845252ac6b662d5c72c29903813eJake Slack final static byte OP_CONTINUATION = 0x00; 4803928aee4356845252ac6b662d5c72c29903813eJake Slack final static byte OP_TEXT = 0x01; 4903928aee4356845252ac6b662d5c72c29903813eJake Slack final static byte OP_BINARY = 0x02; 5003928aee4356845252ac6b662d5c72c29903813eJake Slack final static byte OP_EXT_DATA = 0x03; 5103928aee4356845252ac6b662d5c72c29903813eJake Slack 5203928aee4356845252ac6b662d5c72c29903813eJake Slack final static byte OP_CONTROL = 0x08; 5303928aee4356845252ac6b662d5c72c29903813eJake Slack final static byte OP_CLOSE = 0x08; 5403928aee4356845252ac6b662d5c72c29903813eJake Slack final static byte OP_PING = 0x09; 5503928aee4356845252ac6b662d5c72c29903813eJake Slack final static byte OP_PONG = 0x0A; 5603928aee4356845252ac6b662d5c72c29903813eJake Slack final static byte OP_EXT_CTRL = 0x0B; 5703928aee4356845252ac6b662d5c72c29903813eJake Slack 5803928aee4356845252ac6b662d5c72c29903813eJake Slack final static int CLOSE_NORMAL=1000; 5903928aee4356845252ac6b662d5c72c29903813eJake Slack final static int CLOSE_SHUTDOWN=1001; 6003928aee4356845252ac6b662d5c72c29903813eJake Slack final static int CLOSE_PROTOCOL=1002; 6103928aee4356845252ac6b662d5c72c29903813eJake Slack final static int CLOSE_BADDATA=1003; 6203928aee4356845252ac6b662d5c72c29903813eJake Slack final static int CLOSE_NOCODE=1005; 6303928aee4356845252ac6b662d5c72c29903813eJake Slack final static int CLOSE_NOCLOSE=1006; 6403928aee4356845252ac6b662d5c72c29903813eJake Slack final static int CLOSE_NOTUTF8=1007; 6503928aee4356845252ac6b662d5c72c29903813eJake Slack 6603928aee4356845252ac6b662d5c72c29903813eJake Slack final static int FLAG_FIN=0x8; 6703928aee4356845252ac6b662d5c72c29903813eJake Slack 6803928aee4356845252ac6b662d5c72c29903813eJake Slack final static int VERSION=8; 6903928aee4356845252ac6b662d5c72c29903813eJake Slack 7003928aee4356845252ac6b662d5c72c29903813eJake Slack static boolean isLastFrame(byte flags) 7103928aee4356845252ac6b662d5c72c29903813eJake Slack { 7203928aee4356845252ac6b662d5c72c29903813eJake Slack return (flags&FLAG_FIN)!=0; 7303928aee4356845252ac6b662d5c72c29903813eJake Slack } 7403928aee4356845252ac6b662d5c72c29903813eJake Slack 7503928aee4356845252ac6b662d5c72c29903813eJake Slack static boolean isControlFrame(byte opcode) 7603928aee4356845252ac6b662d5c72c29903813eJake Slack { 7703928aee4356845252ac6b662d5c72c29903813eJake Slack return (opcode&OP_CONTROL)!=0; 7803928aee4356845252ac6b662d5c72c29903813eJake Slack } 7903928aee4356845252ac6b662d5c72c29903813eJake Slack 8003928aee4356845252ac6b662d5c72c29903813eJake Slack private final static byte[] MAGIC; 8103928aee4356845252ac6b662d5c72c29903813eJake Slack private final List<Extension> _extensions; 8203928aee4356845252ac6b662d5c72c29903813eJake Slack private final WebSocketParserD08 _parser; 8303928aee4356845252ac6b662d5c72c29903813eJake Slack private final WebSocketGeneratorD08 _generator; 8403928aee4356845252ac6b662d5c72c29903813eJake Slack private final WebSocketGenerator _outbound; 8503928aee4356845252ac6b662d5c72c29903813eJake Slack private final WebSocket _webSocket; 8603928aee4356845252ac6b662d5c72c29903813eJake Slack private final OnFrame _onFrame; 8703928aee4356845252ac6b662d5c72c29903813eJake Slack private final OnBinaryMessage _onBinaryMessage; 8803928aee4356845252ac6b662d5c72c29903813eJake Slack private final OnTextMessage _onTextMessage; 8903928aee4356845252ac6b662d5c72c29903813eJake Slack private final OnControl _onControl; 9003928aee4356845252ac6b662d5c72c29903813eJake Slack private final String _protocol; 9103928aee4356845252ac6b662d5c72c29903813eJake Slack private final int _draft; 9203928aee4356845252ac6b662d5c72c29903813eJake Slack private final ClassLoader _context; 9303928aee4356845252ac6b662d5c72c29903813eJake Slack private volatile int _closeCode; 9403928aee4356845252ac6b662d5c72c29903813eJake Slack private volatile String _closeMessage; 9503928aee4356845252ac6b662d5c72c29903813eJake Slack private volatile boolean _closedIn; 9603928aee4356845252ac6b662d5c72c29903813eJake Slack private volatile boolean _closedOut; 9703928aee4356845252ac6b662d5c72c29903813eJake Slack private int _maxTextMessageSize=-1; 9803928aee4356845252ac6b662d5c72c29903813eJake Slack private int _maxBinaryMessageSize=-1; 9903928aee4356845252ac6b662d5c72c29903813eJake Slack 10003928aee4356845252ac6b662d5c72c29903813eJake Slack static 10103928aee4356845252ac6b662d5c72c29903813eJake Slack { 10203928aee4356845252ac6b662d5c72c29903813eJake Slack try 10303928aee4356845252ac6b662d5c72c29903813eJake Slack { 10403928aee4356845252ac6b662d5c72c29903813eJake Slack MAGIC="258EAFA5-E914-47DA-95CA-C5AB0DC85B11".getBytes(StringUtil.__ISO_8859_1); 10503928aee4356845252ac6b662d5c72c29903813eJake Slack } 10603928aee4356845252ac6b662d5c72c29903813eJake Slack catch (UnsupportedEncodingException e) 10703928aee4356845252ac6b662d5c72c29903813eJake Slack { 10803928aee4356845252ac6b662d5c72c29903813eJake Slack throw new RuntimeException(e); 10903928aee4356845252ac6b662d5c72c29903813eJake Slack } 11003928aee4356845252ac6b662d5c72c29903813eJake Slack } 11103928aee4356845252ac6b662d5c72c29903813eJake Slack 11203928aee4356845252ac6b662d5c72c29903813eJake Slack private final WebSocket.FrameConnection _connection = new WSFrameConnection(); 11303928aee4356845252ac6b662d5c72c29903813eJake Slack 11403928aee4356845252ac6b662d5c72c29903813eJake Slack 11503928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 11603928aee4356845252ac6b662d5c72c29903813eJake Slack public WebSocketConnectionD08(WebSocket websocket, EndPoint endpoint, WebSocketBuffers buffers, long timestamp, int maxIdleTime, String protocol, List<Extension> extensions,int draft) 11703928aee4356845252ac6b662d5c72c29903813eJake Slack throws IOException 11803928aee4356845252ac6b662d5c72c29903813eJake Slack { 11903928aee4356845252ac6b662d5c72c29903813eJake Slack this(websocket,endpoint,buffers,timestamp,maxIdleTime,protocol,extensions,draft,null); 12003928aee4356845252ac6b662d5c72c29903813eJake Slack } 12103928aee4356845252ac6b662d5c72c29903813eJake Slack 12203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 12303928aee4356845252ac6b662d5c72c29903813eJake Slack public WebSocketConnectionD08(WebSocket websocket, EndPoint endpoint, WebSocketBuffers buffers, long timestamp, int maxIdleTime, String protocol, List<Extension> extensions,int draft, MaskGen maskgen) 12403928aee4356845252ac6b662d5c72c29903813eJake Slack throws IOException 12503928aee4356845252ac6b662d5c72c29903813eJake Slack { 12603928aee4356845252ac6b662d5c72c29903813eJake Slack super(endpoint,timestamp); 12703928aee4356845252ac6b662d5c72c29903813eJake Slack 12803928aee4356845252ac6b662d5c72c29903813eJake Slack _context=Thread.currentThread().getContextClassLoader(); 12903928aee4356845252ac6b662d5c72c29903813eJake Slack 13003928aee4356845252ac6b662d5c72c29903813eJake Slack _draft=draft; 13103928aee4356845252ac6b662d5c72c29903813eJake Slack _endp.setMaxIdleTime(maxIdleTime); 13203928aee4356845252ac6b662d5c72c29903813eJake Slack 13303928aee4356845252ac6b662d5c72c29903813eJake Slack _webSocket = websocket; 13403928aee4356845252ac6b662d5c72c29903813eJake Slack _onFrame=_webSocket instanceof OnFrame ? (OnFrame)_webSocket : null; 13503928aee4356845252ac6b662d5c72c29903813eJake Slack _onTextMessage=_webSocket instanceof OnTextMessage ? (OnTextMessage)_webSocket : null; 13603928aee4356845252ac6b662d5c72c29903813eJake Slack _onBinaryMessage=_webSocket instanceof OnBinaryMessage ? (OnBinaryMessage)_webSocket : null; 13703928aee4356845252ac6b662d5c72c29903813eJake Slack _onControl=_webSocket instanceof OnControl ? (OnControl)_webSocket : null; 13803928aee4356845252ac6b662d5c72c29903813eJake Slack _generator = new WebSocketGeneratorD08(buffers, _endp,maskgen); 13903928aee4356845252ac6b662d5c72c29903813eJake Slack 14003928aee4356845252ac6b662d5c72c29903813eJake Slack _extensions=extensions; 14103928aee4356845252ac6b662d5c72c29903813eJake Slack WebSocketParser.FrameHandler _frameHandler= new WSFrameHandler(); 14203928aee4356845252ac6b662d5c72c29903813eJake Slack if (_extensions!=null) 14303928aee4356845252ac6b662d5c72c29903813eJake Slack { 14403928aee4356845252ac6b662d5c72c29903813eJake Slack int e=0; 14503928aee4356845252ac6b662d5c72c29903813eJake Slack for (Extension extension : _extensions) 14603928aee4356845252ac6b662d5c72c29903813eJake Slack { 14703928aee4356845252ac6b662d5c72c29903813eJake Slack extension.bind( 14803928aee4356845252ac6b662d5c72c29903813eJake Slack _connection, 14903928aee4356845252ac6b662d5c72c29903813eJake Slack e==extensions.size()-1?_frameHandler:extensions.get(e+1), 15003928aee4356845252ac6b662d5c72c29903813eJake Slack e==0?_generator:extensions.get(e-1)); 15103928aee4356845252ac6b662d5c72c29903813eJake Slack e++; 15203928aee4356845252ac6b662d5c72c29903813eJake Slack } 15303928aee4356845252ac6b662d5c72c29903813eJake Slack } 15403928aee4356845252ac6b662d5c72c29903813eJake Slack 15503928aee4356845252ac6b662d5c72c29903813eJake Slack _outbound=(_extensions==null||_extensions.size()==0)?_generator:extensions.get(extensions.size()-1); 15603928aee4356845252ac6b662d5c72c29903813eJake Slack WebSocketParser.FrameHandler _inbound=(_extensions==null||_extensions.size()==0)?_frameHandler:extensions.get(0); 15703928aee4356845252ac6b662d5c72c29903813eJake Slack 15803928aee4356845252ac6b662d5c72c29903813eJake Slack _parser = new WebSocketParserD08(buffers, endpoint,_inbound,maskgen==null); 15903928aee4356845252ac6b662d5c72c29903813eJake Slack 16003928aee4356845252ac6b662d5c72c29903813eJake Slack _protocol=protocol; 16103928aee4356845252ac6b662d5c72c29903813eJake Slack 16203928aee4356845252ac6b662d5c72c29903813eJake Slack } 16303928aee4356845252ac6b662d5c72c29903813eJake Slack 16403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 16503928aee4356845252ac6b662d5c72c29903813eJake Slack public WebSocket.Connection getConnection() 16603928aee4356845252ac6b662d5c72c29903813eJake Slack { 16703928aee4356845252ac6b662d5c72c29903813eJake Slack return _connection; 16803928aee4356845252ac6b662d5c72c29903813eJake Slack } 16903928aee4356845252ac6b662d5c72c29903813eJake Slack 17003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 17103928aee4356845252ac6b662d5c72c29903813eJake Slack public List<Extension> getExtensions() 17203928aee4356845252ac6b662d5c72c29903813eJake Slack { 17303928aee4356845252ac6b662d5c72c29903813eJake Slack if (_extensions==null) 17403928aee4356845252ac6b662d5c72c29903813eJake Slack return Collections.emptyList(); 17503928aee4356845252ac6b662d5c72c29903813eJake Slack 17603928aee4356845252ac6b662d5c72c29903813eJake Slack return _extensions; 17703928aee4356845252ac6b662d5c72c29903813eJake Slack } 17803928aee4356845252ac6b662d5c72c29903813eJake Slack 17903928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 18003928aee4356845252ac6b662d5c72c29903813eJake Slack public Connection handle() throws IOException 18103928aee4356845252ac6b662d5c72c29903813eJake Slack { 18203928aee4356845252ac6b662d5c72c29903813eJake Slack Thread current = Thread.currentThread(); 18303928aee4356845252ac6b662d5c72c29903813eJake Slack ClassLoader oldcontext = current.getContextClassLoader(); 18403928aee4356845252ac6b662d5c72c29903813eJake Slack current.setContextClassLoader(_context); 18503928aee4356845252ac6b662d5c72c29903813eJake Slack try 18603928aee4356845252ac6b662d5c72c29903813eJake Slack { 18703928aee4356845252ac6b662d5c72c29903813eJake Slack // handle the framing protocol 18803928aee4356845252ac6b662d5c72c29903813eJake Slack boolean progress=true; 18903928aee4356845252ac6b662d5c72c29903813eJake Slack 19003928aee4356845252ac6b662d5c72c29903813eJake Slack while (progress) 19103928aee4356845252ac6b662d5c72c29903813eJake Slack { 19203928aee4356845252ac6b662d5c72c29903813eJake Slack int flushed=_generator.flushBuffer(); 19303928aee4356845252ac6b662d5c72c29903813eJake Slack int filled=_parser.parseNext(); 19403928aee4356845252ac6b662d5c72c29903813eJake Slack 19503928aee4356845252ac6b662d5c72c29903813eJake Slack progress = flushed>0 || filled>0; 19603928aee4356845252ac6b662d5c72c29903813eJake Slack _endp.flush(); 19703928aee4356845252ac6b662d5c72c29903813eJake Slack 19803928aee4356845252ac6b662d5c72c29903813eJake Slack if (_endp instanceof AsyncEndPoint && ((AsyncEndPoint)_endp).hasProgressed()) 19903928aee4356845252ac6b662d5c72c29903813eJake Slack progress=true; 20003928aee4356845252ac6b662d5c72c29903813eJake Slack } 20103928aee4356845252ac6b662d5c72c29903813eJake Slack } 20203928aee4356845252ac6b662d5c72c29903813eJake Slack catch(IOException e) 20303928aee4356845252ac6b662d5c72c29903813eJake Slack { 20403928aee4356845252ac6b662d5c72c29903813eJake Slack try 20503928aee4356845252ac6b662d5c72c29903813eJake Slack { 20603928aee4356845252ac6b662d5c72c29903813eJake Slack if (_endp.isOpen()) 20703928aee4356845252ac6b662d5c72c29903813eJake Slack _endp.close(); 20803928aee4356845252ac6b662d5c72c29903813eJake Slack } 20903928aee4356845252ac6b662d5c72c29903813eJake Slack catch(IOException e2) 21003928aee4356845252ac6b662d5c72c29903813eJake Slack { 21103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e2); 21203928aee4356845252ac6b662d5c72c29903813eJake Slack } 21303928aee4356845252ac6b662d5c72c29903813eJake Slack throw e; 21403928aee4356845252ac6b662d5c72c29903813eJake Slack } 21503928aee4356845252ac6b662d5c72c29903813eJake Slack finally 21603928aee4356845252ac6b662d5c72c29903813eJake Slack { 21703928aee4356845252ac6b662d5c72c29903813eJake Slack current.setContextClassLoader(oldcontext); 21803928aee4356845252ac6b662d5c72c29903813eJake Slack _parser.returnBuffer(); 21903928aee4356845252ac6b662d5c72c29903813eJake Slack _generator.returnBuffer(); 22003928aee4356845252ac6b662d5c72c29903813eJake Slack if (_endp.isOpen()) 22103928aee4356845252ac6b662d5c72c29903813eJake Slack { 22203928aee4356845252ac6b662d5c72c29903813eJake Slack if (_closedIn && _closedOut && _outbound.isBufferEmpty()) 22303928aee4356845252ac6b662d5c72c29903813eJake Slack _endp.close(); 22403928aee4356845252ac6b662d5c72c29903813eJake Slack else if (_endp.isInputShutdown() && !_closedIn) 22503928aee4356845252ac6b662d5c72c29903813eJake Slack closeIn(CLOSE_NOCLOSE,null); 22603928aee4356845252ac6b662d5c72c29903813eJake Slack else 22703928aee4356845252ac6b662d5c72c29903813eJake Slack checkWriteable(); 22803928aee4356845252ac6b662d5c72c29903813eJake Slack } 22903928aee4356845252ac6b662d5c72c29903813eJake Slack } 23003928aee4356845252ac6b662d5c72c29903813eJake Slack return this; 23103928aee4356845252ac6b662d5c72c29903813eJake Slack } 23203928aee4356845252ac6b662d5c72c29903813eJake Slack 23303928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 23403928aee4356845252ac6b662d5c72c29903813eJake Slack public void onInputShutdown() throws IOException 23503928aee4356845252ac6b662d5c72c29903813eJake Slack { 23603928aee4356845252ac6b662d5c72c29903813eJake Slack if (!_closedIn) 23703928aee4356845252ac6b662d5c72c29903813eJake Slack _endp.close(); 23803928aee4356845252ac6b662d5c72c29903813eJake Slack } 23903928aee4356845252ac6b662d5c72c29903813eJake Slack 24003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 24103928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isIdle() 24203928aee4356845252ac6b662d5c72c29903813eJake Slack { 24303928aee4356845252ac6b662d5c72c29903813eJake Slack return _parser.isBufferEmpty() && _outbound.isBufferEmpty(); 24403928aee4356845252ac6b662d5c72c29903813eJake Slack } 24503928aee4356845252ac6b662d5c72c29903813eJake Slack 24603928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 24703928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 24803928aee4356845252ac6b662d5c72c29903813eJake Slack public void onIdleExpired(long idleForMs) 24903928aee4356845252ac6b662d5c72c29903813eJake Slack { 25003928aee4356845252ac6b662d5c72c29903813eJake Slack closeOut(WebSocketConnectionD08.CLOSE_NORMAL,"Idle for "+idleForMs+"ms > "+_endp.getMaxIdleTime()+"ms"); 25103928aee4356845252ac6b662d5c72c29903813eJake Slack } 25203928aee4356845252ac6b662d5c72c29903813eJake Slack 25303928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 25403928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isSuspended() 25503928aee4356845252ac6b662d5c72c29903813eJake Slack { 25603928aee4356845252ac6b662d5c72c29903813eJake Slack return false; 25703928aee4356845252ac6b662d5c72c29903813eJake Slack } 25803928aee4356845252ac6b662d5c72c29903813eJake Slack 25903928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 26003928aee4356845252ac6b662d5c72c29903813eJake Slack public void onClose() 26103928aee4356845252ac6b662d5c72c29903813eJake Slack { 26203928aee4356845252ac6b662d5c72c29903813eJake Slack final boolean closed; 26303928aee4356845252ac6b662d5c72c29903813eJake Slack synchronized (this) 26403928aee4356845252ac6b662d5c72c29903813eJake Slack { 26503928aee4356845252ac6b662d5c72c29903813eJake Slack closed=_closeCode==0; 26603928aee4356845252ac6b662d5c72c29903813eJake Slack if (closed) 26703928aee4356845252ac6b662d5c72c29903813eJake Slack _closeCode=WebSocketConnectionD08.CLOSE_NOCLOSE; 26803928aee4356845252ac6b662d5c72c29903813eJake Slack } 26903928aee4356845252ac6b662d5c72c29903813eJake Slack if (closed) 27003928aee4356845252ac6b662d5c72c29903813eJake Slack _webSocket.onClose(WebSocketConnectionD08.CLOSE_NOCLOSE,"closed"); 27103928aee4356845252ac6b662d5c72c29903813eJake Slack } 27203928aee4356845252ac6b662d5c72c29903813eJake Slack 27303928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 27403928aee4356845252ac6b662d5c72c29903813eJake Slack public void closeIn(int code,String message) 27503928aee4356845252ac6b662d5c72c29903813eJake Slack { 27603928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("ClosedIn {} {} {}",this,code,message); 27703928aee4356845252ac6b662d5c72c29903813eJake Slack 27803928aee4356845252ac6b662d5c72c29903813eJake Slack final boolean closed_out; 27903928aee4356845252ac6b662d5c72c29903813eJake Slack final boolean tell_app; 28003928aee4356845252ac6b662d5c72c29903813eJake Slack synchronized (this) 28103928aee4356845252ac6b662d5c72c29903813eJake Slack { 28203928aee4356845252ac6b662d5c72c29903813eJake Slack closed_out=_closedOut; 28303928aee4356845252ac6b662d5c72c29903813eJake Slack _closedIn=true; 28403928aee4356845252ac6b662d5c72c29903813eJake Slack tell_app=_closeCode==0; 28503928aee4356845252ac6b662d5c72c29903813eJake Slack if (tell_app) 28603928aee4356845252ac6b662d5c72c29903813eJake Slack { 28703928aee4356845252ac6b662d5c72c29903813eJake Slack _closeCode=code; 28803928aee4356845252ac6b662d5c72c29903813eJake Slack _closeMessage=message; 28903928aee4356845252ac6b662d5c72c29903813eJake Slack } 29003928aee4356845252ac6b662d5c72c29903813eJake Slack } 29103928aee4356845252ac6b662d5c72c29903813eJake Slack 29203928aee4356845252ac6b662d5c72c29903813eJake Slack try 29303928aee4356845252ac6b662d5c72c29903813eJake Slack { 29403928aee4356845252ac6b662d5c72c29903813eJake Slack if (!closed_out) 29503928aee4356845252ac6b662d5c72c29903813eJake Slack closeOut(code,message); 29603928aee4356845252ac6b662d5c72c29903813eJake Slack } 29703928aee4356845252ac6b662d5c72c29903813eJake Slack finally 29803928aee4356845252ac6b662d5c72c29903813eJake Slack { 29903928aee4356845252ac6b662d5c72c29903813eJake Slack if (tell_app) 30003928aee4356845252ac6b662d5c72c29903813eJake Slack _webSocket.onClose(code,message); 30103928aee4356845252ac6b662d5c72c29903813eJake Slack } 30203928aee4356845252ac6b662d5c72c29903813eJake Slack } 30303928aee4356845252ac6b662d5c72c29903813eJake Slack 30403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 30503928aee4356845252ac6b662d5c72c29903813eJake Slack public void closeOut(int code,String message) 30603928aee4356845252ac6b662d5c72c29903813eJake Slack { 30703928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("ClosedOut {} {} {}",this,code,message); 30803928aee4356845252ac6b662d5c72c29903813eJake Slack 30903928aee4356845252ac6b662d5c72c29903813eJake Slack final boolean closed_out; 31003928aee4356845252ac6b662d5c72c29903813eJake Slack final boolean tell_app; 31103928aee4356845252ac6b662d5c72c29903813eJake Slack synchronized (this) 31203928aee4356845252ac6b662d5c72c29903813eJake Slack { 31303928aee4356845252ac6b662d5c72c29903813eJake Slack closed_out=_closedOut; 31403928aee4356845252ac6b662d5c72c29903813eJake Slack _closedOut=true; 31503928aee4356845252ac6b662d5c72c29903813eJake Slack tell_app=_closeCode==0; 31603928aee4356845252ac6b662d5c72c29903813eJake Slack if (tell_app) 31703928aee4356845252ac6b662d5c72c29903813eJake Slack { 31803928aee4356845252ac6b662d5c72c29903813eJake Slack _closeCode=code; 31903928aee4356845252ac6b662d5c72c29903813eJake Slack _closeMessage=message; 32003928aee4356845252ac6b662d5c72c29903813eJake Slack } 32103928aee4356845252ac6b662d5c72c29903813eJake Slack } 32203928aee4356845252ac6b662d5c72c29903813eJake Slack 32303928aee4356845252ac6b662d5c72c29903813eJake Slack try 32403928aee4356845252ac6b662d5c72c29903813eJake Slack { 32503928aee4356845252ac6b662d5c72c29903813eJake Slack if (tell_app) 32603928aee4356845252ac6b662d5c72c29903813eJake Slack _webSocket.onClose(code,message); 32703928aee4356845252ac6b662d5c72c29903813eJake Slack } 32803928aee4356845252ac6b662d5c72c29903813eJake Slack finally 32903928aee4356845252ac6b662d5c72c29903813eJake Slack { 33003928aee4356845252ac6b662d5c72c29903813eJake Slack try 33103928aee4356845252ac6b662d5c72c29903813eJake Slack { 33203928aee4356845252ac6b662d5c72c29903813eJake Slack if (!closed_out) 33303928aee4356845252ac6b662d5c72c29903813eJake Slack { 33403928aee4356845252ac6b662d5c72c29903813eJake Slack if (code<=0) 33503928aee4356845252ac6b662d5c72c29903813eJake Slack code=WebSocketConnectionD08.CLOSE_NORMAL; 33603928aee4356845252ac6b662d5c72c29903813eJake Slack byte[] bytes = ("xx"+(message==null?"":message)).getBytes(StringUtil.__ISO_8859_1); 33703928aee4356845252ac6b662d5c72c29903813eJake Slack bytes[0]=(byte)(code/0x100); 33803928aee4356845252ac6b662d5c72c29903813eJake Slack bytes[1]=(byte)(code%0x100); 33903928aee4356845252ac6b662d5c72c29903813eJake Slack _outbound.addFrame((byte)FLAG_FIN,WebSocketConnectionD08.OP_CLOSE,bytes,0,bytes.length); 34003928aee4356845252ac6b662d5c72c29903813eJake Slack } 34103928aee4356845252ac6b662d5c72c29903813eJake Slack _outbound.flush(); 34203928aee4356845252ac6b662d5c72c29903813eJake Slack 34303928aee4356845252ac6b662d5c72c29903813eJake Slack } 34403928aee4356845252ac6b662d5c72c29903813eJake Slack catch(IOException e) 34503928aee4356845252ac6b662d5c72c29903813eJake Slack { 34603928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 34703928aee4356845252ac6b662d5c72c29903813eJake Slack } 34803928aee4356845252ac6b662d5c72c29903813eJake Slack } 34903928aee4356845252ac6b662d5c72c29903813eJake Slack } 35003928aee4356845252ac6b662d5c72c29903813eJake Slack 35103928aee4356845252ac6b662d5c72c29903813eJake Slack public void shutdown() 35203928aee4356845252ac6b662d5c72c29903813eJake Slack { 35303928aee4356845252ac6b662d5c72c29903813eJake Slack final WebSocket.Connection connection = _connection; 35403928aee4356845252ac6b662d5c72c29903813eJake Slack if (connection != null) 35503928aee4356845252ac6b662d5c72c29903813eJake Slack connection.close(CLOSE_SHUTDOWN, null); 35603928aee4356845252ac6b662d5c72c29903813eJake Slack } 35703928aee4356845252ac6b662d5c72c29903813eJake Slack 35803928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 35903928aee4356845252ac6b662d5c72c29903813eJake Slack public void fillBuffersFrom(Buffer buffer) 36003928aee4356845252ac6b662d5c72c29903813eJake Slack { 36103928aee4356845252ac6b662d5c72c29903813eJake Slack _parser.fill(buffer); 36203928aee4356845252ac6b662d5c72c29903813eJake Slack } 36303928aee4356845252ac6b662d5c72c29903813eJake Slack 36403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 36503928aee4356845252ac6b662d5c72c29903813eJake Slack private void checkWriteable() 36603928aee4356845252ac6b662d5c72c29903813eJake Slack { 36703928aee4356845252ac6b662d5c72c29903813eJake Slack if (!_outbound.isBufferEmpty() && _endp instanceof AsyncEndPoint) 36803928aee4356845252ac6b662d5c72c29903813eJake Slack { 36903928aee4356845252ac6b662d5c72c29903813eJake Slack ((AsyncEndPoint)_endp).scheduleWrite(); 37003928aee4356845252ac6b662d5c72c29903813eJake Slack } 37103928aee4356845252ac6b662d5c72c29903813eJake Slack } 37203928aee4356845252ac6b662d5c72c29903813eJake Slack 37303928aee4356845252ac6b662d5c72c29903813eJake Slack protected void onFrameHandshake() 37403928aee4356845252ac6b662d5c72c29903813eJake Slack { 37503928aee4356845252ac6b662d5c72c29903813eJake Slack if (_onFrame != null) 37603928aee4356845252ac6b662d5c72c29903813eJake Slack { 37703928aee4356845252ac6b662d5c72c29903813eJake Slack _onFrame.onHandshake(_connection); 37803928aee4356845252ac6b662d5c72c29903813eJake Slack } 37903928aee4356845252ac6b662d5c72c29903813eJake Slack } 38003928aee4356845252ac6b662d5c72c29903813eJake Slack 38103928aee4356845252ac6b662d5c72c29903813eJake Slack protected void onWebSocketOpen() 38203928aee4356845252ac6b662d5c72c29903813eJake Slack { 38303928aee4356845252ac6b662d5c72c29903813eJake Slack _webSocket.onOpen(_connection); 38403928aee4356845252ac6b662d5c72c29903813eJake Slack } 38503928aee4356845252ac6b662d5c72c29903813eJake Slack 38603928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 38703928aee4356845252ac6b662d5c72c29903813eJake Slack private class WSFrameConnection implements WebSocket.FrameConnection 38803928aee4356845252ac6b662d5c72c29903813eJake Slack { 38903928aee4356845252ac6b662d5c72c29903813eJake Slack private volatile boolean _disconnecting; 39003928aee4356845252ac6b662d5c72c29903813eJake Slack 39103928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 39203928aee4356845252ac6b662d5c72c29903813eJake Slack public void sendMessage(String content) throws IOException 39303928aee4356845252ac6b662d5c72c29903813eJake Slack { 39403928aee4356845252ac6b662d5c72c29903813eJake Slack if (_closedOut) 39503928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IOException("closedOut "+_closeCode+":"+_closeMessage); 39603928aee4356845252ac6b662d5c72c29903813eJake Slack byte[] data = content.getBytes(StringUtil.__UTF8); 39703928aee4356845252ac6b662d5c72c29903813eJake Slack _outbound.addFrame((byte)FLAG_FIN,WebSocketConnectionD08.OP_TEXT,data,0,data.length); 39803928aee4356845252ac6b662d5c72c29903813eJake Slack checkWriteable(); 39903928aee4356845252ac6b662d5c72c29903813eJake Slack } 40003928aee4356845252ac6b662d5c72c29903813eJake Slack 40103928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 40203928aee4356845252ac6b662d5c72c29903813eJake Slack public void sendMessage(byte[] content, int offset, int length) throws IOException 40303928aee4356845252ac6b662d5c72c29903813eJake Slack { 40403928aee4356845252ac6b662d5c72c29903813eJake Slack if (_closedOut) 40503928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IOException("closedOut "+_closeCode+":"+_closeMessage); 40603928aee4356845252ac6b662d5c72c29903813eJake Slack _outbound.addFrame((byte)FLAG_FIN,WebSocketConnectionD08.OP_BINARY,content,offset,length); 40703928aee4356845252ac6b662d5c72c29903813eJake Slack checkWriteable(); 40803928aee4356845252ac6b662d5c72c29903813eJake Slack } 40903928aee4356845252ac6b662d5c72c29903813eJake Slack 41003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 41103928aee4356845252ac6b662d5c72c29903813eJake Slack public void sendFrame(byte flags,byte opcode, byte[] content, int offset, int length) throws IOException 41203928aee4356845252ac6b662d5c72c29903813eJake Slack { 41303928aee4356845252ac6b662d5c72c29903813eJake Slack if (_closedOut) 41403928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IOException("closedOut "+_closeCode+":"+_closeMessage); 41503928aee4356845252ac6b662d5c72c29903813eJake Slack _outbound.addFrame(flags,opcode,content,offset,length); 41603928aee4356845252ac6b662d5c72c29903813eJake Slack checkWriteable(); 41703928aee4356845252ac6b662d5c72c29903813eJake Slack } 41803928aee4356845252ac6b662d5c72c29903813eJake Slack 41903928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 42003928aee4356845252ac6b662d5c72c29903813eJake Slack public void sendControl(byte ctrl, byte[] data, int offset, int length) throws IOException 42103928aee4356845252ac6b662d5c72c29903813eJake Slack { 42203928aee4356845252ac6b662d5c72c29903813eJake Slack if (_closedOut) 42303928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IOException("closedOut "+_closeCode+":"+_closeMessage); 42403928aee4356845252ac6b662d5c72c29903813eJake Slack _outbound.addFrame((byte)FLAG_FIN,ctrl,data,offset,length); 42503928aee4356845252ac6b662d5c72c29903813eJake Slack checkWriteable(); 42603928aee4356845252ac6b662d5c72c29903813eJake Slack } 42703928aee4356845252ac6b662d5c72c29903813eJake Slack 42803928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 42903928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isMessageComplete(byte flags) 43003928aee4356845252ac6b662d5c72c29903813eJake Slack { 43103928aee4356845252ac6b662d5c72c29903813eJake Slack return isLastFrame(flags); 43203928aee4356845252ac6b662d5c72c29903813eJake Slack } 43303928aee4356845252ac6b662d5c72c29903813eJake Slack 43403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 43503928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isOpen() 43603928aee4356845252ac6b662d5c72c29903813eJake Slack { 43703928aee4356845252ac6b662d5c72c29903813eJake Slack return _endp!=null&&_endp.isOpen(); 43803928aee4356845252ac6b662d5c72c29903813eJake Slack } 43903928aee4356845252ac6b662d5c72c29903813eJake Slack 44003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 44103928aee4356845252ac6b662d5c72c29903813eJake Slack public void close(int code, String message) 44203928aee4356845252ac6b662d5c72c29903813eJake Slack { 44303928aee4356845252ac6b662d5c72c29903813eJake Slack if (_disconnecting) 44403928aee4356845252ac6b662d5c72c29903813eJake Slack return; 44503928aee4356845252ac6b662d5c72c29903813eJake Slack _disconnecting=true; 44603928aee4356845252ac6b662d5c72c29903813eJake Slack WebSocketConnectionD08.this.closeOut(code,message); 44703928aee4356845252ac6b662d5c72c29903813eJake Slack } 44803928aee4356845252ac6b662d5c72c29903813eJake Slack 44903928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 45003928aee4356845252ac6b662d5c72c29903813eJake Slack public void setMaxIdleTime(int ms) 45103928aee4356845252ac6b662d5c72c29903813eJake Slack { 45203928aee4356845252ac6b662d5c72c29903813eJake Slack try 45303928aee4356845252ac6b662d5c72c29903813eJake Slack { 45403928aee4356845252ac6b662d5c72c29903813eJake Slack _endp.setMaxIdleTime(ms); 45503928aee4356845252ac6b662d5c72c29903813eJake Slack } 45603928aee4356845252ac6b662d5c72c29903813eJake Slack catch(IOException e) 45703928aee4356845252ac6b662d5c72c29903813eJake Slack { 45803928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(e); 45903928aee4356845252ac6b662d5c72c29903813eJake Slack } 46003928aee4356845252ac6b662d5c72c29903813eJake Slack } 46103928aee4356845252ac6b662d5c72c29903813eJake Slack 46203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 46303928aee4356845252ac6b662d5c72c29903813eJake Slack public void setMaxTextMessageSize(int size) 46403928aee4356845252ac6b662d5c72c29903813eJake Slack { 46503928aee4356845252ac6b662d5c72c29903813eJake Slack _maxTextMessageSize=size; 46603928aee4356845252ac6b662d5c72c29903813eJake Slack } 46703928aee4356845252ac6b662d5c72c29903813eJake Slack 46803928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 46903928aee4356845252ac6b662d5c72c29903813eJake Slack public void setMaxBinaryMessageSize(int size) 47003928aee4356845252ac6b662d5c72c29903813eJake Slack { 47103928aee4356845252ac6b662d5c72c29903813eJake Slack _maxBinaryMessageSize=size; 47203928aee4356845252ac6b662d5c72c29903813eJake Slack } 47303928aee4356845252ac6b662d5c72c29903813eJake Slack 47403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 47503928aee4356845252ac6b662d5c72c29903813eJake Slack public int getMaxIdleTime() 47603928aee4356845252ac6b662d5c72c29903813eJake Slack { 47703928aee4356845252ac6b662d5c72c29903813eJake Slack return _endp.getMaxIdleTime(); 47803928aee4356845252ac6b662d5c72c29903813eJake Slack } 47903928aee4356845252ac6b662d5c72c29903813eJake Slack 48003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 48103928aee4356845252ac6b662d5c72c29903813eJake Slack public int getMaxTextMessageSize() 48203928aee4356845252ac6b662d5c72c29903813eJake Slack { 48303928aee4356845252ac6b662d5c72c29903813eJake Slack return _maxTextMessageSize; 48403928aee4356845252ac6b662d5c72c29903813eJake Slack } 48503928aee4356845252ac6b662d5c72c29903813eJake Slack 48603928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 48703928aee4356845252ac6b662d5c72c29903813eJake Slack public int getMaxBinaryMessageSize() 48803928aee4356845252ac6b662d5c72c29903813eJake Slack { 48903928aee4356845252ac6b662d5c72c29903813eJake Slack return _maxBinaryMessageSize; 49003928aee4356845252ac6b662d5c72c29903813eJake Slack } 49103928aee4356845252ac6b662d5c72c29903813eJake Slack 49203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 49303928aee4356845252ac6b662d5c72c29903813eJake Slack public String getProtocol() 49403928aee4356845252ac6b662d5c72c29903813eJake Slack { 49503928aee4356845252ac6b662d5c72c29903813eJake Slack return _protocol; 49603928aee4356845252ac6b662d5c72c29903813eJake Slack } 49703928aee4356845252ac6b662d5c72c29903813eJake Slack 49803928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 49903928aee4356845252ac6b662d5c72c29903813eJake Slack public byte binaryOpcode() 50003928aee4356845252ac6b662d5c72c29903813eJake Slack { 50103928aee4356845252ac6b662d5c72c29903813eJake Slack return OP_BINARY; 50203928aee4356845252ac6b662d5c72c29903813eJake Slack } 50303928aee4356845252ac6b662d5c72c29903813eJake Slack 50403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 50503928aee4356845252ac6b662d5c72c29903813eJake Slack public byte textOpcode() 50603928aee4356845252ac6b662d5c72c29903813eJake Slack { 50703928aee4356845252ac6b662d5c72c29903813eJake Slack return OP_TEXT; 50803928aee4356845252ac6b662d5c72c29903813eJake Slack } 50903928aee4356845252ac6b662d5c72c29903813eJake Slack 51003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 51103928aee4356845252ac6b662d5c72c29903813eJake Slack public byte continuationOpcode() 51203928aee4356845252ac6b662d5c72c29903813eJake Slack { 51303928aee4356845252ac6b662d5c72c29903813eJake Slack return OP_CONTINUATION; 51403928aee4356845252ac6b662d5c72c29903813eJake Slack } 51503928aee4356845252ac6b662d5c72c29903813eJake Slack 51603928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 51703928aee4356845252ac6b662d5c72c29903813eJake Slack public byte finMask() 51803928aee4356845252ac6b662d5c72c29903813eJake Slack { 51903928aee4356845252ac6b662d5c72c29903813eJake Slack return FLAG_FIN; 52003928aee4356845252ac6b662d5c72c29903813eJake Slack } 52103928aee4356845252ac6b662d5c72c29903813eJake Slack 52203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 52303928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isControl(byte opcode) 52403928aee4356845252ac6b662d5c72c29903813eJake Slack { 52503928aee4356845252ac6b662d5c72c29903813eJake Slack return isControlFrame(opcode); 52603928aee4356845252ac6b662d5c72c29903813eJake Slack } 52703928aee4356845252ac6b662d5c72c29903813eJake Slack 52803928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 52903928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isText(byte opcode) 53003928aee4356845252ac6b662d5c72c29903813eJake Slack { 53103928aee4356845252ac6b662d5c72c29903813eJake Slack return opcode==OP_TEXT; 53203928aee4356845252ac6b662d5c72c29903813eJake Slack } 53303928aee4356845252ac6b662d5c72c29903813eJake Slack 53403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 53503928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isBinary(byte opcode) 53603928aee4356845252ac6b662d5c72c29903813eJake Slack { 53703928aee4356845252ac6b662d5c72c29903813eJake Slack return opcode==OP_BINARY; 53803928aee4356845252ac6b662d5c72c29903813eJake Slack } 53903928aee4356845252ac6b662d5c72c29903813eJake Slack 54003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 54103928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isContinuation(byte opcode) 54203928aee4356845252ac6b662d5c72c29903813eJake Slack { 54303928aee4356845252ac6b662d5c72c29903813eJake Slack return opcode==OP_CONTINUATION; 54403928aee4356845252ac6b662d5c72c29903813eJake Slack } 54503928aee4356845252ac6b662d5c72c29903813eJake Slack 54603928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 54703928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isClose(byte opcode) 54803928aee4356845252ac6b662d5c72c29903813eJake Slack { 54903928aee4356845252ac6b662d5c72c29903813eJake Slack return opcode==OP_CLOSE; 55003928aee4356845252ac6b662d5c72c29903813eJake Slack } 55103928aee4356845252ac6b662d5c72c29903813eJake Slack 55203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 55303928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isPing(byte opcode) 55403928aee4356845252ac6b662d5c72c29903813eJake Slack { 55503928aee4356845252ac6b662d5c72c29903813eJake Slack return opcode==OP_PING; 55603928aee4356845252ac6b662d5c72c29903813eJake Slack } 55703928aee4356845252ac6b662d5c72c29903813eJake Slack 55803928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 55903928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isPong(byte opcode) 56003928aee4356845252ac6b662d5c72c29903813eJake Slack { 56103928aee4356845252ac6b662d5c72c29903813eJake Slack return opcode==OP_PONG; 56203928aee4356845252ac6b662d5c72c29903813eJake Slack } 56303928aee4356845252ac6b662d5c72c29903813eJake Slack 56403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 56503928aee4356845252ac6b662d5c72c29903813eJake Slack public void disconnect() 56603928aee4356845252ac6b662d5c72c29903813eJake Slack { 56703928aee4356845252ac6b662d5c72c29903813eJake Slack close(CLOSE_NORMAL,null); 56803928aee4356845252ac6b662d5c72c29903813eJake Slack } 56903928aee4356845252ac6b662d5c72c29903813eJake Slack 57003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 57103928aee4356845252ac6b662d5c72c29903813eJake Slack public void close() 57203928aee4356845252ac6b662d5c72c29903813eJake Slack { 57303928aee4356845252ac6b662d5c72c29903813eJake Slack close(CLOSE_NORMAL,null); 57403928aee4356845252ac6b662d5c72c29903813eJake Slack } 57503928aee4356845252ac6b662d5c72c29903813eJake Slack 57603928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 57703928aee4356845252ac6b662d5c72c29903813eJake Slack public void setAllowFrameFragmentation(boolean allowFragmentation) 57803928aee4356845252ac6b662d5c72c29903813eJake Slack { 57903928aee4356845252ac6b662d5c72c29903813eJake Slack _parser.setFakeFragments(allowFragmentation); 58003928aee4356845252ac6b662d5c72c29903813eJake Slack } 58103928aee4356845252ac6b662d5c72c29903813eJake Slack 58203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 58303928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isAllowFrameFragmentation() 58403928aee4356845252ac6b662d5c72c29903813eJake Slack { 58503928aee4356845252ac6b662d5c72c29903813eJake Slack return _parser.isFakeFragments(); 58603928aee4356845252ac6b662d5c72c29903813eJake Slack } 58703928aee4356845252ac6b662d5c72c29903813eJake Slack 58803928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 58903928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 59003928aee4356845252ac6b662d5c72c29903813eJake Slack public String toString() 59103928aee4356845252ac6b662d5c72c29903813eJake Slack { 59203928aee4356845252ac6b662d5c72c29903813eJake Slack return String.format("%s[D08]@%x l(%s:%d)<->r(%s:%d)", 59303928aee4356845252ac6b662d5c72c29903813eJake Slack getClass().getSimpleName(), 59403928aee4356845252ac6b662d5c72c29903813eJake Slack hashCode(), 59503928aee4356845252ac6b662d5c72c29903813eJake Slack _endp.getLocalAddr(), 59603928aee4356845252ac6b662d5c72c29903813eJake Slack _endp.getLocalPort(), 59703928aee4356845252ac6b662d5c72c29903813eJake Slack _endp.getRemoteAddr(), 59803928aee4356845252ac6b662d5c72c29903813eJake Slack _endp.getRemotePort()); 59903928aee4356845252ac6b662d5c72c29903813eJake Slack } 60003928aee4356845252ac6b662d5c72c29903813eJake Slack } 60103928aee4356845252ac6b662d5c72c29903813eJake Slack 60203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 60303928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 60403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 60503928aee4356845252ac6b662d5c72c29903813eJake Slack private class WSFrameHandler implements WebSocketParser.FrameHandler 60603928aee4356845252ac6b662d5c72c29903813eJake Slack { 60703928aee4356845252ac6b662d5c72c29903813eJake Slack private final Utf8StringBuilder _utf8 = new Utf8StringBuilder(); 60803928aee4356845252ac6b662d5c72c29903813eJake Slack private ByteArrayBuffer _aggregate; 60903928aee4356845252ac6b662d5c72c29903813eJake Slack private byte _opcode=-1; 61003928aee4356845252ac6b662d5c72c29903813eJake Slack 61103928aee4356845252ac6b662d5c72c29903813eJake Slack public void onFrame(final byte flags, final byte opcode, final Buffer buffer) 61203928aee4356845252ac6b662d5c72c29903813eJake Slack { 61303928aee4356845252ac6b662d5c72c29903813eJake Slack boolean lastFrame = isLastFrame(flags); 61403928aee4356845252ac6b662d5c72c29903813eJake Slack 61503928aee4356845252ac6b662d5c72c29903813eJake Slack synchronized(WebSocketConnectionD08.this) 61603928aee4356845252ac6b662d5c72c29903813eJake Slack { 61703928aee4356845252ac6b662d5c72c29903813eJake Slack // Ignore incoming after a close 61803928aee4356845252ac6b662d5c72c29903813eJake Slack if (_closedIn) 61903928aee4356845252ac6b662d5c72c29903813eJake Slack return; 62003928aee4356845252ac6b662d5c72c29903813eJake Slack } 62103928aee4356845252ac6b662d5c72c29903813eJake Slack try 62203928aee4356845252ac6b662d5c72c29903813eJake Slack { 62303928aee4356845252ac6b662d5c72c29903813eJake Slack byte[] array=buffer.array(); 62403928aee4356845252ac6b662d5c72c29903813eJake Slack 62503928aee4356845252ac6b662d5c72c29903813eJake Slack // Deliver frame if websocket is a FrameWebSocket 62603928aee4356845252ac6b662d5c72c29903813eJake Slack if (_onFrame!=null) 62703928aee4356845252ac6b662d5c72c29903813eJake Slack { 62803928aee4356845252ac6b662d5c72c29903813eJake Slack if (_onFrame.onFrame(flags,opcode,array,buffer.getIndex(),buffer.length())) 62903928aee4356845252ac6b662d5c72c29903813eJake Slack return; 63003928aee4356845252ac6b662d5c72c29903813eJake Slack } 63103928aee4356845252ac6b662d5c72c29903813eJake Slack 63203928aee4356845252ac6b662d5c72c29903813eJake Slack if (_onControl!=null && isControlFrame(opcode)) 63303928aee4356845252ac6b662d5c72c29903813eJake Slack { 63403928aee4356845252ac6b662d5c72c29903813eJake Slack if (_onControl.onControl(opcode,array,buffer.getIndex(),buffer.length())) 63503928aee4356845252ac6b662d5c72c29903813eJake Slack return; 63603928aee4356845252ac6b662d5c72c29903813eJake Slack } 63703928aee4356845252ac6b662d5c72c29903813eJake Slack 63803928aee4356845252ac6b662d5c72c29903813eJake Slack switch(opcode) 63903928aee4356845252ac6b662d5c72c29903813eJake Slack { 64003928aee4356845252ac6b662d5c72c29903813eJake Slack case WebSocketConnectionD08.OP_CONTINUATION: 64103928aee4356845252ac6b662d5c72c29903813eJake Slack { 64203928aee4356845252ac6b662d5c72c29903813eJake Slack // If text, append to the message buffer 64303928aee4356845252ac6b662d5c72c29903813eJake Slack if (_onTextMessage!=null && _opcode==WebSocketConnectionD08.OP_TEXT) 64403928aee4356845252ac6b662d5c72c29903813eJake Slack { 64503928aee4356845252ac6b662d5c72c29903813eJake Slack if (_utf8.append(buffer.array(),buffer.getIndex(),buffer.length(),_connection.getMaxTextMessageSize())) 64603928aee4356845252ac6b662d5c72c29903813eJake Slack { 64703928aee4356845252ac6b662d5c72c29903813eJake Slack // If this is the last fragment, deliver the text buffer 64803928aee4356845252ac6b662d5c72c29903813eJake Slack if (lastFrame) 64903928aee4356845252ac6b662d5c72c29903813eJake Slack { 65003928aee4356845252ac6b662d5c72c29903813eJake Slack _opcode=-1; 65103928aee4356845252ac6b662d5c72c29903813eJake Slack String msg =_utf8.toString(); 65203928aee4356845252ac6b662d5c72c29903813eJake Slack _utf8.reset(); 65303928aee4356845252ac6b662d5c72c29903813eJake Slack _onTextMessage.onMessage(msg); 65403928aee4356845252ac6b662d5c72c29903813eJake Slack } 65503928aee4356845252ac6b662d5c72c29903813eJake Slack } 65603928aee4356845252ac6b662d5c72c29903813eJake Slack else 65703928aee4356845252ac6b662d5c72c29903813eJake Slack textMessageTooLarge(); 65803928aee4356845252ac6b662d5c72c29903813eJake Slack } 65903928aee4356845252ac6b662d5c72c29903813eJake Slack 66003928aee4356845252ac6b662d5c72c29903813eJake Slack if (_opcode>=0 && _connection.getMaxBinaryMessageSize()>=0) 66103928aee4356845252ac6b662d5c72c29903813eJake Slack { 66203928aee4356845252ac6b662d5c72c29903813eJake Slack if (checkBinaryMessageSize(_aggregate.length(),buffer.length())) 66303928aee4356845252ac6b662d5c72c29903813eJake Slack { 66403928aee4356845252ac6b662d5c72c29903813eJake Slack _aggregate.put(buffer); 66503928aee4356845252ac6b662d5c72c29903813eJake Slack 66603928aee4356845252ac6b662d5c72c29903813eJake Slack // If this is the last fragment, deliver 66703928aee4356845252ac6b662d5c72c29903813eJake Slack if (lastFrame && _onBinaryMessage!=null) 66803928aee4356845252ac6b662d5c72c29903813eJake Slack { 66903928aee4356845252ac6b662d5c72c29903813eJake Slack try 67003928aee4356845252ac6b662d5c72c29903813eJake Slack { 67103928aee4356845252ac6b662d5c72c29903813eJake Slack _onBinaryMessage.onMessage(_aggregate.array(),_aggregate.getIndex(),_aggregate.length()); 67203928aee4356845252ac6b662d5c72c29903813eJake Slack } 67303928aee4356845252ac6b662d5c72c29903813eJake Slack finally 67403928aee4356845252ac6b662d5c72c29903813eJake Slack { 67503928aee4356845252ac6b662d5c72c29903813eJake Slack _opcode=-1; 67603928aee4356845252ac6b662d5c72c29903813eJake Slack _aggregate.clear(); 67703928aee4356845252ac6b662d5c72c29903813eJake Slack } 67803928aee4356845252ac6b662d5c72c29903813eJake Slack } 67903928aee4356845252ac6b662d5c72c29903813eJake Slack } 68003928aee4356845252ac6b662d5c72c29903813eJake Slack } 68103928aee4356845252ac6b662d5c72c29903813eJake Slack break; 68203928aee4356845252ac6b662d5c72c29903813eJake Slack } 68303928aee4356845252ac6b662d5c72c29903813eJake Slack case WebSocketConnectionD08.OP_PING: 68403928aee4356845252ac6b662d5c72c29903813eJake Slack { 68503928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("PING {}",this); 68603928aee4356845252ac6b662d5c72c29903813eJake Slack if (!_closedOut) 68703928aee4356845252ac6b662d5c72c29903813eJake Slack _connection.sendControl(WebSocketConnectionD08.OP_PONG,buffer.array(),buffer.getIndex(),buffer.length()); 68803928aee4356845252ac6b662d5c72c29903813eJake Slack break; 68903928aee4356845252ac6b662d5c72c29903813eJake Slack } 69003928aee4356845252ac6b662d5c72c29903813eJake Slack 69103928aee4356845252ac6b662d5c72c29903813eJake Slack case WebSocketConnectionD08.OP_PONG: 69203928aee4356845252ac6b662d5c72c29903813eJake Slack { 69303928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("PONG {}",this); 69403928aee4356845252ac6b662d5c72c29903813eJake Slack break; 69503928aee4356845252ac6b662d5c72c29903813eJake Slack } 69603928aee4356845252ac6b662d5c72c29903813eJake Slack 69703928aee4356845252ac6b662d5c72c29903813eJake Slack case WebSocketConnectionD08.OP_CLOSE: 69803928aee4356845252ac6b662d5c72c29903813eJake Slack { 69903928aee4356845252ac6b662d5c72c29903813eJake Slack int code=WebSocketConnectionD08.CLOSE_NOCODE; 70003928aee4356845252ac6b662d5c72c29903813eJake Slack String message=null; 70103928aee4356845252ac6b662d5c72c29903813eJake Slack if (buffer.length()>=2) 70203928aee4356845252ac6b662d5c72c29903813eJake Slack { 70303928aee4356845252ac6b662d5c72c29903813eJake Slack code=buffer.array()[buffer.getIndex()]*0x100+buffer.array()[buffer.getIndex()+1]; 70403928aee4356845252ac6b662d5c72c29903813eJake Slack if (buffer.length()>2) 70503928aee4356845252ac6b662d5c72c29903813eJake Slack message=new String(buffer.array(),buffer.getIndex()+2,buffer.length()-2,StringUtil.__UTF8); 70603928aee4356845252ac6b662d5c72c29903813eJake Slack } 70703928aee4356845252ac6b662d5c72c29903813eJake Slack closeIn(code,message); 70803928aee4356845252ac6b662d5c72c29903813eJake Slack break; 70903928aee4356845252ac6b662d5c72c29903813eJake Slack } 71003928aee4356845252ac6b662d5c72c29903813eJake Slack 71103928aee4356845252ac6b662d5c72c29903813eJake Slack case WebSocketConnectionD08.OP_TEXT: 71203928aee4356845252ac6b662d5c72c29903813eJake Slack { 71303928aee4356845252ac6b662d5c72c29903813eJake Slack if(_onTextMessage!=null) 71403928aee4356845252ac6b662d5c72c29903813eJake Slack { 71503928aee4356845252ac6b662d5c72c29903813eJake Slack if (_connection.getMaxTextMessageSize()<=0) 71603928aee4356845252ac6b662d5c72c29903813eJake Slack { 71703928aee4356845252ac6b662d5c72c29903813eJake Slack // No size limit, so handle only final frames 71803928aee4356845252ac6b662d5c72c29903813eJake Slack if (lastFrame) 71903928aee4356845252ac6b662d5c72c29903813eJake Slack _onTextMessage.onMessage(buffer.toString(StringUtil.__UTF8)); 72003928aee4356845252ac6b662d5c72c29903813eJake Slack else 72103928aee4356845252ac6b662d5c72c29903813eJake Slack { 72203928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Frame discarded. Text aggregation disabled for {}",_endp); 72303928aee4356845252ac6b662d5c72c29903813eJake Slack _connection.close(WebSocketConnectionD08.CLOSE_BADDATA,"Text frame aggregation disabled"); 72403928aee4356845252ac6b662d5c72c29903813eJake Slack } 72503928aee4356845252ac6b662d5c72c29903813eJake Slack } 72603928aee4356845252ac6b662d5c72c29903813eJake Slack // append bytes to message buffer (if they fit) 72703928aee4356845252ac6b662d5c72c29903813eJake Slack else if (_utf8.append(buffer.array(),buffer.getIndex(),buffer.length(),_connection.getMaxTextMessageSize())) 72803928aee4356845252ac6b662d5c72c29903813eJake Slack { 72903928aee4356845252ac6b662d5c72c29903813eJake Slack if (lastFrame) 73003928aee4356845252ac6b662d5c72c29903813eJake Slack { 73103928aee4356845252ac6b662d5c72c29903813eJake Slack String msg =_utf8.toString(); 73203928aee4356845252ac6b662d5c72c29903813eJake Slack _utf8.reset(); 73303928aee4356845252ac6b662d5c72c29903813eJake Slack _onTextMessage.onMessage(msg); 73403928aee4356845252ac6b662d5c72c29903813eJake Slack } 73503928aee4356845252ac6b662d5c72c29903813eJake Slack else 73603928aee4356845252ac6b662d5c72c29903813eJake Slack { 73703928aee4356845252ac6b662d5c72c29903813eJake Slack _opcode=WebSocketConnectionD08.OP_TEXT; 73803928aee4356845252ac6b662d5c72c29903813eJake Slack } 73903928aee4356845252ac6b662d5c72c29903813eJake Slack } 74003928aee4356845252ac6b662d5c72c29903813eJake Slack else 74103928aee4356845252ac6b662d5c72c29903813eJake Slack textMessageTooLarge(); 74203928aee4356845252ac6b662d5c72c29903813eJake Slack } 74303928aee4356845252ac6b662d5c72c29903813eJake Slack break; 74403928aee4356845252ac6b662d5c72c29903813eJake Slack } 74503928aee4356845252ac6b662d5c72c29903813eJake Slack 74603928aee4356845252ac6b662d5c72c29903813eJake Slack default: 74703928aee4356845252ac6b662d5c72c29903813eJake Slack { 74803928aee4356845252ac6b662d5c72c29903813eJake Slack if (_onBinaryMessage!=null && checkBinaryMessageSize(0,buffer.length())) 74903928aee4356845252ac6b662d5c72c29903813eJake Slack { 75003928aee4356845252ac6b662d5c72c29903813eJake Slack if (lastFrame) 75103928aee4356845252ac6b662d5c72c29903813eJake Slack { 75203928aee4356845252ac6b662d5c72c29903813eJake Slack _onBinaryMessage.onMessage(array,buffer.getIndex(),buffer.length()); 75303928aee4356845252ac6b662d5c72c29903813eJake Slack } 75403928aee4356845252ac6b662d5c72c29903813eJake Slack else if (_connection.getMaxBinaryMessageSize()>=0) 75503928aee4356845252ac6b662d5c72c29903813eJake Slack { 75603928aee4356845252ac6b662d5c72c29903813eJake Slack _opcode=opcode; 75703928aee4356845252ac6b662d5c72c29903813eJake Slack if (_aggregate==null) 75803928aee4356845252ac6b662d5c72c29903813eJake Slack _aggregate=new ByteArrayBuffer(_connection.getMaxBinaryMessageSize()); 75903928aee4356845252ac6b662d5c72c29903813eJake Slack _aggregate.put(buffer); 76003928aee4356845252ac6b662d5c72c29903813eJake Slack } 76103928aee4356845252ac6b662d5c72c29903813eJake Slack else 76203928aee4356845252ac6b662d5c72c29903813eJake Slack { 76303928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Frame discarded. Binary aggregation disabed for {}",_endp); 76403928aee4356845252ac6b662d5c72c29903813eJake Slack _connection.close(WebSocketConnectionD08.CLOSE_BADDATA,"Binary frame aggregation disabled"); 76503928aee4356845252ac6b662d5c72c29903813eJake Slack } 76603928aee4356845252ac6b662d5c72c29903813eJake Slack } 76703928aee4356845252ac6b662d5c72c29903813eJake Slack } 76803928aee4356845252ac6b662d5c72c29903813eJake Slack } 76903928aee4356845252ac6b662d5c72c29903813eJake Slack } 77003928aee4356845252ac6b662d5c72c29903813eJake Slack catch(Throwable e) 77103928aee4356845252ac6b662d5c72c29903813eJake Slack { 77203928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("{} for {}",e,_endp, e); 77303928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug(e); 77403928aee4356845252ac6b662d5c72c29903813eJake Slack errorClose(WebSocketConnectionRFC6455.CLOSE_SERVER_ERROR,"Internal Server Error: "+e); 77503928aee4356845252ac6b662d5c72c29903813eJake Slack } 77603928aee4356845252ac6b662d5c72c29903813eJake Slack } 77703928aee4356845252ac6b662d5c72c29903813eJake Slack 77803928aee4356845252ac6b662d5c72c29903813eJake Slack private void errorClose(int code, String message) 77903928aee4356845252ac6b662d5c72c29903813eJake Slack { 78003928aee4356845252ac6b662d5c72c29903813eJake Slack _connection.close(code,message); 78103928aee4356845252ac6b662d5c72c29903813eJake Slack 78203928aee4356845252ac6b662d5c72c29903813eJake Slack // Brutally drop the connection 78303928aee4356845252ac6b662d5c72c29903813eJake Slack try 78403928aee4356845252ac6b662d5c72c29903813eJake Slack { 78503928aee4356845252ac6b662d5c72c29903813eJake Slack _endp.close(); 78603928aee4356845252ac6b662d5c72c29903813eJake Slack } 78703928aee4356845252ac6b662d5c72c29903813eJake Slack catch (IOException e) 78803928aee4356845252ac6b662d5c72c29903813eJake Slack { 78903928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(e.toString()); 79003928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug(e); 79103928aee4356845252ac6b662d5c72c29903813eJake Slack } 79203928aee4356845252ac6b662d5c72c29903813eJake Slack } 79303928aee4356845252ac6b662d5c72c29903813eJake Slack 79403928aee4356845252ac6b662d5c72c29903813eJake Slack private boolean checkBinaryMessageSize(int bufferLen, int length) 79503928aee4356845252ac6b662d5c72c29903813eJake Slack { 79603928aee4356845252ac6b662d5c72c29903813eJake Slack int max = _connection.getMaxBinaryMessageSize(); 79703928aee4356845252ac6b662d5c72c29903813eJake Slack if (max>0 && (bufferLen+length)>max) 79803928aee4356845252ac6b662d5c72c29903813eJake Slack { 79903928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Binary message too large > {}B for {}",_connection.getMaxBinaryMessageSize(),_endp); 80003928aee4356845252ac6b662d5c72c29903813eJake Slack _connection.close(WebSocketConnectionD08.CLOSE_BADDATA,"Message size > "+_connection.getMaxBinaryMessageSize()); 80103928aee4356845252ac6b662d5c72c29903813eJake Slack _opcode=-1; 80203928aee4356845252ac6b662d5c72c29903813eJake Slack if (_aggregate!=null) 80303928aee4356845252ac6b662d5c72c29903813eJake Slack _aggregate.clear(); 80403928aee4356845252ac6b662d5c72c29903813eJake Slack return false; 80503928aee4356845252ac6b662d5c72c29903813eJake Slack } 80603928aee4356845252ac6b662d5c72c29903813eJake Slack return true; 80703928aee4356845252ac6b662d5c72c29903813eJake Slack } 80803928aee4356845252ac6b662d5c72c29903813eJake Slack 80903928aee4356845252ac6b662d5c72c29903813eJake Slack private void textMessageTooLarge() 81003928aee4356845252ac6b662d5c72c29903813eJake Slack { 81103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Text message too large > {} chars for {}",_connection.getMaxTextMessageSize(),_endp); 81203928aee4356845252ac6b662d5c72c29903813eJake Slack _connection.close(WebSocketConnectionD08.CLOSE_BADDATA,"Text message size > "+_connection.getMaxTextMessageSize()+" chars"); 81303928aee4356845252ac6b662d5c72c29903813eJake Slack 81403928aee4356845252ac6b662d5c72c29903813eJake Slack _opcode=-1; 81503928aee4356845252ac6b662d5c72c29903813eJake Slack _utf8.reset(); 81603928aee4356845252ac6b662d5c72c29903813eJake Slack } 81703928aee4356845252ac6b662d5c72c29903813eJake Slack 81803928aee4356845252ac6b662d5c72c29903813eJake Slack public void close(int code,String message) 81903928aee4356845252ac6b662d5c72c29903813eJake Slack { 82003928aee4356845252ac6b662d5c72c29903813eJake Slack if (code!=CLOSE_NORMAL) 82103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Close: "+code+" "+message); 82203928aee4356845252ac6b662d5c72c29903813eJake Slack _connection.close(code,message); 82303928aee4356845252ac6b662d5c72c29903813eJake Slack } 82403928aee4356845252ac6b662d5c72c29903813eJake Slack 82503928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 82603928aee4356845252ac6b662d5c72c29903813eJake Slack public String toString() 82703928aee4356845252ac6b662d5c72c29903813eJake Slack { 82803928aee4356845252ac6b662d5c72c29903813eJake Slack return WebSocketConnectionD08.this.toString()+"FH"; 82903928aee4356845252ac6b662d5c72c29903813eJake Slack } 83003928aee4356845252ac6b662d5c72c29903813eJake Slack } 83103928aee4356845252ac6b662d5c72c29903813eJake Slack 83203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 83303928aee4356845252ac6b662d5c72c29903813eJake Slack public static String hashKey(String key) 83403928aee4356845252ac6b662d5c72c29903813eJake Slack { 83503928aee4356845252ac6b662d5c72c29903813eJake Slack try 83603928aee4356845252ac6b662d5c72c29903813eJake Slack { 83703928aee4356845252ac6b662d5c72c29903813eJake Slack MessageDigest md = MessageDigest.getInstance("SHA1"); 83803928aee4356845252ac6b662d5c72c29903813eJake Slack md.update(key.getBytes("UTF-8")); 83903928aee4356845252ac6b662d5c72c29903813eJake Slack md.update(MAGIC); 84003928aee4356845252ac6b662d5c72c29903813eJake Slack return new String(B64Code.encode(md.digest())); 84103928aee4356845252ac6b662d5c72c29903813eJake Slack } 84203928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception e) 84303928aee4356845252ac6b662d5c72c29903813eJake Slack { 84403928aee4356845252ac6b662d5c72c29903813eJake Slack throw new RuntimeException(e); 84503928aee4356845252ac6b662d5c72c29903813eJake Slack } 84603928aee4356845252ac6b662d5c72c29903813eJake Slack } 84703928aee4356845252ac6b662d5c72c29903813eJake Slack 84803928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 84903928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 85003928aee4356845252ac6b662d5c72c29903813eJake Slack public String toString() 85103928aee4356845252ac6b662d5c72c29903813eJake Slack { 85203928aee4356845252ac6b662d5c72c29903813eJake Slack return String.format("WS/D%d p=%s g=%s", _draft, _parser, _generator); 85303928aee4356845252ac6b662d5c72c29903813eJake Slack } 85403928aee4356845252ac6b662d5c72c29903813eJake Slack} 855