Skip to content

HttpServerCodec always constructs an "EmptyLastHttpContent" and passes it to the Handler chain when processing OPTIONS requests #15148

@anren1024

Description

@anren1024

HttpServerCodec always constructs an "EmptyLastHttpContent" and passes it to the Handler chain when processing OPTIONS requests, The "EmptyLastHttpContent" propagate through the handler chain.

If a CORS handler is added to the pipeline, it may prematurely return a response to the HTTP client.

However, the CORS handler might still propagate the EmptyLastHttpContent to downstream handlers via fireChannelRead(), causing subsequent handlers to receive only this empty content and lose access to the original request URL.

Can the CORSHandler be configured to directly consume/discard the EmptyLastHttpContent?

simple channel:

 ServerBootstrap b = new ServerBootstrap();
                b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            
                            ch.pipeline().addLast(new HttpServerCodec())

                                .addLast(new CorsHandler(CorsConfigBuilder.forAnyOrigin()
                                    .allowedRequestMethods(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, HttpMethod.DELETE, HttpMethod.OPTIONS)
                                    .allowedRequestHeaders("*")
                                    .maxAge(3600L)
                                    .allowNullOrigin()
                                    .build()))

                                .addLast(new SimpleHandler())

SimpleHandler:

public SimpleHandler extends ChannelInboundHandlerAdapter {
    private static final Logger log = LoggerFactory.getLogger(SimpleHandler.class);

    private boolean isOption;
 
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
         if (msg instanceof HttpRequest req) {
              isOption = req.method() == HttpMethod.OPTIONS;
         }
                                        
          if (msg instanceof LastHttpContent && isOption && msg.toString().equals("EmptyLastHttpContent")) {
                log.info("an EmptyLastHttpContent");
                return;
          }
         ctx.fireChannelRead(msg);
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions