/// <summary> /// /// </summary> /// <param name="socket"></param> /// <param name="handshakeData"></param> /// <returns></returns> protected override bool ResponseHandshake(TNSocket socket, HandshakeData handshakeData) { string secKey1; string secKey2; byte[] secKey3; if (handshakeData.ParamItems.TryGet(HandshakeHeadKeys.SecKey1, out secKey1) && handshakeData.ParamItems.TryGet(HandshakeHeadKeys.SecKey2, out secKey2) && handshakeData.ParamItems.TryGet(HandshakeHeadKeys.SecKey3, out secKey3)) { //The minimum version support StringBuilder response = new StringBuilder(); response.AppendLine(HandshakeHeadKeys.RespHead_00); response.AppendLine(HandshakeHeadKeys.RespUpgrade00); response.AppendLine(HandshakeHeadKeys.RespConnection); string origin; if (handshakeData.ParamItems.TryGet(HandshakeHeadKeys.Origin, out origin)) { response.AppendLine(string.Format(HandshakeHeadKeys.RespOriginLine, origin)); } response.AppendLine(string.Format(HandshakeHeadKeys.SecLocation, handshakeData.UriSchema, handshakeData.Host, handshakeData.UrlPath)); if (!string.IsNullOrEmpty(handshakeData.Protocol)) { response.AppendLine(string.Format(HandshakeHeadKeys.RespProtocol, handshakeData.Protocol)); } response.AppendLine(); Handler.SendMessage(socket, response.ToString(), Encoding, result => { }); //Encrypt message byte[] securityKey = GetResponseSecurityKey(secKey1, secKey2, secKey3); Handler.SendMessage(socket, securityKey, result => { }); return(true); } return(false); }
private string GenreateKey(HandshakeData handshakeData) { string key; if (handshakeData.ParamItems.TryGet(HandshakeHeadKeys.SecKey, out key)) { return(GenreateKey(key)); } return(string.Empty); }
/// <summary> /// /// </summary> /// <param name="handshakeData"></param> /// <returns></returns> protected override bool CheckSignKey(HandshakeData handshakeData) { byte[] secAccept; byte[] signKey; if (handshakeData.ParamItems.TryGet(HandshakeHeadKeys.SecAccept, out secAccept) && handshakeData.ParamItems.TryGet(HandshakeHeadKeys.SecSignKey, out signKey)) { return(secAccept.IndexOf(signKey) != -1); } return(false); }
/// <summary> /// /// </summary> /// <param name="handshakeData"></param> /// <returns></returns> protected override bool CheckSignKey(HandshakeData handshakeData) { if (handshakeData.WebSocketVersion < _version) { return(base.CheckSignKey(handshakeData)); } string signKey; string accecpKey; if (handshakeData.ParamItems.TryGet(HandshakeHeadKeys.SecAccept, out accecpKey) && handshakeData.ParamItems.TryGet(HandshakeHeadKeys.SecSignKey, out signKey)) { return(string.Equals(signKey, accecpKey)); } return(false); }
/// <summary> /// /// </summary> /// <param name="handshake"></param> /// <param name="cookieStr"></param> /// <returns></returns> 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()); } } }
/// <summary> /// /// </summary> /// <param name="socket"></param> /// <param name="handshakeData"></param> /// <returns></returns> protected override bool ResponseHandshake(TNSocket socket, HandshakeData handshakeData) { if (handshakeData.WebSocketVersion < _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(); Handler.SendMessage(socket, response.ToString(), Encoding, result => { }); return(true); }
/// <summary> /// /// </summary> /// <param name="handshakeData"></param> /// <returns></returns> protected abstract bool CheckSignKey(HandshakeData handshakeData);
/// <summary> /// /// </summary> /// <param name="socket"></param> /// <param name="handshakeData"></param> protected abstract bool ResponseHandshake(TNSocket socket, HandshakeData handshakeData);
/// <summary> /// /// </summary> /// <param name="message"></param> /// <param name="handshakeData"></param> /// <param name="error"></param> /// <returns></returns> 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); } bool isResponse = headParams[0] == HandshakeHeadKeys.HttpVersion; if (!isResponse) { if (Handler.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 = value.ToInt(); 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); }
/// <summary> /// Receive handshake /// </summary> /// <param name="ioEventArgs"></param> /// <param name="dataToken"></param> /// <param name="data"></param> /// <returns></returns> internal HandshakeResult Receive(SocketAsyncEventArgs ioEventArgs, DataToken dataToken, byte[] data) { if (dataToken.byteArrayForHandshake == null) { dataToken.byteArrayForHandshake = new List <byte>(data); } else { dataToken.byteArrayForHandshake.AddRange(data); } 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 = dataToken.Socket.Handshake; string error; if (TryParseHandshake(message, handshakeData, out 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) { bool result = ResponseHandshake(dataToken.Socket, handshakeData); if (!result) { TraceLog.ReleaseWriteDebug("Client {0} handshake fail, message:\r\n{2}", dataToken.Socket.RemoteEndPoint, message); return(HandshakeResult.Close); } dataToken.byteArrayForHandshake = null; dataToken.Socket.Handshake.Handshaked = true; return(HandshakeResult.Success); } if (CheckSignKey(handshakeData)) { dataToken.byteArrayForHandshake = null; dataToken.Socket.Handshake.Handshaked = true; return(HandshakeResult.Success); } return(HandshakeResult.Close); } TraceLog.WriteWarn("Client {0} handshake {1}error, detail\r\n{2}", dataToken.Socket.RemoteEndPoint, error, message); return(HandshakeResult.Close); }