Uploaded image for project: 'RESTEasy'
  1. RESTEasy
  2. RESTEASY-3289

Issue in AbstractMultipartFormDataWriter when using custom RequestHandler configuration in Netty

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Minor Minor
    • None
    • 5.0.5.Final
    • Netty integration
    • None
    • Hide

      Checkout the reproducer and run the Main.java class (e.g. by executing ./gradlew run).

      Execute curl --location --request POST 'localhost:8080/service/example' --form 'content=example string'

      Change this line to .addLast(new RequestHandler(dispatcher)); and everything works as expected.

      Show
      Checkout the reproducer and run the  Main.java class (e.g. by executing ./gradlew run ). Execute curl --location --request POST 'localhost:8080/service/example' --form 'content=example string' Change this line to .addLast(new RequestHandler(dispatcher)); and everything works as expected.

      This is a follow up issue to RESTEASY-2693 (see my last comment there).

      When creating a multipart/form-data response with more than one form data like this:

      MultipartFormDataOutput multipart = new MultipartFormDataOutput();
      multipart.addFormData("content", request.getContent(), MediaType.APPLICATION_OCTET_STREAM_TYPE);
      multipart.addFormData("more content", "test", MediaType.APPLICATION_OCTET_STREAM_TYPE);
      
      GenericEntity<MultipartFormDataOutput> entity = new GenericEntity<MultipartFormDataOutput>(multipart) {
      };
      return Response.ok(entity, MediaType.MULTIPART_FORM_DATA).build();
      

      only one of the added multiparts is actually sent.

      The output looks like the following:

      --a51b09ef-55d7-48fe-87a7-9832b6751079
      Content-Disposition: form-data; name="more content"
      Content-Type: application/octet-stream
      
      test 

      although I would expect:

      --a51b09ef-55d7-48fe-87a7-9832b6751079
      Content-Disposition: form-data; name="more content"
      Content-Type: application/octet-stream
      
      test
      --a51b09ef-55d7-48fe-87a7-9832b6751079
      Content-Disposition: form-data; name="content"
      Content-Type: application/octet-stream
      
      example string
      --a51b09ef-55d7-48fe-87a7-9832b6751079
      

       
      I start the RESTeasy deployment using the following configuration:

      RequestDispatcher dispatcher = new RequestDispatcher((SynchronousDispatcher) deployment.getDispatcher(), deployment.getProviderFactory(), null);
      RestEasyHttpRequestDecoder restEasyHttpRequestDecoder = new RestEasyHttpRequestDecoder(dispatcher.getDispatcher(),
              "", RestEasyHttpRequestDecoder.Protocol.HTTP);
      RestEasyHttpResponseEncoder restEasyHttpResponseEncoder = new RestEasyHttpResponseEncoder();
      
      ServerBootstrap serverBootstrap = new ServerBootstrap()
              .group(new NioEventLoopGroup())
              .channel(NioServerSocketChannel.class)
              .childHandler(new ChannelInitializer<Channel>() {
                  @Override
                  protected void initChannel(Channel ch) {
                      ChannelPipeline pipe = ch.pipeline();
                      pipe.addLast(new HttpRequestDecoder())
                              .addLast(new HttpResponseEncoder())
                              .addLast(new HttpObjectAggregator(10 * 1024 * 1024))
                              .addLast(restEasyHttpRequestDecoder)
                              .addLast(restEasyHttpResponseEncoder)
                              .addLast(new NioEventLoopGroup(), new RequestHandler(dispatcher));
                  }
              }).childOption(ChannelOption.SO_KEEPALIVE, true);
      serverBootstrap.bind(8080).syncUninterruptibly();
      

      When removing the second NioEventLoopGroup here (so the line becomes just .addLast(new RequestHandler(dispatcher));) everything works, even with version 5.0.4.Final (so without the changes done in RESTEASY-2693).

      I think the reason for this behavior is once again here, as the ResteasyContext#getContextDataMap returns an empty map, due to contextualData being a ThreadLocalStack and the additional NioEventLoopGroup (see above).

      Not sure, if this really has something to do with it, but maybe a good starting point.

            Unassigned Unassigned
            lars_ka Lars Kaulen (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: