eclipse-ee4j / eclipse-ee4j/jersey

Missing Content-Length header on jetty

Open
#6,042 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
730
Forks
382
PR merge metrics
No merged PRs in 30d

Description

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?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.