Skip to content

Netty Client Transport Connector doesn't work in BUFFERED mode #6040

@joain946

Description

@joain946

By default the Netty Connector uses CHUNKED transfer encoding. This is fine in many cases but sometimes it is required to use a request that contains a "Content-Length" header, for example Azure Blob Storage requires this.

Changing to BUFFERED mode can be done either by setting the "RequestEntityProcessing.BUFFERED" property or by specifying a "Content-Length" header. But both these triggers a bug which will create a "read timeout" in every other request. So request 2, 4, 6 and so on will hang until the configured read timeout is reached. It looks like the "Channel" ends up in an incorrect state. At least POST and PUT are affected.

This issue can be found in all the latest versions of the connector ("2.47", "3.1.11" and "4.0.0").

This can be replicated using the following:
POM
<dependency> <groupId>org.glassfish.jersey.connectors</groupId> <artifactId>jersey-netty-connector</artifactId> <version>2.47</version> </dependency>

Code
`
package com.test;

// Same issue for "jakarta.ws.rs.client" package
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.Invocation.Builder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;

import org.glassfish.jersey.client.ClientProperties;
import org.glassfish.jersey.client.RequestEntityProcessing;
import org.glassfish.jersey.netty.connector.NettyConnectorProvider;

public class App {
private static Client client = null;

// Initializes the client on first request
public static Client getClient() {
    if (client == null) {
        client = ClientBuilder.newBuilder()
                .property(ClientProperties.CONNECTOR_PROVIDER, NettyConnectorProvider.class.getName())
                .property(ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.BUFFERED) 
                .build();
    }

    return client;
}

private static String executeRequest(final String url, final String body) {
    // Create the request
    WebTarget target = getClient().target(url);
    Builder builder = target.request();
    // builder.header("Content-Length", body.getBytes(StandardCharsets.UTF_8).length);  // Setting this doesn't resolve the issue
    Invocation invocation = builder.build("POST", Entity.entity(body, "application/json"));

    // Invoke the request
    try (Response response = invocation.invoke()) {
        return response.hasEntity() ? response.readEntity(String.class) : null;
    }
}

public static void main(String[] args) {
    final String url = "https://echo.free.beeceptor.com/";
    final String body = "{}";

    System.out.println(executeRequest(url, body));
    System.out.println(executeRequest(url, body));
}

}
`

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions