Skip to content

Commit

Permalink
Prevent creation of the Response object for ContainerResponseContext
Browse files Browse the repository at this point in the history
Fixes: #45791
  • Loading branch information
geoand committed Jan 23, 2025
1 parent 4198ee4 commit 974edb1
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
import java.nio.file.Path;
import java.nio.file.Paths;

import jakarta.ws.rs.container.ContainerResponseContext;
import jakarta.ws.rs.core.HttpHeaders;

import org.hamcrest.Matchers;
import org.jboss.resteasy.reactive.FilePart;
import org.jboss.resteasy.reactive.PathPart;
import org.jboss.resteasy.reactive.server.ServerResponseFilter;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
Expand All @@ -30,7 +32,7 @@ public class FileTestCase {
@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.withApplicationRoot((jar) -> jar
.addClasses(FileResource.class, WithWriterInterceptor.class, WriterInterceptor.class));
.addClasses(FileResource.class, WithWriterInterceptor.class, WriterInterceptor.class, Filters.class));

@Test
public void testFiles() throws Exception {
Expand Down Expand Up @@ -168,4 +170,14 @@ public void testChecks() throws IOException {
} catch (IllegalArgumentException x) {
}
}

public static class Filters {

@ServerResponseFilter
public void responseHeaders(ContainerResponseContext responseContext) {
// make sure the use of these methods does not change the response code
responseContext.hasEntity();
responseContext.getEntity();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ public interface LazyResponse {
*/
Response get();

/**
* Gets the response, but makes change to the state of the object
*/
Response transientGet();

/**
*
* @return <code>true</code> if the response already exists
Expand Down Expand Up @@ -37,6 +42,11 @@ public Response get() {
return response;
}

@Override
public Response transientGet() {
return response;
}

@Override
public boolean isCreated() {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,42 +139,51 @@ public void handle(ResteasyReactiveRequestContext requestContext) throws Excepti

Response response;

public Response create() {
ResponseBuilderImpl responseBuilder;
if (result instanceof GenericEntity) {
GenericEntity<?> genericEntity = (GenericEntity<?>) result;
requestContext.setGenericReturnType(genericEntity.getType());
responseBuilder = ResponseBuilderImpl.ok(genericEntity.getEntity());
} else if (result == null) {
// FIXME: custom status codes depending on method?
responseBuilder = ResponseBuilderImpl.noContent();
} else {
// FIXME: custom status codes depending on method?
responseBuilder = ResponseBuilderImpl.ok(result);
}
if (responseBuilder.getEntity() != null) {
EncodedMediaType produces = requestContext.getResponseContentType();
if (produces != null) {
responseBuilder.header(HttpHeaders.CONTENT_TYPE, produces.toString());
}
}
if (!responseBuilderCustomizers.isEmpty()) {
for (int i = 0; i < responseBuilderCustomizers.size(); i++) {
responseBuilderCustomizers.get(i).customize(responseBuilder);
}
}
if ((responseBuilder instanceof ResponseBuilderImpl)) {
// avoid unnecessary copying of HTTP headers from the Builder to the Response
return ((ResponseBuilderImpl) responseBuilder).build(false);
} else {
return responseBuilder.build();
}
}

@Override
public Response get() {
if (response == null) {
ResponseBuilderImpl responseBuilder;
if (result instanceof GenericEntity) {
GenericEntity<?> genericEntity = (GenericEntity<?>) result;
requestContext.setGenericReturnType(genericEntity.getType());
responseBuilder = ResponseBuilderImpl.ok(genericEntity.getEntity());
} else if (result == null) {
// FIXME: custom status codes depending on method?
responseBuilder = ResponseBuilderImpl.noContent();
} else {
// FIXME: custom status codes depending on method?
responseBuilder = ResponseBuilderImpl.ok(result);
}
if (responseBuilder.getEntity() != null) {
EncodedMediaType produces = requestContext.getResponseContentType();
if (produces != null) {
responseBuilder.header(HttpHeaders.CONTENT_TYPE, produces.toString());
}
}
if (!responseBuilderCustomizers.isEmpty()) {
for (int i = 0; i < responseBuilderCustomizers.size(); i++) {
responseBuilderCustomizers.get(i).customize(responseBuilder);
}
}
if ((responseBuilder instanceof ResponseBuilderImpl)) {
// avoid unnecessary copying of HTTP headers from the Builder to the Response
response = ((ResponseBuilderImpl) responseBuilder).build(false);
} else {
response = responseBuilder.build();
}
response = create();
}
return response;
}

@Override
public Response transientGet() {
return create();
}

@Override
public boolean isCreated() {
return response != null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,14 +134,18 @@ public Builder getLinkBuilder(String relation) {
return response().getLinkBuilder(relation);
}

protected Response transientResponse() {
return context.getResponse().transientGet();
}

@Override
public boolean hasEntity() {
return response().hasEntity();
return transientResponse().hasEntity();
}

@Override
public Object getEntity() {
return response().getEntity();
return transientResponse().getEntity();
}

@Override
Expand Down

0 comments on commit 974edb1

Please sign in to comment.