/// <summary>
        /// Inserts a  ChannelHandler after an existing handler of this pipeline.
        //  The name of the handlers is taken from the NameAttribute of the handler class.
        /// </summary>
        /// <typeparam name="TAfter"></typeparam>
        /// <param name="channelPipeline"></param>
        /// <param name="handler"></param>
        /// <returns></returns>
        public static IChannelPipeline AddAfter <TAfter>(this IChannelPipeline channelPipeline, IChannelHandler handler)
        {
            var name     = handler.GetType().GetTypeInfo().GetCustomAttribute <NameAttribute>(false).Name;
            var baseName = typeof(TAfter).GetTypeInfo().GetCustomAttribute <NameAttribute>(false).Name;

            return(channelPipeline.AddAfter(baseName, name, handler));
        }
        /// <summary>
        /// Performs the opening handshake
        /// When call this method you <c>MUST NOT</c> retain the <see cref="IHttpRequest"/> 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>
        /// <returns></returns>
        public Task HandshakeAsync(IChannel channel, IHttpRequest req, HttpHeaders responseHeaders)
        {
            if (req is IFullHttpRequest request)
            {
                return(HandshakeAsync(channel, request, responseHeaders));
            }
            if (Logger.DebugEnabled)
            {
                Logger.WebSocketVersionServerHandshake(channel, _version);
            }
            IChannelPipeline       p   = channel.Pipeline;
            IChannelHandlerContext ctx = p.Context <HttpRequestDecoder>();

            if (ctx is null)
            {
                // this means the user use an HttpServerCodec
                ctx = p.Context <HttpServerCodec>();
                if (ctx is null)
                {
                    return(ThrowHelper.ThrowInvalidOperationException_NoHttpDecoderAndServerCodec());
                }
            }

            // Add aggregator and ensure we feed the HttpRequest so it is aggregated. A limit o 8192 should be more then
            // enough for the websockets handshake payload.
            //
            // TODO: Make handshake work without HttpObjectAggregator at all.
            string aggregatorName = "httpAggregator";

            _ = p.AddAfter(ctx.Name, aggregatorName, new HttpObjectAggregator(8192));
            var completion = channel.NewPromise();

            _ = p.AddAfter(aggregatorName, "handshaker", new Handshaker(this, channel, responseHeaders, completion));
            try
            {
                _ = ctx.FireChannelRead(ReferenceCountUtil.Retain(req));
            }
            catch (Exception cause)
            {
                _ = completion.TrySetException(cause);
            }
            return(completion.Task);
        }
            protected override void ChannelRead0(IChannelHandlerContext ctx, IHttpMessage msg)
            {
                // If this handler is hit then no upgrade has been attempted and the client is just talking HTTP.
                s_logger.LogInformation("Directly talking: " + msg.ProtocolVersion + " (no upgrade was attempted)");
                IChannelPipeline pipeline = ctx.Pipeline;

                pipeline.AddAfter(ctx.Name, null, new Http2Helloworld.Server.HelloWorldHttp1Handler("Direct. No Upgrade Attempted."));
                pipeline.Replace(this, null, new HttpObjectAggregator(this.maxHttpContentLength));
                ctx.FireChannelRead(ReferenceCountUtil.Retain(msg));
            }
示例#4
0
        public Task HandshakeAsync(IChannel channel, IHttpRequest req, HttpHeaders responseHeaders)
        {
            if (req is IFullHttpRequest request)
            {
                return(this.HandshakeAsync(channel, request, responseHeaders));
            }
            if (Logger.DebugEnabled)
            {
                Logger.Debug("{} WebSocket version {} server handshake", channel, this.version);
            }
            IChannelPipeline       p   = channel.Pipeline;
            IChannelHandlerContext ctx = p.Context <HttpRequestDecoder>();

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

            // Add aggregator and ensure we feed the HttpRequest so it is aggregated. A limit o 8192 should be more then
            // enough for the websockets handshake payload.
            //
            // TODO: Make handshake work without HttpObjectAggregator at all.
            string aggregatorName = "httpAggregator";

            p.AddAfter(ctx.Name, aggregatorName, new HttpObjectAggregator(8192));
            var completion = new TaskCompletionSource();

            p.AddAfter(aggregatorName, "handshaker", new Handshaker(this, channel, responseHeaders, completion));
            try
            {
                ctx.FireChannelRead(ReferenceCountUtil.Retain(req));
            }
            catch (Exception cause)
            {
                completion.TrySetException(cause);
            }
            return(completion.Task);
        }
 /// <summary>
 /// Inserts a ChannelHandler after an existing handler of this pipeline.
 //  The name of the handlers is taken from the NameAttribute of the handler class.
 /// </summary>
 /// <typeparam name="TNewHandler">The type of the new handler.</typeparam>
 /// <typeparam name="TAfter">The type of the handler to be added after.</typeparam>
 /// <param name="channelPipeline">The channel pipeline.</param>
 /// <returns></returns>
 public static IChannelPipeline AddAfter <TNewHandler, TAfter>(this IChannelPipeline channelPipeline)
     where TNewHandler : class, IChannelHandler
 {
     return(channelPipeline.AddAfter <TAfter>(Activator.CreateInstance <TNewHandler>()));
 }