public override IWebSocketFragment Filter(IAppSession <IWebSocketFragment> session, byte[] readBuffer, int offset, int length, bool isReusableBuffer, out int left) { left = 0; var skipByteCount = 0; if (!m_Type.HasValue) { byte startByte = readBuffer[offset]; skipByteCount = 1; m_Type = startByte; } //0xxxxxxx: Collect protocol data by end mark if ((m_Type.Value & 0x80) == 0x00) { byte lookForByte = 0xFF; int i; for (i = offset + skipByteCount; i < offset + length; i++) { if (readBuffer[i] == lookForByte) { left = length - (i - offset + 1); if (BufferSegments.Count <= 0) { var commandInfo = new PlainFragment(Encoding.UTF8.GetString(readBuffer, offset + skipByteCount, i - offset - skipByteCount)); Reset(); return(commandInfo); } else { AddArraySegment(readBuffer, offset + skipByteCount, i - offset - skipByteCount, false); var commandInfo = new PlainFragment(BufferSegments.Decode(Encoding.UTF8)); Reset(); return(commandInfo); } } } AddArraySegment(readBuffer, offset + skipByteCount, length - skipByteCount, isReusableBuffer); return(null); } else//10000000: Collect protocol data by length { while (!m_Length.HasValue) { if (length <= skipByteCount) { //No data to read return(null); } byte lengthByte = readBuffer[skipByteCount]; //Closing handshake if (lengthByte == 0x00 && m_Type.Value == m_ClosingHandshakeType) { session.Close(CloseReason.ClientClosing); return(null); } int thisLength = (int)(lengthByte & 0x7F); m_TempLength = m_TempLength * 128 + thisLength; skipByteCount++; if ((lengthByte & 0x80) != 0x80) { m_Length = m_TempLength; break; } } int requiredSize = m_Length.Value - BufferSegments.Count; int leftSize = length - skipByteCount; if (leftSize < requiredSize) { AddArraySegment(readBuffer, skipByteCount, length - skipByteCount, isReusableBuffer); return(null); } else { left = leftSize - requiredSize; if (BufferSegments.Count <= 0) { var commandInfo = new PlainFragment(Encoding.UTF8.GetString(readBuffer, offset + skipByteCount, requiredSize)); Reset(); return(commandInfo); } else { AddArraySegment(readBuffer, offset + skipByteCount, requiredSize, false); var commandInfo = new PlainFragment(BufferSegments.Decode(Encoding.UTF8)); Reset(); return(commandInfo); } } } }
public override IWebSocketFragment Filter(IAppSession session, byte[] readBuffer, int offset, int length, bool isReusableBuffer, out int left) { left = 0; int prevMatched = m_SearchState.Matched; var result = readBuffer.SearchMark(offset, length, m_SearchState); if (result < 0) { this.AddArraySegment(readBuffer, offset, length, isReusableBuffer); return null; } int findLen = result - offset; string header = string.Empty; if (this.BufferSegments.Count > 0) { if (findLen > 0) { this.AddArraySegment(readBuffer, offset, findLen, false); header = this.BufferSegments.Decode(Encoding.UTF8); } else { header = this.BufferSegments.Decode(Encoding.UTF8, 0, this.BufferSegments.Count - prevMatched); } } else { header = Encoding.UTF8.GetString(readBuffer, offset, findLen); } var webSocketSession = session as IWebSocketSession; try { WebSocketServer.ParseHandshake(webSocketSession, new StringReader(header)); } catch (Exception e) { session.Logger.Error("Failed to parse handshake!" + Environment.NewLine + header, e); session.Close(CloseReason.ProtocolError); return null; } var secWebSocketKey1 = webSocketSession.Items.GetValue<string>(WebSocketConstant.SecWebSocketKey1, string.Empty); var secWebSocketKey2 = webSocketSession.Items.GetValue<string>(WebSocketConstant.SecWebSocketKey2, string.Empty); var secWebSocketVersion = webSocketSession.SecWebSocketVersion; left = length - findLen - (m_HeaderTerminator.Length - prevMatched); this.ClearBufferSegments(); if (string.IsNullOrEmpty(secWebSocketKey1) && string.IsNullOrEmpty(secWebSocketKey2)) { //draft-hixie-thewebsocketprotocol-75 if(Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession)) return HandshakeRequestInfo; } else if ("6".Equals(secWebSocketVersion)) //draft-ietf-hybi-thewebsocketprotocol-06 { if(Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession)) return HandshakeRequestInfo; } else { //draft-hixie-thewebsocketprotocol-76/draft-ietf-hybi-thewebsocketprotocol-00 //Read SecWebSocketKey3(8 bytes) if (left == SecKey3Len) { webSocketSession.Items[WebSocketConstant.SecWebSocketKey3] = readBuffer.CloneRange(offset + length - left, left); left = 0; if(Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession)) return HandshakeRequestInfo; } else if (left > SecKey3Len) { webSocketSession.Items[WebSocketConstant.SecWebSocketKey3] = readBuffer.CloneRange(offset + length - left, 8); left -= 8; if(Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession)) return HandshakeRequestInfo; } else { //left < 8 if (left > 0) { AddArraySegment(readBuffer, offset + length - left, left, isReusableBuffer); left = 0; } NextRequestFilter = new WebSocketSecKey3RequestFilter(this); return null; } } return null; }
public override IWebSocketFragment FindCommandInfo(IAppSession session, byte[] readBuffer, int offset, int length, bool isReusableBuffer, out int left) { left = 0; int prevMatched = m_SearchState.Matched; var result = readBuffer.SearchMark(offset, length, m_SearchState); if (result < 0) { this.AddArraySegment(readBuffer, offset, length, isReusableBuffer); return(null); } int findLen = result - offset; string header = string.Empty; if (this.BufferSegments.Count > 0) { if (findLen > 0) { this.AddArraySegment(readBuffer, offset, findLen, false); header = this.BufferSegments.Decode(Encoding.UTF8); } else { header = this.BufferSegments.Decode(Encoding.UTF8, 0, this.BufferSegments.Count - prevMatched); } } else { header = Encoding.UTF8.GetString(readBuffer, offset, findLen); } var webSocketSession = session as IWebSocketSession; try { WebSocketServer.ParseHandshake(webSocketSession, new StringReader(header)); } catch (Exception e) { session.Logger.LogError("Failed to parse handshake!" + Environment.NewLine + header, e); session.Close(CloseReason.Unknown); return(null); } var secWebSocketKey1 = webSocketSession.Items.GetValue <string>(WebSocketConstant.SecWebSocketKey1, string.Empty); var secWebSocketKey2 = webSocketSession.Items.GetValue <string>(WebSocketConstant.SecWebSocketKey2, string.Empty); var secWebSocketVersion = webSocketSession.SecWebSocketVersion; left = length - findLen - (m_HeaderTerminator.Length - prevMatched); this.ClearBufferSegments(); if (string.IsNullOrEmpty(secWebSocketKey1) && string.IsNullOrEmpty(secWebSocketKey2)) { //draft-hixie-thewebsocketprotocol-75 if (Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession)) { return(HandshakeCommandInfo); } } else if ("6".Equals(secWebSocketVersion)) //draft-ietf-hybi-thewebsocketprotocol-06 { if (Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession)) { return(HandshakeCommandInfo); } } else { //draft-hixie-thewebsocketprotocol-76/draft-ietf-hybi-thewebsocketprotocol-00 //Read SecWebSocketKey3(8 bytes) if (left == SecKey3Len) { webSocketSession.Items[WebSocketConstant.SecWebSocketKey3] = readBuffer.CloneRange(offset + length - left, left); left = 0; if (Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession)) { return(HandshakeCommandInfo); } } else if (left > SecKey3Len) { webSocketSession.Items[WebSocketConstant.SecWebSocketKey3] = readBuffer.CloneRange(offset + length - left, 8); left -= 8; if (Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession)) { return(HandshakeCommandInfo); } } else { //left < 8 if (left > 0) { AddArraySegment(readBuffer, offset + length - left, left, isReusableBuffer); left = 0; } NextCommandReader = new WebSocketSecKey3Reader(this); return(null); } } return(null); }
public override IWebSocketFragment FindCommandInfo(IAppSession session, byte[] readBuffer, int offset, int length, bool isReusableBuffer, out int left) { left = 0; var skipByteCount = 0; if (!m_Type.HasValue) { byte startByte = readBuffer[offset]; skipByteCount = 1; m_Type = startByte; } //0xxxxxxx: Collect protocol data by end mark if ((m_Type.Value & 0x80) == 0x00) { byte lookForByte = 0xFF; int i; for (i = offset + skipByteCount; i < offset + length; i++) { if (readBuffer[i] == lookForByte) { left = length - (i - offset + 1); if (BufferSegments.Count <= 0) { var commandInfo = new PlainFragment(Encoding.UTF8.GetString(readBuffer, offset + skipByteCount, i - offset - skipByteCount)); Reset(); return commandInfo; } else { AddArraySegment(readBuffer, offset + skipByteCount, i - offset - skipByteCount, false); var commandInfo = new PlainFragment(BufferSegments.Decode(Encoding.UTF8)); Reset(); return commandInfo; } } } AddArraySegment(readBuffer, offset + skipByteCount, length - skipByteCount, isReusableBuffer); return null; } else//10000000: Collect protocol data by length { while (!m_Length.HasValue) { if (length <= skipByteCount) { //No data to read return null; } byte lengthByte = readBuffer[skipByteCount]; //Closing handshake if (lengthByte == 0x00 && m_Type.Value == m_ClosingHandshakeType) { session.Close(CloseReason.ClientClosing); return null; } int thisLength = (int)(lengthByte & 0x7F); m_TempLength = m_TempLength * 128 + thisLength; skipByteCount++; if ((lengthByte & 0x80) != 0x80) { m_Length = m_TempLength; break; } } int requiredSize = m_Length.Value - BufferSegments.Count; int leftSize = length - skipByteCount; if (leftSize < requiredSize) { AddArraySegment(readBuffer, skipByteCount, length - skipByteCount, isReusableBuffer); return null; } else { left = leftSize - requiredSize; if (BufferSegments.Count <= 0) { var commandInfo = new PlainFragment(Encoding.UTF8.GetString(readBuffer, offset + skipByteCount, requiredSize)); Reset(); return commandInfo; } else { AddArraySegment(readBuffer, offset + skipByteCount, requiredSize, false); var commandInfo = new PlainFragment(BufferSegments.Decode(Encoding.UTF8)); Reset(); return commandInfo; } } } }