Skip to content

Missing Content-Length header on jetty #6042

@jan-berge-ommedal

Description

@jan-berge-ommedal

Hi!

I am trying to make jersey+jetty automatically set the Content-Length to pass this test:

    @Path("/")
    public static class MyResource {
        @GET
        public String get() {
            return "hello world";
        }
    }

    @Test
    public void testContentLength() {
        URI uri = UriBuilder.fromUri("http://localhost/").port(8123).build();
        JettyHttpContainerFactory.createServer(uri, new ResourceConfig(MyResource.class));
        Response response = ClientBuilder.newClient().target(uri).request().get(Response.class);
        assertEquals(response.readEntity(String.class), "hello world");
        assertEquals(response.getLength(), 11);
    }

I tried manipulating the OUTBOUND_CONTENT_LENGTH_BUFFER configuration, but looks like the JettyHttpContainer is the only supported container that disables response buffering, presumably because:

Containers that provide it's own solution for determining the message payload size may decide to return to prevent Jersey from buffering message entities unnecessarily.

But it seems like jersey doesn't use jetty in a manner that allows jetty to automatically resolve the content length and set the header. (the jetty HttpChannel needs to know if the response content being written is the last content that will be written).

Perhaps i am missing something here, but i find it confusing that response buffering is explicitly disabled for the JettyHttpContainer when it seemingly doesn't provide it's own solution for this as suggested in the javadoc. Is there a reason for jetty being the only container not supporting response buffering?

The best workaround i've found is to forcefully enable buffering in a filter:

    private static class ContentLengthFilter implements ContainerResponseFilter {
        @Override
        public void filter(ContainerRequestContext containerRequestContext, ContainerResponseContext containerResponseContext) {
            OutputStream entityStream = containerResponseContext.getEntityStream();
            if (entityStream instanceof CommittingOutputStream committingOutputStream) {
                committingOutputStream.enableBuffering(1234);
            }
        }
    }

Might there be a better way to do this?

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