Exemple #1
0
        void HandleReceivedData(RecvEventCode recvCode)
        {
            switch (recvCode)
            {
            case RecvEventCode.HasSomeData:

                //parse recv msg
                switch (this.webSocketReqParser.ParseRecvData())
                {
                //in this version all data is copy into WebSocketRequest
                //so we can reuse recv buffer
                //TODO: review this, if we need to copy?,

                case ProcessReceiveBufferResult.Complete:
                {
                    //you can choose ...
                    //invoke webSocketReqHandler in this thread or another thread
                    while (webSocketReqParser.ReqCount > 0)
                    {
                        WebSocketRequest req = webSocketReqParser.Dequeue();
                        webSocketReqHandler(req, webSocketResp);
                    }
                    recvIO.StartReceive();
                    //***no code after StartReceive***
                }
                    return;

                case ProcessReceiveBufferResult.NeedMore:
                {
                    recvIO.StartReceive();
                    //***no code after StartReceive***
                }
                    return;

                case ProcessReceiveBufferResult.Error:
                default:
                    throw new NotSupportedException();
                }

            case RecvEventCode.NoMoreReceiveData:
            {
            }
            break;

            case RecvEventCode.SocketError:
            {
            }
            break;
            }
        }
 public WebSocketReqQueueItem(WebSocketConnectionBase conn, WebSocketRequest req)
 {
     _conn    = conn;
     _request = req;
 }
        bool ReadHeader()
        {
            if (!myBufferStream.Ensure(2))
            {
                myBufferStream.BackupRecvIO();
                return false;
            }
            //----------------------------------------------------------
            //when we read header we start a new websocket request
            currentReq = new WebSocketRequest();
            incommingReqs.Enqueue(currentReq);


            byte b1 = myBufferStream.ReadByte();
            // FIN
            Fin fin = (b1 & (1 << 7)) == (1 << 7) ? Fin.Final : Fin.More;

            // RSV1
            Rsv rsv1 = (b1 & (1 << 6)) == (1 << 6) ? Rsv.On : Rsv.Off;

            // RSV2
            Rsv rsv2 = (b1 & (1 << 5)) == (1 << 5) ? Rsv.On : Rsv.Off;

            // RSV3
            Rsv rsv3 = (b1 & (1 << 4)) == (1 << 4) ? Rsv.On : Rsv.Off;
            //----------------------------------------------------------   
            // Opcode
            currentOpCode = (Opcode)(b1 & 0x0f);//4 bits  
            //----------------------------------------------------------  
            byte b2 = myBufferStream.ReadByte();          //mask

            //----------------------------------------------------------  
            //finish first 2 bytes  
            // MASK
            Mask currentMask = (b2 & (1 << 7)) == (1 << 7) ? Mask.On : Mask.Off;
            //we should check receive frame here ... 
            this.useMask = currentMask == Mask.On;
            if (currentMask == Mask.Off)
            {
                //if this act as WebSocketServer 
                //erro packet ? 
                throw new NotSupportedException();
            }
            else
            {

            }
            //----------------------------------------------------------
            // Payload Length
            byte payloadLen = (byte)(b2 & 0x7f); //is 7 bits of the b2 
            if (fin == Fin.More || currentOpCode == Opcode.Cont)
            {
                //process fragment frame *** 
                throw new NotSupportedException();
            }
            else
            {

            }

            //----------------------------------------------------------
            //translate opcode ....
            string errCode = null;
            switch (currentOpCode)
            {
                case Opcode.Cont:
                    {
                        //continue
                    }
                    break;
                case Opcode.Text: //this is data
                    {
                        if (rsv1 == Rsv.On)
                        {
                            errCode = "A non data frame is compressed.";
                        }
                    }
                    break;
                case Opcode.Binary: //this is data
                    {
                        if (rsv1 == Rsv.On)
                        {
                            errCode = "A non data frame is compressed.";
                        }
                    }
                    break;
                case Opcode.Close: //control
                    {
                        if (fin == Fin.More)
                        {
                            errCode = "A control frame is fragmented.";
                        }
                        else if (payloadLen > 125)
                        {
                            errCode = "A control frame has a long payload length.";
                        }
                    }
                    break;
                case Opcode.Ping: //control
                case Opcode.Pong: //control
                    {
                        if (fin == Fin.More)
                        {
                            errCode = "A control frame is fragmented.";
                        }
                        else if (payloadLen > 125)
                        {
                            errCode = "A control frame has a long payload length.";
                        }
                    }
                    break;
                default:
                    {
                        if (fin != Fin.More)
                        {
                            errCode = "An unsupported opcode.";
                        }
                    }
                    break;
            }
            //----------------------------------------------------------
            if (errCode != null)
            {
                //report error
                throw new NotSupportedException();
            }
            //----------------------------------------------------------  
            this._currentPacketLen = payloadLen;
            currentReq.OpCode = currentOpCode;
            this._currentMaskLen = (currentMask == Mask.On) ? 4 : 0;
            //----------------------------------------------------------
            if (payloadLen >= 126)
            {
                this.parseState = ParseState.ReadExtendedPayloadLen;
                return true;
            }
            //----------------------------------------------------------
            this.parseState = this._currentMaskLen > 0 ?
                ParseState.ReadMask :
                ParseState.ExpectBody;
            return true;
        }
 public void HandleWebSocket(WebSocketRequest req, WebSocketResponse resp)
 {
     resp.Write("server:" + (count++));
 }
        bool ReadHeader()
        {
            if (!_myBufferStream.Ensure(2))
            {
                return(false);
            }
            //----------------------------------------------------------
            //when we read header we start a new websocket request
            _currentReq = new WebSocketRequest(this.OwnerWebSocketConnBase);

#if DEBUG
            //byte[] peek = new byte[8];
            //_myBufferStream.dbugPeekBytes(peek, 8);

            //System.Text.StringBuilder stbuilder = new System.Text.StringBuilder();
            //for (int i = 0; i < peek.Length; ++i)
            //{
            //    stbuilder.Append((char)peek[i]);
            //}
#endif

            byte b1 = _myBufferStream.ReadByte();

            // FIN
            Fin fin = (b1 & (1 << 7)) == (1 << 7) ? Fin.Final : Fin.More;

            // RSV1
            Rsv rsv1 = (b1 & (1 << 6)) == (1 << 6) ? Rsv.On : Rsv.Off;

            // RSV2
            Rsv rsv2 = (b1 & (1 << 5)) == (1 << 5) ? Rsv.On : Rsv.Off;

            // RSV3
            Rsv rsv3 = (b1 & (1 << 4)) == (1 << 4) ? Rsv.On : Rsv.Off;
            //----------------------------------------------------------
            // Opcode
            _currentOpCode = (Opcode)(b1 & 0x0f);//4 bits
            //----------------------------------------------------------

            if (rsv1 == Rsv.On)
            {
                _currentReq.Compression = OwnerWebSocketConnBase.Compression;
            }


            byte b2 = _myBufferStream.ReadByte();          //mask

            //----------------------------------------------------------
            //finish first 2 bytes
            // MASK
            Mask currentMask = (b2 & (1 << 7)) == (1 << 7) ? Mask.On : Mask.Off;
            //we should check receive frame here ...

            if (_asClientContext)
            {
                //as client context (we are in client context)
                if (currentMask != Mask.Off)
                {
                    throw new NotSupportedException();
                }
                _useMask = false;
            }
            else
            {
                //as server context (we are in server context)
                //data from client must useMask
                if (currentMask != Mask.On)
                {
                    throw new NotSupportedException();
                }
                _useMask = true;
            }
            //----------------------------------------------------------
            // Payload Length
            byte payloadLen = (byte)(b2 & 0x7f); //is 7 bits of the b2

            bool allowMoreFrame = false;
            if (fin == Fin.More || _currentOpCode == Opcode.Cont)
            {
                throw new NotSupportedException();
            }
            else
            {
            }

            //----------------------------------------------------------
            //translate opcode ....
            string errCode = null;
            switch (_currentOpCode)
            {
            case Opcode.Cont:
            {
                //continue
            }
            break;

            case Opcode.Text:     //this is data
            {
                if (rsv1 == Rsv.On && _currentReq.Compression == WebSocketContentCompression.NoCompression)
                {
                    errCode = "A non data frame is compressed.";
                }
            }
            break;

            case Opcode.Binary:     //this is data
            {
                if (rsv1 == Rsv.On && _currentReq.Compression == WebSocketContentCompression.NoCompression)
                {
                    errCode = "A non data frame is compressed.";
                }
            }
            break;

            case Opcode.Close:     //control
            {
                if (fin == Fin.More)
                {
                    errCode = "A control frame is fragmented.";
                }
                else if (payloadLen > 125)
                {
                    errCode = "A control frame has a long payload length.";
                }
            }
            break;

            case Opcode.Ping:     //control
            case Opcode.Pong:     //control
            {
                if (fin == Fin.More)
                {
                    errCode = "A control frame is fragmented.";
                }
                else if (payloadLen > 125)
                {
                    errCode = "A control frame has a long payload length.";
                }
            }
            break;

            default:
            {
                if (fin != Fin.More)
                {
                    errCode = "An unsupported opcode.";
                }
            }
            break;
            }
            //----------------------------------------------------------
            if (errCode != null)
            {
                //report error
                throw new NotSupportedException();
            }
            //----------------------------------------------------------
            _currentPacketLen  = payloadLen;
            _currentReq.OpCode = _currentOpCode;
            _currentMaskLen    = (currentMask == Mask.On) ? 4 : 0;
            //----------------------------------------------------------
            if (payloadLen >= 126)
            {
                _parseState = ParseState.ReadExtendedPayloadLen;
                return(true);
            }
            //----------------------------------------------------------
            _parseState = _currentMaskLen > 0 ?
                          ParseState.ReadMask :
                          ParseState.ExpectBody;
            return(true);
        }
        internal ProcessReceiveBufferResult ParseRecvData()
        {
            _myBufferStream.AppendNewRecvData();

            for (; ;)
            {
                switch (_parseState)
                {
                default:
                    throw new NotSupportedException();

                case ParseState.Init:

                    if (!ReadHeader())
                    {
                        return(ProcessReceiveBufferResult.NeedMore);
                    }
                    break;

                case ParseState.ReadExtendedPayloadLen:

                    if (!ReadPayloadLen())
                    {
                        return(ProcessReceiveBufferResult.NeedMore);
                    }
                    break;

                case ParseState.ReadMask:

                    if (!ReadMask())
                    {
                        return(ProcessReceiveBufferResult.NeedMore);
                    }

                    break;

                case ParseState.ExpectBody:
                {
                    //-------------------------------------
                    switch (_currentOpCode)
                    {
                    //ping,
                    //pong
                    default:
                        throw new NotSupportedException();

                    case Opcode.Binary:
                    case Opcode.Text:
                    case Opcode.Close:
                        break;

                    case Opcode.Pong:
                    case Opcode.Ping:
                        break;
                    }

                    if (!ReadBodyContent(_currentPacketLen))
                    {
                        return(ProcessReceiveBufferResult.NeedMore);
                    }

                    if (_myBufferStream.IsEnd())
                    {
                        _parseState = ParseState.Init;
                        _myBufferStream.Clear();

                        _newResultHandler(_currentReq);
                        _currentReq = null;
                        return(ProcessReceiveBufferResult.Complete);
                    }
                    else
                    {
                        //more than 1 msg?
                        _parseState = ParseState.Init;
                        //
                        _newResultHandler(_currentReq);
                        _currentReq = null;
                    }
                }
                break;
                }
            }
        }
        bool ReadHeader()
        {
            if (!myBufferStream.Ensure(2))
            {
                myBufferStream.BackupRecvIO();
                return(false);
            }
            //----------------------------------------------------------
            //when we read header we start a new websocket request
            currentReq = new WebSocketRequest(this._ownerContext);
            incommingReqs.Enqueue(currentReq);


            byte b1 = myBufferStream.ReadByte();
            // FIN
            Fin fin = (b1 & (1 << 7)) == (1 << 7) ? Fin.Final : Fin.More;

            // RSV1
            Rsv rsv1 = (b1 & (1 << 6)) == (1 << 6) ? Rsv.On : Rsv.Off;

            // RSV2
            Rsv rsv2 = (b1 & (1 << 5)) == (1 << 5) ? Rsv.On : Rsv.Off;

            // RSV3
            Rsv rsv3 = (b1 & (1 << 4)) == (1 << 4) ? Rsv.On : Rsv.Off;

            //----------------------------------------------------------
            // Opcode
            currentOpCode = (Opcode)(b1 & 0x0f); //4 bits
            //----------------------------------------------------------
            byte b2 = myBufferStream.ReadByte(); //mask

            //----------------------------------------------------------
            //finish first 2 bytes
            // MASK
            Mask currentMask = (b2 & (1 << 7)) == (1 << 7) ? Mask.On : Mask.Off;

            //we should check receive frame here ...
            this.useMask = currentMask == Mask.On;
            if (currentMask == Mask.Off)
            {
                //if this act as WebSocketServer
                //erro packet ?
                throw new NotSupportedException();
            }
            else
            {
            }
            //----------------------------------------------------------
            // Payload Length
            byte payloadLen = (byte)(b2 & 0x7f); //is 7 bits of the b2

            if (fin == Fin.More || currentOpCode == Opcode.Cont)
            {
                //process fragment frame ***
                throw new NotSupportedException();
            }
            else
            {
            }

            //----------------------------------------------------------
            //translate opcode ....
            string errCode = null;

            switch (currentOpCode)
            {
            case Opcode.Cont:
            {
                //continue
            }
            break;

            case Opcode.Text:     //this is data
            {
                if (rsv1 == Rsv.On)
                {
                    errCode = "A non data frame is compressed.";
                }
            }
            break;

            case Opcode.Binary:     //this is data
            {
                if (rsv1 == Rsv.On)
                {
                    errCode = "A non data frame is compressed.";
                }
            }
            break;

            case Opcode.Close:     //control
            {
                if (fin == Fin.More)
                {
                    errCode = "A control frame is fragmented.";
                }
                else if (payloadLen > 125)
                {
                    errCode = "A control frame has a long payload length.";
                }
            }
            break;

            case Opcode.Ping:     //control
            case Opcode.Pong:     //control
            {
                if (fin == Fin.More)
                {
                    errCode = "A control frame is fragmented.";
                }
                else if (payloadLen > 125)
                {
                    errCode = "A control frame has a long payload length.";
                }
            }
            break;

            default:
            {
                if (fin != Fin.More)
                {
                    errCode = "An unsupported opcode.";
                }
            }
            break;
            }
            //----------------------------------------------------------
            if (errCode != null)
            {
                //report error
                throw new NotSupportedException();
            }
            //----------------------------------------------------------
            this._currentPacketLen = payloadLen;
            currentReq.OpCode      = currentOpCode;
            this._currentMaskLen   = (currentMask == Mask.On) ? 4 : 0;
            //----------------------------------------------------------
            if (payloadLen >= 126)
            {
                this.parseState = ParseState.ReadExtendedPayloadLen;
                return(true);
            }
            //----------------------------------------------------------
            this.parseState = this._currentMaskLen > 0 ?
                              ParseState.ReadMask :
                              ParseState.ExpectBody;
            return(true);
        }