Beispiel #1
0
 public static Task SendControlFrame(Synchronized <Stream> stream, ControlFrame frame)
 {
     return(SendFixedFrame(stream, frame.FrameType.ToControlFrameOpcode(),
                           frame.Payload.Length, false, (buffer, appDataOffset) => {
         Buffer.BlockCopy(frame.Payload, 0, buffer, appDataOffset, frame.Payload.Length);
     }));
 }
 public WebSocketSession(Stream stream, string requestUrl, IPEndPoint remoteAddress)
 {
     RequestUrl     = requestUrl;
     RemoteEndPoint = remoteAddress;
     OutputStream   = new Synchronized <Stream>(stream);
     InputStream    = new Synchronized <Stream>(stream);
 }
Beispiel #3
0
        protected override void Dispose(bool disposing)
        {
            if (UnderlyingHolder != null)
            {
                UnderlyingHolder.Dispose();
                UnderlyingHolder = null;
            }

            base.Dispose(disposing);
        }
Beispiel #4
0
        public WebSocketInputStream(WebSocketProtocol.FrameHeader initialHeader,
                                    Synchronized <Stream> .LockHolder underlyingHolder)
        {
            if (!underlyingHolder.LockedObject.CanRead)
            {
                throw new ArgumentException("Need readable Stream", "underlying");
            }

            Underlying       = underlyingHolder.LockedObject;
            UnderlyingHolder = underlyingHolder;
            BeginReadingFrame(initialHeader);
        }
Beispiel #5
0
        public static async Task SendStream(Synchronized <Stream> sSocketStream, Stream dataStream, bool masking)
        {
            using (var socketStreamHolder = await sSocketStream) {
                var socketStream = socketStreamHolder.LockedObject;

                int    appDataOffset;
                byte[] header, maskData;
                BuildFrameHeader(FrameOpcode.Binary, checked ((int)dataStream.Length), masking, out maskData, out header, out appDataOffset, bareHeader: true);

                await socketStream.WriteAsync(header, 0, header.Length);

                if (masking)
                {
                    socketStream = new MaskingStream(socketStream, maskData);
                }

                await dataStream.CopyToAsync(socketStream);
            }
        }
Beispiel #6
0
        private static async Task SendFixedFrame(Synchronized <Stream> sStream, FrameOpcode opcode, int appDataLength, bool masking, Action <byte[], int> dataWriter)
        {
            int appDataOffset;

            byte[] buffer, maskData;
            BuildFrameHeader(opcode, appDataLength, masking, out maskData, out buffer, out appDataOffset, bareHeader: false);

            dataWriter(buffer, appDataOffset);

            if (masking)
            {
                for (int i = 0; i < appDataLength; i++)
                {
                    buffer[i + appDataOffset] ^= maskData[i % 4];
                }
            }

            using (var streamHolder = await sStream)
                await streamHolder.LockedObject.WriteAsync(buffer, 0, buffer.Length);
        }
 internal LockHolder(Synchronized <T> parent)
 {
     Parent = parent;
 }
Beispiel #8
0
        public static async Task <object> ReadFrameGroupLockAcquired(Synchronized <Stream> .LockHolder streamHolder, Func <ControlFrame, Task> controlFrameHandler, CancellationToken token, bool loop = true)
        {
            var stream        = streamHolder.LockedObject;
            var textFragments = new List <byte[]>(1);

            do
            {
                var header = await ReadFrameHeader(stream, token);

                switch (header.Opcode)
                {
                case FrameOpcode.Binary:
                    if (textFragments.Count > 0)
                    {
                        throw new InvalidDataException();
                    }
                    return(new WebSocketInputStream(header, streamHolder));

                case FrameOpcode.Continuation:
                // we don't have to expect that the client breaks the protocol
                // if this continues binary, we already returned the stream
                case FrameOpcode.Text:
                    var streamAfterMasking = header.IsMasked ? new MaskingStream(stream, header.MaskData) : stream;
                    var buffer             = await streamAfterMasking.ReadAllBytesAsync(header.PayloadLength, token);

                    textFragments.Add(buffer);
                    if (header.GroupIsComplete)
                    {
                        if (textFragments.Count == 1)
                        {
                            streamHolder.Dispose();
                            return(Encoding.UTF8.GetString(buffer));
                        }

                        var finalBuffer = new byte[textFragments.Sum(array => array.Length)];
                        int offset      = 0;
                        foreach (var part in textFragments)
                        {
                            Buffer.BlockCopy(part, 0, finalBuffer, offset, part.Length);
                            offset += part.Length;
                        }

                        streamHolder.Dispose();
                        return(Encoding.UTF8.GetString(finalBuffer));
                    }

                    break;

                case FrameOpcode.Ping:
                case FrameOpcode.Pong:
                case FrameOpcode.Close:
                    await HandleControlFrame(header, stream, controlFrameHandler, token);

                    if (header.Opcode == FrameOpcode.Close)
                    {
                        return(null);
                    }
                    break;

                default:
                    throw new InvalidDataException("unknown opcode");
                }
            } while (loop);
            streamHolder.Dispose();
            return(null);
        }
Beispiel #9
0
 public static async Task <object> ReadFrameGroup(Synchronized <Stream> stream, Func <ControlFrame, Task> controlFrameHandler, CancellationToken token)
 {
     return(await ReadFrameGroupLockAcquired(await stream, controlFrameHandler, token));
 }
Beispiel #10
0
 public static Task SendByteArrayFrame(Synchronized <Stream> stream, byte[] data, int offset, int length, bool masking)
 {
     return(SendFixedFrame(stream, FrameOpcode.Binary, length, masking, (buffer, appDataOffset) => {
         Buffer.BlockCopy(data, offset, buffer, appDataOffset, length);
     }));
 }
Beispiel #11
0
 public static Task SendTextFrame(Synchronized <Stream> stream, string message, bool masking)
 {
     return(SendFixedFrame(stream, FrameOpcode.Text, Encoding.UTF8.GetByteCount(message), masking, (buffer, appDataOffset) => {
         Encoding.UTF8.GetBytes(message, 0, message.Length, buffer, appDataOffset);
     }));
 }