/// <summary>
        /// Performs the opening handshake
        /// When call this method you <c>MUST NOT</c> retain the <see cref="IFullHttpRequest"/> which is passed in.
        /// </summary>
        /// <param name="channel">Channel</param>
        /// <param name="req">HTTP Request</param>
        /// <param name="responseHeaders">Extra headers to add to the handshake response or <code>null</code> if no extra headers should be added</param>
        /// <param name="completion">the <see cref="IPromise"/> to be notified when the opening handshake is done</param>
        public void Handshake(IChannel channel, IFullHttpRequest req, HttpHeaders responseHeaders, IPromise completion)
        {
#if DEBUG
            if (Logger.DebugEnabled)
            {
                Logger.WebSocketVersionServerHandshake(channel, _version);
            }
#endif

            IFullHttpResponse response = NewHandshakeResponse(req, responseHeaders);
            IChannelPipeline  p        = channel.Pipeline;

            if (p.Get <HttpObjectAggregator>() is object)
            {
                _ = p.Remove <HttpObjectAggregator>();
            }
            if (p.Get <HttpContentCompressor>() is object)
            {
                _ = p.Remove <HttpContentCompressor>();
            }
            if (p.Get <CorsHandler>() is object)
            {
                _ = p.Remove <CorsHandler>();
            }
            if (p.Get <HttpServerExpectContinueHandler>() is object)
            {
                _ = p.Remove <HttpServerExpectContinueHandler>();
            }
            if (p.Get <HttpServerKeepAliveHandler>() is object)
            {
                _ = p.Remove <HttpServerKeepAliveHandler>();
            }

            IChannelHandlerContext ctx = p.Context <HttpRequestDecoder>();
            string encoderName;
            if (ctx is null)
            {
                // this means the user use an HttpServerCodec
                ctx = p.Context <HttpServerCodec>();
                if (ctx is null)
                {
                    _ = completion.TrySetException(ThrowHelper.GetInvalidOperationException_NoHttpDecoderAndServerCodec());
                    return;
                }

                encoderName = ctx.Name;
                _           = p.AddBefore(encoderName, "wsencoder", NewWebSocketEncoder());
                _           = p.AddBefore(encoderName, "wsdecoder", NewWebsocketDecoder());
            }
            else
            {
                _ = p.Replace(ctx.Name, "wsdecoder", NewWebsocketDecoder());

                encoderName = p.Context <HttpResponseEncoder>().Name;
                _           = p.AddBefore(encoderName, "wsencoder", NewWebSocketEncoder());
            }

            _ = channel.WriteAndFlushAsync(response).ContinueWith(RemoveHandlerAfterWriteAction, (completion, p, encoderName), TaskContinuationOptions.ExecuteSynchronously);
        }
 public Context CreateIncomingSession()
 {
     IChannel channel = Substitute.For<IChannel>();
     _currentSession = new Session(_localPort,  LimboLogs.Instance, channel);
     _pipeline.Get<ZeroNettyP2PHandler>().Returns(new ZeroNettyP2PHandler(_currentSession, LimboLogs.Instance));
     _localPeer.SessionCreated += Raise.EventWith(new object(), new SessionEventArgs(_currentSession));
     return this;
 }
示例#3
0
        public void Handshake(IChannel channel, IFullHttpRequest req, HttpHeaders responseHeaders, TaskCompletionSource completion)
        {
            if (Logger.DebugEnabled)
            {
                Logger.Debug("{} WebSocket version {} server handshake", channel, this.version);
            }

            IFullHttpResponse response = this.NewHandshakeResponse(req, responseHeaders);
            IChannelPipeline  p        = channel.Pipeline;

            if (p.Get <HttpObjectAggregator>() != null)
            {
                p.Remove <HttpObjectAggregator>();
            }

            if (p.Get <HttpContentCompressor>() != null)
            {
                p.Remove <HttpContentCompressor>();
            }

            IChannelHandlerContext ctx = p.Context <HttpRequestDecoder>();
            string encoderName;

            if (ctx == null)
            {
                // this means the user use a HttpServerCodec
                ctx = p.Context <HttpServerCodec>();
                if (ctx == null)
                {
                    completion.TrySetException(new InvalidOperationException("No HttpDecoder and no HttpServerCodec in the pipeline"));
                    return;
                }

                p.AddBefore(ctx.Name, "wsdecoder", this.NewWebsocketDecoder());
                p.AddBefore(ctx.Name, "wsencoder", this.NewWebSocketEncoder());
                encoderName = ctx.Name;
            }
            else
            {
                p.Replace(ctx.Name, "wsdecoder", this.NewWebsocketDecoder());

                encoderName = p.Context <HttpResponseEncoder>().Name;
                p.AddBefore(encoderName, "wsencoder", this.NewWebSocketEncoder());
            }

            channel.WriteAndFlushAsync(response).ContinueWith(t =>
            {
                if (t.Status == TaskStatus.RanToCompletion)
                {
                    p.Remove(encoderName);
                    completion.TryComplete();
                }
                else
                {
                    completion.TrySetException(t.Exception);
                }
            });
        }
示例#4
0
            public Context CreateIncomingSession()
            {
                IChannel channel = Substitute.For <IChannel>();

                _currentSession = new Session(_localPort, channel, NullDisconnectsAnalyzer.Instance, LimboLogs.Instance);
                _pipeline.Get <ZeroNettyP2PHandler>().Returns(new ZeroNettyP2PHandler(_currentSession, LimboLogs.Instance));
                _rlpxHost.SessionCreated += Raise.EventWith(new object(), new SessionEventArgs(_currentSession));
                return(this);
            }
示例#5
0
        public override void HandlerAdded(IChannelHandlerContext ctx)
        {
            IChannelPipeline cp = ctx.Pipeline;

            if (cp.Get <WebSocketServerProtocolHandshakeHandler>() is null)
            {
                // Add the WebSocketHandshakeHandler before this one.
                _ = cp.AddBefore(ctx.Name, nameof(WebSocketServerProtocolHandshakeHandler),
                                 new WebSocketServerProtocolHandshakeHandler(_serverConfig));
            }

            if (_serverConfig.DecoderConfig.WithUTF8Validator && cp.Get <Utf8FrameValidator>() is null)
            {
                // Add the UFT8 checking before this one.
                _ = cp.AddBefore(ctx.Name, nameof(Utf8FrameValidator), new Utf8FrameValidator());
            }
        }
示例#6
0
        public override void HandlerAdded(IChannelHandlerContext ctx)
        {
            IChannelPipeline cp = ctx.Channel.Pipeline;

            if (cp.Get <WebSocketClientProtocolHandshakeHandler>() == null)
            {
                // Add the WebSocketClientProtocolHandshakeHandler before this one.
                ctx.Channel.Pipeline.AddBefore(ctx.Name, nameof(WebSocketClientProtocolHandshakeHandler),
                                               new WebSocketClientProtocolHandshakeHandler(this.handshaker));
            }
            if (cp.Get <Utf8FrameValidator>() == null)
            {
                // Add the UFT8 checking before this one.
                ctx.Channel.Pipeline.AddBefore(ctx.Name, nameof(Utf8FrameValidator),
                                               new Utf8FrameValidator());
            }
        }
示例#7
0
 public void SetUp()
 {
     _channel = Substitute.For <IChannel>();
     _channelHandlerContext = Substitute.For <IChannelHandlerContext>();
     _pipeline = Substitute.For <IChannelPipeline>();
     _channelHandlerContext.Channel.Returns(_channel);
     _channel.Pipeline.Returns(_pipeline);
     _pipeline.Get <NettyPacketSplitter>().Returns(new NettyPacketSplitter());
     _packetSender = Substitute.For <IPacketSender>();
 }
示例#8
0
 public void SetUp()
 {
     _channel = Substitute.For<IChannel>();
     _channelHandlerContext = Substitute.For<IChannelHandlerContext>();
     _pipeline = Substitute.For<IChannelPipeline>();
     _channelHandlerContext.Channel.Returns(_channel);
     _channel.Pipeline.Returns(_pipeline);
     _pipeline.Get<ZeroPacketSplitter>().Returns(new ZeroPacketSplitter(LimboLogs.Instance));
     _packetSender = Substitute.For<IPacketSender>();
 }
        public void Select(ISerializer protocol, IChannelPipeline pipeline)
        {
            if (protocol.GetType() == typeof(DefaultSerializer))
            {
                pipeline.AddLast(new LengthFieldPrepender(2));
                pipeline.AddLast(new LengthFieldBasedFrameDecoder(ushort.MaxValue, 0, 2, 0, 2));
                pipeline.AddLast(new MessageSendHandler(protocol));
            }             //TODO use pf or other protocal ,now use binary serializer as default

            RpcServerLoader.Instance.SetMessageSendHandler(pipeline.Get <MessageSendHandler>());
        }
示例#10
0
 public static void AddToPipeline(IChannelPipeline cp)
 {
     lock (SyncRoot)
     {
         Guard.ArgumentNotNull(cp, nameof(cp));
         if (cp.Get(TimeoutHandler.Name) == null)
         {
             cp.AddFirst(TimeoutHandler.Name, new TimeoutHandler());
         }
     }
 }
示例#11
0
 public void Can_enable_snappy()
 {
     Session session = new(30312, new Node(TestItem.PublicKeyA, "127.0.0.1", 8545), _channel, NullDisconnectsAnalyzer.Instance, LimboLogs.Instance);
     ZeroNettyP2PHandler handler = new(session, LimboLogs.Instance);
     _pipeline.Get<ZeroNettyP2PHandler>().Returns(handler);
     Assert.False(handler.SnappyEnabled);
     session.Handshake(TestItem.PublicKeyA);
     session.Init(5, _channelHandlerContext, _packetSender);
     session.EnableSnappy();
     Assert.True(handler.SnappyEnabled);
     _pipeline.Received().Get<ZeroPacketSplitter>();
     _pipeline.Received().AddBefore(Arg.Any<string>(), Arg.Any<string>(), Arg.Any<ZeroSnappyEncoder>());
 }
示例#12
0
        public override void HandlerAdded(IChannelHandlerContext ctx)
        {
            IChannelPipeline cp = ctx.Channel.Pipeline;

            if (cp.Get <WebSocketServerProtocolHandshakeHandler>() == null)
            {
                // Add the WebSocketHandshakeHandler before this one.
                ctx.Channel.Pipeline.AddBefore(ctx.Name, nameof(WebSocketServerProtocolHandshakeHandler),
                                               new WebSocketServerProtocolHandshakeHandler(
                                                   this.websocketPath,
                                                   this.subprotocols,
                                                   this.allowExtensions,
                                                   this.maxFramePayloadLength,
                                                   this.allowMaskMismatch,
                                                   this.checkStartsWith));
            }

            if (cp.Get <Utf8FrameValidator>() == null)
            {
                // Add the UFT8 checking before this one.
                ctx.Channel.Pipeline.AddBefore(ctx.Name, nameof(Utf8FrameValidator), new Utf8FrameValidator());
            }
        }
            public Context()
            {
                _channel = Substitute.For <IChannel>();
                _channelHandlerContext = Substitute.For <IChannelHandlerContext>();
                _pipeline = Substitute.For <IChannelPipeline>();
                _channelHandlerContext.Channel.Returns(_channel);
                _channel.Pipeline.Returns(_pipeline);
                _pipeline.Get <ZeroPacketSplitter>().Returns(new ZeroPacketSplitter(LimboLogs.Instance));
                _packetSender = Substitute.For <IPacketSender>();
                _syncServer   = Substitute.For <ISyncServer>();
                _syncServer   = Substitute.For <ISyncServer>();
                _syncServer.Genesis.Returns(Build.A.Block.Genesis.TestObject.Header);
                _syncServer.Head.Returns(Build.A.BlockHeader.TestObject);
                _txPool             = Substitute.For <ITxPool>();
                _pooledTxsRequestor = Substitute.For <IPooledTxsRequestor>();
                _discoveryApp       = Substitute.For <IDiscoveryApp>();
                _serializer         = new MessageSerializationService();
                _rlpxHost           = Substitute.For <IRlpxHost>();
                _rlpxHost.LocalPort.Returns(_localPort);
                _rlpxHost.LocalNodeId.Returns(TestItem.PublicKeyA);
                ITimerFactory timerFactory = Substitute.For <ITimerFactory>();

                _nodeStatsManager = new NodeStatsManager(timerFactory, LimboLogs.Instance);
                _blockTree        = Substitute.For <IBlockTree>();
                _blockTree.ChainId.Returns(1ul);
                _blockTree.Genesis.Returns(Build.A.Block.Genesis.TestObject.Header);
                _protocolValidator = new ProtocolValidator(_nodeStatsManager, _blockTree, LimboLogs.Instance);
                _peerStorage       = Substitute.For <INetworkStorage>();
                _syncPeerPool      = Substitute.For <ISyncPeerPool>();
                _gossipPolicy      = Substitute.For <IGossipPolicy>();
                _manager           = new ProtocolsManager(
                    _syncPeerPool,
                    _syncServer,
                    _txPool,
                    _pooledTxsRequestor,
                    _discoveryApp,
                    _serializer,
                    _rlpxHost,
                    _nodeStatsManager,
                    _protocolValidator,
                    _peerStorage,
                    MainnetSpecProvider.Instance,
                    _gossipPolicy,
                    LimboLogs.Instance);

                _serializer.Register(new HelloMessageSerializer());
                _serializer.Register(new StatusMessageSerializer());
                _serializer.Register(new DisconnectMessageSerializer());
            }
        static string GetWebSocketLocation(IChannelPipeline cp, IHttpRequest req, string path)
        {
            string protocol = "ws";

            if (cp.Get <TlsHandler>() != null)
            {
                // SSL in use so use Secure WebSockets
                protocol = "wss";
            }

            string host = null;

            if (req.Headers.TryGet(HttpHeaderNames.Host, out ICharSequence value))
            {
                host = value.ToString();
            }
            return($"{protocol}://{host}{path}");
        }
示例#15
0
            public Context()
            {
                _channel = Substitute.For <IChannel>();
                _channelHandlerContext = Substitute.For <IChannelHandlerContext>();
                _pipeline = Substitute.For <IChannelPipeline>();
                _channelHandlerContext.Channel.Returns(_channel);
                _channel.Pipeline.Returns(_pipeline);
                _pipeline.Get <ZeroPacketSplitter>().Returns(new ZeroPacketSplitter(LimboLogs.Instance));
                _packetSender = Substitute.For <IPacketSender>();
                _syncServer   = Substitute.For <ISyncServer>();
                _syncServer   = Substitute.For <ISyncServer>();
                _syncServer.Genesis.Returns(Build.A.Block.Genesis.TestObject.Header);
                _syncServer.Head.Returns(Build.A.BlockHeader.TestObject);
                _txPool       = Substitute.For <ITxPool>();
                _discoveryApp = Substitute.For <IDiscoveryApp>();
                _serializer   = new MessageSerializationService();
                _localPeer    = Substitute.For <IRlpxPeer>();
                _localPeer.LocalPort.Returns(_localPort);
                _localPeer.LocalNodeId.Returns(TestItem.PublicKeyA);
                _nodeStatsManager = new NodeStatsManager(new StatsConfig(), LimboLogs.Instance);
                _blockTree        = Substitute.For <IBlockTree>();
                _blockTree.ChainId.Returns(1);
                _blockTree.Genesis.Returns(Build.A.Block.Genesis.TestObject.Header);
                _protocolValidator = new ProtocolValidator(_nodeStatsManager, _blockTree, LimboLogs.Instance);
                _peerStorage       = Substitute.For <INetworkStorage>();
                _perfService       = new PerfService(LimboLogs.Instance);
                _syncPeerPool      = Substitute.For <IEthSyncPeerPool>();
                _manager           = new ProtocolsManager(
                    _syncPeerPool,
                    _syncServer,
                    _txPool,
                    _discoveryApp,
                    _serializer,
                    _localPeer,
                    _nodeStatsManager,
                    _protocolValidator,
                    _peerStorage,
                    _perfService,
                    LimboLogs.Instance);

                _serializer.Register(new HelloMessageSerializer());
                _serializer.Register(new StatusMessageSerializer());
                _serializer.Register(new DisconnectMessageSerializer());
            }
        /// <summary>
        /// Populates the channel pipeline in order to read data from a WebSocket connection.
        /// </summary>
        public static void populateWSPipeline(IChannel ch, IChannelHandler wsChHandler)
        {
            IChannelPipeline chPipeline = ch.Pipeline;
            IChannelHandler  reader     = chPipeline.Get(READER_KEY);

            if (reader == null)
            {
                /*
                 * there is no reader when the WebSocket channel is fresh,
                 * i.e the channel was filled by populateWSPipelineForHandshake()
                 */
                chPipeline.AddLast(READER_KEY, wsChHandler);
            }
            else
            {
                /*
                 * the old reader is the WebSocket channel handler used before the channel was released to the pool,
                 * i.e the channel was already filled by populateWSPipeline()
                 */
                chPipeline.Replace(READER_KEY, READER_KEY, wsChHandler);
            }
        }
示例#17
0
 public static TimeoutHandler FindTimeoutHandler(IChannelPipeline cp)
 {
     return((TimeoutHandler)cp.Get(TimeoutHandler.Name));
 }
 public static bool Contains <T>(this IChannelPipeline channelPipeline) where T : class, IChannelHandler
 {
     return(channelPipeline.Get <T>() != null);
 }
 public void ResetStream(IChannelPipeline pipeline)
 {
     pipeline.Get <XmlStreamDecoder>().Reset();
 }