private string GenreateKey(HandshakeData handshakeData) { if (handshakeData.ParamItems.TryGet(HandshakeHeadKeys.SecKey, out string key)) { return(GenreateKey(key)); } return(string.Empty); }
protected override bool CheckSignKey(HandshakeData handshakeData) { if (handshakeData.WebSocketVersion < WebSocketListener.Version) { return(base.CheckSignKey(handshakeData)); } if (handshakeData.ParamItems.TryGet(HandshakeHeadKeys.SecAccept, out string accecpKey) && handshakeData.ParamItems.TryGet(HandshakeHeadKeys.SecSignKey, out string signKey)) { return(string.Equals(signKey, accecpKey)); } return(false); }
protected void ParseCookies(HandshakeData handshake, string cookieStr) { if (handshake == null) { return; } if (handshake.Cookies == null) { handshake.Cookies = new Dictionary <string, string>(); } var array = cookieStr.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (var item in array) { var kvs = item.Split('='); if (kvs.Length == 2 && !string.IsNullOrEmpty(kvs[0])) { handshake.Cookies[Uri.UnescapeDataString(kvs[0])] = Uri.UnescapeDataString(kvs[1].Trim()); } } }
protected override bool ResponseHandshake(WebSocket socket, HandshakeData handshakeData) { if (handshakeData.WebSocketVersion < WebSocketListener.Version) { return(base.ResponseHandshake(socket, handshakeData)); } string secKeyAccept = GenreateKey(handshakeData); StringBuilder response = new StringBuilder(); response.AppendLine(HandshakeHeadKeys.RespHead_10); response.AppendLine(HandshakeHeadKeys.RespUpgrade); response.AppendLine(HandshakeHeadKeys.RespConnection); response.AppendLine(string.Format(HandshakeHeadKeys.RespAccept, secKeyAccept)); if (!string.IsNullOrEmpty(handshakeData.Protocol)) { response.AppendLine(string.Format(HandshakeHeadKeys.RespProtocol, handshakeData.Protocol)); } response.AppendLine(); socket.PostSend(response.ToString()); return(true); }
protected override bool CheckSignKey(HandshakeData handshakeData) { if (handshakeData.ParamItems.TryGet(HandshakeHeadKeys.SecAccept, out byte[] secAccept) &&
protected virtual bool TryParseHandshake(string message, HandshakeData handshakeData, out string error) { using (var reader = new StringReader(message)) { error = string.Empty; string headData = reader.ReadLine() ?? ""; var headParams = headData.Split(' '); if (headParams.Length < 3 || (headParams[0] != HandshakeHeadKeys.Method && headParams[0] != HandshakeHeadKeys.HttpVersion)) { return(false); } if (headParams[0] != HandshakeHeadKeys.HttpVersion) { if (webSocketListener.IsSecurity) { handshakeData.UriSchema = "wss"; } handshakeData.Method = headParams[0]; handshakeData.UrlPath = headParams[1]; handshakeData.HttpVersion = headParams[2]; } string paramStr; while (!string.IsNullOrEmpty(paramStr = reader.ReadLine())) { //ex: Upgrade: WebSocket var paramArr = paramStr.Split(':'); if (paramArr.Length < 2) { continue; } string key = paramArr[0].Trim(); //value includ spance char string value = string.Join("", paramArr, 1, paramArr.Length - 1); if (value.Length > 1) { value = value.Substring(1); //pre char is spance } if (string.IsNullOrEmpty(key)) { continue; } if (string.Equals(HandshakeHeadKeys.Host, key)) { handshakeData.Host = value; continue; } if (string.Equals(HandshakeHeadKeys.SecVersion, key)) { handshakeData.WebSocketVersion = int.Parse(value); continue; } if (string.Equals(HandshakeHeadKeys.SecProtocol, key)) { handshakeData.Protocol = GetFirstProtocol(value); continue; } if (string.Equals(HandshakeHeadKeys.Cookie, key)) { ParseCookies(handshakeData, value); continue; } handshakeData.ParamItems[key] = value; } if (handshakeData.ParamItems.ContainsKey(HandshakeHeadKeys.Upgrade) && handshakeData.ParamItems.ContainsKey(HandshakeHeadKeys.Connection)) { return(true); } error = "not support websocket "; } return(false); }
protected abstract bool CheckSignKey(HandshakeData handshakeData);
protected abstract bool ResponseHandshake(WebSocket socket, HandshakeData handshakeData);
internal HandshakeResult Receive(SocketAsyncEventArgs ioEventArgs, WSDataToken dataToken, byte[] data) { if (dataToken.ByteArrayForHandshake == null) { dataToken.ByteArrayForHandshake = new List <byte>(data); } else { dataToken.ByteArrayForHandshake.AddRange(data); } var socket = (WebSocket)dataToken.Socket; var buffer = dataToken.ByteArrayForHandshake.ToArray(); int headLength = MathUtils.IndexOf(buffer, HandshakeEndBytes); if (headLength < 0) { //data not complate, wait receive return(HandshakeResult.Wait); } headLength += HandshakeEndBytes.Length; byte[] headBytes = new byte[headLength]; Buffer.BlockCopy(buffer, 0, headBytes, 0, headBytes.Length); string message = Encoding.GetString(headBytes); HandshakeData handshakeData = socket.Handshake; if (TryParseHandshake(message, handshakeData, out string error)) { if (handshakeData.ParamItems.ContainsKey(HandshakeHeadKeys.SecKey1) && handshakeData.ParamItems.ContainsKey(HandshakeHeadKeys.SecKey2)) { int remainBytesNum = buffer.Length - headLength; if (!handshakeData.IsClient && remainBytesNum == 8) { byte[] secKey3Bytes = new byte[remainBytesNum]; Buffer.BlockCopy(buffer, headBytes.Length, secKey3Bytes, 0, secKey3Bytes.Length); handshakeData.ParamItems[HandshakeHeadKeys.SecKey3] = secKey3Bytes; } else if (handshakeData.IsClient && remainBytesNum == 16) { byte[] secKey3Bytes = new byte[remainBytesNum]; Buffer.BlockCopy(buffer, headBytes.Length, secKey3Bytes, 0, secKey3Bytes.Length); handshakeData.ParamItems[HandshakeHeadKeys.SecAccept] = secKey3Bytes; } else { //data not complate, wait receive return(HandshakeResult.Wait); } } if (!handshakeData.IsClient) { if (!ResponseHandshake(socket, handshakeData)) { //TraceLog.ReleaseWriteDebug("Client {0} handshake fail, message:\r\n{2}", session.Socket.RemoteEndPoint, message); return(HandshakeResult.Close); } dataToken.ByteArrayForHandshake = null; socket.Handshake.Handshaked = true; return(HandshakeResult.Success); } if (CheckSignKey(handshakeData)) { dataToken.ByteArrayForHandshake = null; socket.Handshake.Handshaked = true; return(HandshakeResult.Success); } return(HandshakeResult.Close); } logger.Warn("Client {0} handshake {1} error, detail\r\n{2}", socket.RemoteEndPoint, error, message); return(HandshakeResult.Close); }