123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Text;
- using SuperSocket.Common;
- using SuperSocket.SocketBase;
- using SuperSocket.SocketBase.Command;
- using SuperSocket.SocketBase.Protocol;
- namespace SuperWebSocket.Protocol
- {
- class WebSocketHeaderReceiveFilter : WebSocketReceiveFilterBase
- {
- private static readonly byte[] m_HeaderTerminator = Encoding.UTF8.GetBytes("\r\n\r\n");
- private readonly SearchMarkState<byte> m_SearchState;
- public WebSocketHeaderReceiveFilter(IWebSocketSession session)
- : base(session)
- {
- m_SearchState = new SearchMarkState<byte>(m_HeaderTerminator);
- }
- public override IWebSocketFragment Filter(byte[] readBuffer, int offset, int length, bool isReusableBuffer, out int rest)
- {
- rest = 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;
- try
- {
- WebSocketServer.ParseHandshake(webSocketSession, new StringReader(header));
- }
- catch (Exception e)
- {
- webSocketSession.Logger.Error("Failed to parse handshake!" + Environment.NewLine + header, e);
- webSocketSession.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;
- rest = 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 (rest == SecKey3Len)
- {
- webSocketSession.Items[WebSocketConstant.SecWebSocketKey3] = readBuffer.CloneRange(offset + length - rest, rest);
- rest = 0;
- if(Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession))
- return HandshakeRequestInfo;
- }
- else if (rest > SecKey3Len)
- {
- webSocketSession.Items[WebSocketConstant.SecWebSocketKey3] = readBuffer.CloneRange(offset + length - rest, 8);
- rest -= 8;
- if(Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession))
- return HandshakeRequestInfo;
- }
- else
- {
- //rest < 8
- if (rest > 0)
- {
- AddArraySegment(readBuffer, offset + length - rest, rest, isReusableBuffer);
- rest = 0;
- }
- NextReceiveFilter = new WebSocketSecKey3ReceiveFilter(this);
- return null;
- }
- }
- return null;
- }
- }
- }
|