chunked-encodingcxf-client

CXF JAX-RS client always sends empty PUT requests in chunking mode regardles of AllowChunking setting


We perform PUT request to our party using CXF JAX-RS client. Request body is empty. A simple request invocation leads to server response with code 411.

Response-Code: 411  
"Content-Length is missing"

Our party's REST-server requires Content-Length HTTP-header to be set.

We switched chunking off according to note about chunking but this did not solve the problem. The REST-server still answers with 411 error.

Here is our conduit configuration from cxf.xml file

    <http-conf:conduit name="{http://myhost.com/ChangePassword}WebClient.http-conduit">
        <http-conf:client AllowChunking="false"/>
    </http-conf:conduit>

Line in the log confirms that execution of our request bound to our conduit configuration:

DEBUG o.a.cxf.transport.http.HTTPConduit - Conduit '{http://myhost.com/ChangePassword}WebClient.http-conduit' has been configured for plain http.

Adding Content-Length header explicitly also did not help.

    Invocation.Builder builder = ...  
    builder = builder.header(HttpHeaders.CONTENT_LENGTH, 0);

A CXF Client's log entry confirms header setting, however when we sniffed packets, we have surprisingly found that header setting has been completely ignored by CXF client. Content-Length header was not sent.

Here is the log. Content-Length header is present:

INFO  o.a.c.i.LoggingOutInterceptor - Outbound Message
---------------------------
ID: 1
Address: http://myhost.com/ChangePassword?username=abc%40gmail.com&oldPassword=qwerty123&newPassword=321ytrewq
Http-Method: PUT
Content-Type: application/x-www-form-urlencoded
Headers: {Accept=[application/json], client_id=[abcdefg1234567890abcdefg12345678], Content-Length=[0], Content-Type=[application/x-www-form-urlencoded], Cache-Control=[no-cache], Connection=[Keep-Alive]}
--------------------------------------
DEBUG o.apache.cxf.transport.http.Headers - Accept: application/json
DEBUG o.apache.cxf.transport.http.Headers - client_id: abcdefg1234567890abcdefg12345678
DEBUG o.apache.cxf.transport.http.Headers - Content-Length: 0
DEBUG o.apache.cxf.transport.http.Headers - Content-Type: application/x-www-form-urlencoded
DEBUG o.apache.cxf.transport.http.Headers - Cache-Control: no-cache
DEBUG o.apache.cxf.transport.http.Headers - Connection: Keep-Alive

And here is an output of the packet sniffer. Content-Length header is not present:

PUT http://myhost.com/ChangePassword?username=abc%40gmail.com&oldPassword=qwerty123&newPassword=321ytrewq HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Accept: application/json
client_id: abcdefg1234567890abcdefg12345678
Cache-Control: no-cache
User-Agent: Apache-CXF/3.1.8
Pragma: no-cache
Host: myhost.com
Proxy-Connection: keep-alive

Does anyone know how actually disable chunking?

Here is our code:

    public static void main(String[] args)  
    {  
        String clientId   = "abcdefg1234567890abcdefg12345678";  
        String uri        = "http://myhost.com";  
        String user       = "abc@gmail.com";  

        Client client = ClientBuilder.newBuilder().newClient();  
        WebTarget target = client.target(uri);  
        target = target.path("ChangePassword").queryParam("username", user).queryParam("oldPassword", "qwerty123").queryParam("newPassword", "321ytrewq");  
        Invocation.Builder builder = target.request("application/json").header("client_id", clientId).header(HttpHeaders.CONTENT_LENGTH, 0);  
        Response response = builder.put(Entity.form(new Form()));  
        String body = response.readEntity(String.class);  
        System.out.println(body);  
    }

Versions:


Solution

  • I had a very similar issue that I was not able to solve as you did by trying to turn off chunking.

    What I ended up doing was setting the Content-Length to 1 and adding some white space " " as the body. For me it seemed that the proxy servers before the server application was rejected the request and by doing that got me past the proxy servers and the server was able to process the request as it was only operating based on the URL.