WebSocketHeaderReceiveFilter.cs 4.7 KB

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