Esempio n. 1
0
        protected override int ProcessIncoming(NetContext context, Connection connection, Stream incoming)
        {
            if (incoming.Length < 2)
            {
                return(0);                     // can't read that; frame takes at minimum two bytes
            }
            byte[] buffer = null;
            try
            {
                buffer = context.GetBuffer();
                int read;
                // read as much as possible up to 14 bytes; that gives us space for 2 bytes frame header, 8 bytes length, and 4 bytes mask
                read = NetContext.TryFill(incoming, buffer, 14);

                int headerLength;
                var frame = WebSocketsFrame.TryParseFrameHeader(buffer, read, out headerLength);

                if (frame == null)
                {
                    return(0);
                }
                int payloadLen = frame.PayloadLength;

#if VERBOSE
                Debug.WriteLine("Parsed header from: " + BitConverter.ToString(buffer, 0, headerLength));
#endif

                if (incoming.Length < headerLength + payloadLen)
                {
                    return(0);                                             // not enough data to read the payload
                }
                if (payloadLen != 0)
                {
                    Stream payload = null;
                    try
                    {
                        payload = new BufferStream(context, context.Handler.MaxIncomingQuota);
                        if (read != headerLength)
                        {
                            incoming.Position -= (read - headerLength);                       // we got it wrong...
                        }
                        Copy(incoming, payload, buffer, frame.Mask, payloadLen);

                        if (payloadLen != payload.Length)
                        {
                            throw new InvalidOperationException("I munged the data");
                        }
                        frame.Payload = payload;
                        payload       = null;
                    }
                    finally
                    {
                        if (payload != null)
                        {
                            payload.Dispose();
                        }
                    }
                }
                foreach (var final in ApplyExtensions(context, connection, frame, true))
                {
                    ProcessFrame(context, connection, final);
                }
                return(headerLength + payloadLen);
            }
            finally
            {
                context.Recycle(buffer);
            }
        }