Пример #1
0
        public static void ProcessFrame(FrameType frameType, byte[] data, Action<string> onMessage, Fleck2Extensions.Action onClose, Action<byte[]> onBinary)
        {
            switch (frameType)
            {
            case FrameType.Close:
                if (data.Length == 1 || data.Length>125)
                    throw new WebSocketException(WebSocketStatusCodes.ProtocolError);

                if (data.Length >= 2)
                {
                    var closeCode = (ushort) (data.Take(2).ToArray().ToLittleEndianInt());
                    if (!WebSocketStatusCodes.Contains(closeCode) && (closeCode < 3000 || closeCode > 4999))
                        throw new WebSocketException(WebSocketStatusCodes.ProtocolError);
                }

                if (data.Length > 2)
                    ReadUtf8PayloadData(data.Skip(2));

                onClose();
                break;
            case FrameType.Binary:
                onBinary(data);
                break;
            case FrameType.Text:
                onMessage(ReadUtf8PayloadData(data));
                break;
            default:
                FleckLog.Debug("Received unhandled " + frameType);
                break;
            }
        }
Пример #2
0
 public static IHandler Create(WebSocketHttpRequest request, Action<string> onMessage, Fleck2Extensions.Action onClose, Action<byte[]> onBinary)
 {
     var readState = new ReadState();
     return new ComposableHandler
     {
         Handshake = () => BuildHandshake(request),
         TextFrame = data => FrameData(Encoding.UTF8.GetBytes(data), FrameType.Text),
         BinaryFrame = data => FrameData(data, FrameType.Binary),
         CloseFrame = i => FrameData(i.ToBigEndianBytes<ushort>(), FrameType.Close),
         ReceiveData = bytes => ReceiveData(bytes, readState, (op, data) => ProcessFrame(op, data, onMessage, onClose, onBinary))
     };
 }
Пример #3
0
        public void Accept(Fleck2Extensions.Action<ISocket> callback, Fleck2Extensions.Action<Exception> error)
        {
            Fleck2Extensions.Func<IAsyncResult, ICancellationToken, ISocket> end = (result, token) =>
            {
                token.ThrowIfCancellationRequested();
                return new SocketWrapper(_socket.EndAccept(result));
            };

            _socketFactory.HandleAsync(_socket.BeginAccept, end, result =>
            {
                result.Success(callback);
                result.Error(error);
            });
        }
Пример #4
0
 public WebSocketConnection(ISocket socket, Action<IWebSocketConnection> initialize, 
     Fleck2Extensions.Func<byte[], WebSocketHttpRequest> parseRequest, 
     Fleck2Extensions.Func<WebSocketHttpRequest, IHandler> handlerFactory)
 {
     Socket = socket;
     OnOpen = () => { };
     OnClose = () => { };
     OnMessage = x => { };
     OnBinary = x => { };
     OnError = x => { };
     _initialize = initialize;
     _handlerFactory = handlerFactory;
     _parseRequest = parseRequest;
 }
Пример #5
0
        public static IHandler BuildHandler(WebSocketHttpRequest request, Action<string> onMessage, Fleck2Extensions.Action onClose, Action<byte[]> onBinary)
        {
            var version = GetVersion(request);

            switch (version)
            {
                case "76":
                    return Draft76Handler.Create(request, onMessage);
                case "7":
                case "8":
                case "13":
                    return Hybi13Handler.Create(request, onMessage, onClose, onBinary);
            }

            throw new WebSocketException(WebSocketStatusCodes.UnsupportedDataType);
        }
Пример #6
0
        public static void ReceiveData(List<byte> data, ReadState readState, Fleck2Extensions.Action<FrameType, byte[]> processFrame)
        {
            while (data.Count >= 2)
            {
                var isFinal = (data[0] & 128) != 0;
                var reservedBits = (data[0] & 112);
                var frameType = (FrameType)(data[0] & 15);
                var isMasked = (data[1] & 128) != 0;
                var length = (data[1] & 127);

                if (!isMasked
                    || !Enum.IsDefined(typeof(FrameType), frameType)
                    || reservedBits != 0 //Must be zero per spec 5.2
                    || (frameType == FrameType.Continuation && !readState.FrameType.HasValue))
                    throw new WebSocketException(WebSocketStatusCodes.ProtocolError);

                var index = 2;
                int payloadLength;

                switch (length)
                {
                    case 127:
                        if (data.Count < index + 8)
                            return; //Not complete
                        payloadLength = data.Skip(index).Take(8).ToArray().ToLittleEndianInt();
                        index += 8;
                        break;
                    case 126:
                        if (data.Count < index + 2)
                            return; //Not complete
                        payloadLength = data.Skip(index).Take(2).ToArray().ToLittleEndianInt();
                        index += 2;
                        break;
                    default:
                        payloadLength = length;
                        break;
                }

                if (data.Count < index + 4)
                    return; //Not complete

                var maskBytes = data.Skip(index).Take(4).ToList();

                index += 4;

                if (data.Count < index + payloadLength)
                    return; //Not complete

                var i = 0;
                var payload = data.Skip(index)
                              .Take(payloadLength)
                              .Select(value => (byte)(value ^ maskBytes[i++ % 4]));

                readState.Data.AddRange(payload);
                data.RemoveRange(0, index + payloadLength);

                if (frameType != FrameType.Continuation)
                    readState.FrameType = frameType;

                if (!isFinal || !readState.FrameType.HasValue)
                {
                    continue;
                }

                var stateData = readState.Data.ToArray();
                var stateFrameType = readState.FrameType;
                readState.Clear();

                processFrame(stateFrameType.Value, stateData);
            }
        }
Пример #7
0
 private void SendBytes(byte[] bytes, Fleck2Extensions.Action callback = null)
 {
     Socket.Send(bytes, () =>
     {
         FleckLog.Debug("Sent " + bytes.Length + " bytes");
         if (callback != null)
             callback();
     },
     e =>
     {
         if (e is IOException)
             FleckLog.Debug("Failed to send. Disconnecting.", e);
         else
             FleckLog.Info("Failed to send. Disconnecting.", e);
         CloseSocket();
     });
 }
Пример #8
0
        public void Authenticate(X509Certificate2 certificate, Fleck2Extensions.Action callback, Fleck2Extensions.Action<Exception> error)
        {
            var ssl = new SslStream(_stream, false);
            _stream = ssl;

            Fleck2Extensions.Func<AsyncCallback, object, IAsyncResult> begin =
                (cb, s) => ssl.BeginAuthenticateAsServer(certificate, false, SslProtocols.Tls, false, cb, s);

            _socketFactory.HandleAsyncVoid(begin, ssl.EndAuthenticateAsServer, result =>
                {
                    result.Success(callback);
                    result.Error(error);
                });
        }
Пример #9
0
        public void Send(byte[] buffer, Fleck2Extensions.Action callback, Fleck2Extensions.Action<Exception> error)
        {
            Fleck2Extensions.Func<AsyncCallback, object, IAsyncResult> begin =
                            (cb, s) => _stream.BeginWrite(buffer, 0, buffer.Length, cb, s);

            _socketFactory.HandleAsyncVoid(begin, _stream.EndWrite, result =>
            {
                result.Success(callback);
                result.Error(error);
            });
        }
Пример #10
0
        public void Receive(byte[] buffer, Fleck2Extensions.Action<int> callback, Fleck2Extensions.Action<Exception> error, int offset = 0)
        {
            Fleck2Extensions.Func<AsyncCallback, object, IAsyncResult> begin = (cb, data) =>
            _stream.BeginRead(buffer, offset, buffer.Length, cb, data);

            _socketFactory.HandleAsync(begin, _stream.EndRead, result =>
            {
                result.Success(callback);
                result.Error(error);
            });
        }