/// <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)); }
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>())); }