WebSocketHeaderReceiveFilter.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Text;
  6. using SuperSocket.Common;
  7. using SuperSocket.SocketBase;
  8. using SuperSocket.SocketBase.Command;
  9. using SuperSocket.SocketBase.Protocol;
  10. namespace SuperWebSocket.Protocol
  11. {
  12. class WebSocketHeaderReceiveFilter : WebSocketReceiveFilterBase
  13. {
  14. private static readonly byte[] m_HeaderTerminator = Encoding.UTF8.GetBytes("\r\n\r\n");
  15. private readonly SearchMarkState<byte> m_SearchState;
  16. public WebSocketHeaderReceiveFilter(IWebSocketSession session)
  17. : base(session)
  18. {
  19. m_SearchState = new SearchMarkState<byte>(m_HeaderTerminator);
  20. }
  21. public override IWebSocketFragment Filter(byte[] readBuffer, int offset, int length, bool isReusableBuffer, out int rest)
  22. {
  23. rest = 0;
  24. int prevMatched = m_SearchState.Matched;
  25. var result = readBuffer.SearchMark(offset, length, m_SearchState);
  26. if (result < 0)
  27. {
  28. this.AddArraySegment(readBuffer, offset, length, isReusableBuffer);
  29. return null;
  30. }
  31. int findLen = result - offset;
  32. string header = string.Empty;
  33. if (this.BufferSegments.Count > 0)
  34. {
  35. if (findLen > 0)
  36. {
  37. this.AddArraySegment(readBuffer, offset, findLen, false);
  38. header = this.BufferSegments.Decode(Encoding.UTF8);
  39. }
  40. else
  41. {
  42. header = this.BufferSegments.Decode(Encoding.UTF8, 0, this.BufferSegments.Count - prevMatched);
  43. }
  44. }
  45. else
  46. {
  47. header = Encoding.UTF8.GetString(readBuffer, offset, findLen);
  48. }
  49. var webSocketSession = Session;
  50. try
  51. {
  52. WebSocketServer.ParseHandshake(webSocketSession, new StringReader(header));
  53. }
  54. catch (Exception e)
  55. {
  56. webSocketSession.Logger.Error("Failed to parse handshake!" + Environment.NewLine + header, e);
  57. webSocketSession.Close(CloseReason.ProtocolError);
  58. return null;
  59. }
  60. var secWebSocketKey1 = webSocketSession.Items.GetValue<string>(WebSocketConstant.SecWebSocketKey1, string.Empty);
  61. var secWebSocketKey2 = webSocketSession.Items.GetValue<string>(WebSocketConstant.SecWebSocketKey2, string.Empty);
  62. var secWebSocketVersion = webSocketSession.SecWebSocketVersion;
  63. rest = length - findLen - (m_HeaderTerminator.Length - prevMatched);
  64. this.ClearBufferSegments();
  65. if (string.IsNullOrEmpty(secWebSocketKey1) && string.IsNullOrEmpty(secWebSocketKey2))
  66. {
  67. //draft-hixie-thewebsocketprotocol-75
  68. if(Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession))
  69. return HandshakeRequestInfo;
  70. }
  71. else if ("6".Equals(secWebSocketVersion)) //draft-ietf-hybi-thewebsocketprotocol-06
  72. {
  73. if(Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession))
  74. return HandshakeRequestInfo;
  75. }
  76. else
  77. {
  78. //draft-hixie-thewebsocketprotocol-76/draft-ietf-hybi-thewebsocketprotocol-00
  79. //Read SecWebSocketKey3(8 bytes)
  80. if (rest == SecKey3Len)
  81. {
  82. webSocketSession.Items[WebSocketConstant.SecWebSocketKey3] = readBuffer.CloneRange(offset + length - rest, rest);
  83. rest = 0;
  84. if(Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession))
  85. return HandshakeRequestInfo;
  86. }
  87. else if (rest > SecKey3Len)
  88. {
  89. webSocketSession.Items[WebSocketConstant.SecWebSocketKey3] = readBuffer.CloneRange(offset + length - rest, 8);
  90. rest -= 8;
  91. if(Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession))
  92. return HandshakeRequestInfo;
  93. }
  94. else
  95. {
  96. //rest < 8
  97. if (rest > 0)
  98. {
  99. AddArraySegment(readBuffer, offset + length - rest, rest, isReusableBuffer);
  100. rest = 0;
  101. }
  102. NextReceiveFilter = new WebSocketSecKey3ReceiveFilter(this);
  103. return null;
  104. }
  105. }
  106. return null;
  107. }
  108. }
  109. }