Skip to content

Commit

Permalink
Fixes #4312 - Fix BeanParam annotation with body content (#4313)
Browse files Browse the repository at this point in the history
  • Loading branch information
mnriem authored Dec 2, 2024
1 parent e1c2e27 commit 9e60d9a
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

Expand Down Expand Up @@ -121,12 +128,41 @@ public int read() throws IOException {
return -1;
}
if (inputStream.available() > 0) {
/*
* Because the inputstream indicates we have bytes available we
* read the next byte assuming it won't block.
*/
read = inputStream.read();
index++;
if (index == webApplicationRequest.getContentLength() || read == -1) {
finished = true;
} else {
/*
* Because we do not know if the underlying inputstream can
* block indefinitely we make sure we read from the inputstream
* with a timeout so we do not block the thread indefinitely.
*
* If we do not get a read to succeed within the 30 seconds
* timeout we return -1 to indicate we assume the end of the
* stream has been reached.
*/
ExecutorService executor = Executors.newSingleThreadExecutor();

Callable<Integer> readTask = () -> {
return inputStream.read();
};

Future<Integer> future = executor.submit(readTask);

try {
read = future.get(30, TimeUnit.SECONDS);
} catch (TimeoutException | InterruptedException | ExecutionException e) {
read = -1;
} finally {
executor.shutdown();
}
}
index++;
if (index == webApplicationRequest.getContentLength() || read == -1) {
finished = true;
}
} else {
if (inputStream.available() > 0) {
read = inputStream.read();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,35 @@
*
* @author Manfred Riem (mriem@manorrock.com)
*/
@Path("/beanParam")
@Path("beanParam")
public class BeanParamBean {

/**
* Process BeanParam annotated input.
* Process BeanParam annotated input without content body.
*
* @param input the input.
* @return the response.
*/
@POST
@POST
@Path("withoutContent")
@Consumes(APPLICATION_FORM_URLENCODED)
@Produces(TEXT_PLAIN)
public Response beanParamInput(@BeanParam BeanParamInput input) {
return Response.ok(input.toString()).build();
}

/**
* Process BeanParam annotated input with content body.
*
* @param content the content body.
* @param input the input.
* @return the response.
*/
@POST
@Path("withContent")
@Consumes(APPLICATION_FORM_URLENCODED)
@Produces(TEXT_PLAIN)
public Response beanParamInputWithContent(String content, @BeanParam BeanParamInput input) {
return Response.ok(content + "," + input.toString()).build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@
public class BeanParamIT {

@Test
public void testBeanParamAnnotation() throws Exception {
public void testBeanParamAnnotationWithoutContent() throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://localhost:"
+ System.getProperty("httpPort")
+ "/piranha-test-coreprofile-integration/beanParam?queryParam=10"))
+ "/piranha-test-coreprofile-integration/beanParam/withoutContent?queryParam=10"))
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.ofString("formParam=formParam1"))
.build();
Expand All @@ -54,4 +54,22 @@ public void testBeanParamAnnotation() throws Exception {
assertEquals(200, response.statusCode());
assertEquals("UserInput{formParam='formParam1', queryParam=10, contentType='application/x-www-form-urlencoded'}", response.body());
}

@Test
public void testBeanParamAnnotationWithContent() throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://localhost:"
+ System.getProperty("httpPort")
+ "/piranha-test-coreprofile-integration/beanParam/withContent?queryParam=10"))
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.ofString("CONTENT"))
.build();

HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());

assertEquals(200, response.statusCode());
assertEquals("CONTENT,UserInput{formParam='null', queryParam=10, contentType='application/x-www-form-urlencoded'}", response.body());
}
}

0 comments on commit 9e60d9a

Please sign in to comment.