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);
 }
Exemplo n.º 3
0
        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) &&
Exemplo n.º 6
0
        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);
        }
Exemplo n.º 7
0
 protected abstract bool CheckSignKey(HandshakeData handshakeData);
Exemplo n.º 8
0
 protected abstract bool ResponseHandshake(WebSocket socket, HandshakeData handshakeData);
Exemplo n.º 9
0
        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);
        }