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); }
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); }