Exemplo n.º 1
0
        public static WSHttpRequest ProcessHandShakeData(byte[] data, int offset, int size)
        {
            string body  = Encoding.ASCII.GetString(data, offset, size);
            Match  match = ProtoConfig.REQUEST_REGEX.Match(body);

            if (!match.Success)
            {
                return(null);
            }

            WSHttpRequest request = new WSHttpRequest
            {
                method = match.Groups["method"].Value,
                path   = match.Groups["path"].Value,
                body   = match.Groups["body"].Value
            };

            CaptureCollection fields = match.Groups["field_name"].Captures;
            CaptureCollection values = match.Groups["field_value"].Captures;
            int count = fields.Count;

            for (int i = 0; i < count; i++)
            {
                string name  = fields[i].ToString();
                string value = values[i].ToString();
                request.headers[name] = value;
            }
            return(request);
        }
Exemplo n.º 2
0
        public static byte[] ProcessHybi13Handshake(WSHttpRequest request, string subProtocol)
        {
            StringBuilder builder = new StringBuilder();

            builder.Append("HTTP/1.1 101 Switching Protocols\r\n");
            builder.Append("Upgrade: websocket\r\n");
            builder.Append("Connection: Upgrade\r\n");

            if (!string.IsNullOrEmpty(subProtocol))
            {
                builder.Append($"Sec-WebSocket-Protocol: {subProtocol}\r\n");
            }

            string responseKey =
                Convert.ToBase64String(
                    SHA1.Create().ComputeHash(Encoding.ASCII.GetBytes(request["Sec-WebSocket-Key"] + ProtoConfig.WSRespGuid)));

            builder.Append($"Sec-WebSocket-Accept: {responseKey}\r\n");
            builder.Append("\r\n");
            // Logger.Info( builder.ToString() );
            return(Encoding.ASCII.GetBytes(builder.ToString()));
        }
Exemplo n.º 3
0
        protected override void ProcessData(StreamBuffer cache)
        {
            while (true)
            {
                if (cache.length == 0)
                {
                    break;
                }

                if (!this._handshakeComplete)
                {
                    WSHttpRequest request = WSHelper.ProcessHandShakeData(cache.GetBuffer(), 0, cache.length);
                    if (request == null)
                    {
                        break;
                    }

                    //Logger.Log( request );
                    string subProtocol  = WSHelper.Negotiate(this.subProtocols, request.subProtocols);
                    byte[] responseData = WSHelper.ProcessHybi13Handshake(request, subProtocol);
                    if (responseData == null)
                    {
                        break;
                    }

                    this._handshakeComplete = true;
                    this.SendWithoutHeader(responseData, 0, responseData.Length);

                    cache.Clear();

                    NetEvent netEvent = NetworkMgr.instance.PopEvent();
                    netEvent.type    = NetEvent.Type.Establish;
                    netEvent.session = this.session;
                    NetworkMgr.instance.PushEvent(netEvent);

                    break;
                }
                {
                    bool isEof = WSHelper.ProcessClientData(cache.GetBuffer(), 0, cache.length, this._readState, out int len, out WSOPCode op);
                    if (len < 0)  //载体没有读取完
                    {
                        break;
                    }

                    //截断当前缓冲区
                    cache.Strip(len, cache.length - len);
                    if (isEof)  //分片已结束
                    {
                        if (op == WSOPCode.Close)
                        {
                            //到这里代表连接关闭了
                            this._readState.Clear();
                            this.OnError("client closed");
                            break;
                        }

                        byte[] data = this._readState.ToArray();
                        this._readState.Clear();

                        NetEvent netEvent = NetworkMgr.instance.PopEvent();
                        netEvent.type    = NetEvent.Type.Recv;
                        netEvent.session = this.session;
                        netEvent.data    = data;
                        NetworkMgr.instance.PushEvent(netEvent);
                    }
                }
            }
        }