Skip to content

Commit

Permalink
Merge pull request #3822 from jamezp/backports-6.2
Browse files Browse the repository at this point in the history
[6.2] Back ports
  • Loading branch information
jamezp committed Oct 5, 2023
2 parents ccc8f73 + de88860 commit 5435246
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,61 @@ public void multiInjection() throws Exception {
}
}

/**
* Tests sending {@code multipart/form-data} content as a {@link EntityPart List<EntityPart>}. Three parts are sent
* and injected as {@link FormParam @FormParam} method parameters. Each part send is different and injected as a
* specific type.
* <p>
* The result from the REST endpoint is {@code multipart/form-data} content with a new name and the content for the
* injected field.
* </p>
*
* @throws Exception if an error occurs in the test
*/
@Test
public void multiAllFilesInjection() throws Exception {
try (Client client = ClientBuilder.newClient()) {
final List<EntityPart> multipart = List.of(
EntityPart.withName("entity-part")
.fileName("file1.txt")
.content("test entity part file1.txt")
.mediaType(MediaType.TEXT_PLAIN_TYPE)
.build(),
EntityPart.withName("string-part")
.fileName("file2.txt")
.content("test string file2.txt")
.mediaType(MediaType.TEXT_PLAIN_TYPE)
.build(),
EntityPart.withName("input-stream-part")
.fileName("file3.txt")
.content("test input stream file3.txt".getBytes(StandardCharsets.UTF_8))
.mediaType(MediaType.APPLICATION_OCTET_STREAM_TYPE)
.build());
try (
Response response = client.target(INSTANCE.configuration()
.baseUriBuilder()
.path("test/multi-injected"))
.request(MediaType.MULTIPART_FORM_DATA_TYPE)
.post(Entity.entity(new GenericEntity<>(multipart) {
}, MediaType.MULTIPART_FORM_DATA))) {
Assert.assertEquals(Response.Status.OK, response.getStatusInfo());
final List<EntityPart> entityParts = response.readEntity(new GenericType<>() {
});
if (entityParts.size() != 3) {
final String msg = "Expected 3 entries got " +
entityParts.size() +
'.' +
System.lineSeparator() +
getMessage(entityParts);
Assert.fail(msg);
}
checkEntity(entityParts, "received-entity-part", "test entity part file1.txt");
checkEntity(entityParts, "received-string", "test string file2.txt");
checkEntity(entityParts, "received-input-stream", "test input stream file3.txt");
}
}
}

/**
* Tests sending {@code multipart/form-data} content as a {@link EntityPart List<EntityPart>}. One part is sent
* and injected as {@link FormParam @FormParam} method parameters. The same part should be injected in different
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

public class JettyClientEngine implements AsyncClientHttpEngine {
public static final String REQUEST_TIMEOUT_MS = JettyClientEngine.class + "$RequestTimeout";
public static final String IDLE_TIMEOUT_MS = JettyClientEngine.class + "$IdleTimeout";
// Yeah, this is the Jersey one, but there's no standard one and it makes more sense to reuse than make our own...
public static final String FOLLOW_REDIRECTS = "jersey.config.client.followRedirects";

Expand Down Expand Up @@ -187,6 +188,19 @@ private void failed(Throwable t) {

private void configureTimeout(final Request request) {
final Object timeout = request.getAttributes().get(REQUEST_TIMEOUT_MS);
final Object idleTimeout = request.getAttributes().get(IDLE_TIMEOUT_MS);
final long timeoutMs = parseTimeoutMs(timeout);
final long idleTimeoutMs = parseTimeoutMs(idleTimeout);
if (timeoutMs > 0) {
request.timeout(timeoutMs, TimeUnit.MILLISECONDS);
}

if (idleTimeoutMs > 0) {
request.idleTimeout(idleTimeoutMs, TimeUnit.MILLISECONDS);
}
}

private long parseTimeoutMs(final Object timeout) {
final long timeoutMs;
if (timeout instanceof Duration) {
timeoutMs = ((Duration) timeout).toMillis();
Expand All @@ -197,9 +211,7 @@ private void configureTimeout(final Request request) {
} else {
timeoutMs = -1;
}
if (timeoutMs > 0) {
request.timeout(timeoutMs, TimeUnit.MILLISECONDS);
}
return timeoutMs;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,44 @@ public void handle(String target, Request baseRequest, HttpServletRequest reques
}
}

@Test
public void testIdleTimeout() throws Exception {
server.setHandler(new AbstractHandler() {
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
throws IOException {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new AssertionError(e);
}
baseRequest.setHandled(true);
response.setStatus(200);
response.getWriter().println("Success");
}
});

try {
client().target(baseUri()).request()
.property(JettyClientEngine.REQUEST_TIMEOUT_MS, Duration.ofMillis(2000))
.property(JettyClientEngine.IDLE_TIMEOUT_MS, Duration.ofMillis(500))
.get();
fail();
} catch (ProcessingException e) {
assertTrue(e.getCause() instanceof TimeoutException);
}

final Response response = client().target(baseUri()).request()
.property(JettyClientEngine.REQUEST_TIMEOUT_MS, Duration.ofMillis(2000))
.property(JettyClientEngine.IDLE_TIMEOUT_MS, Duration.ofMillis(1500))
.get();

assertEquals(200, response.getStatus());
assertEquals("Success" + System.lineSeparator(), response.readEntity(String.class));

}

@Test
public void testDeferContent() throws Exception {
server.setHandler(new EchoHandler());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.jboss.resteasy.core;

import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Type;
Expand All @@ -11,6 +13,7 @@

import jakarta.ws.rs.FormParam;
import jakarta.ws.rs.core.EntityPart;
import jakarta.ws.rs.core.MediaType;

import org.jboss.resteasy.resteasy_jaxrs.i18n.Messages;
import org.jboss.resteasy.spi.HttpRequest;
Expand Down Expand Up @@ -45,6 +48,17 @@ public Object inject(HttpRequest request, HttpResponse response, boolean unwrapA
} else if (InputStream.class.isAssignableFrom(type)) {
final Optional<EntityPart> part = request.getFormEntityPart(paramName);
return part.map(EntityPart::getContent).orElse(null);
} else if (String.class.isAssignableFrom(type) &&
// request.getHttpHeaders().getMediaType() may return null, but the isCompatible handles this check
MediaType.MULTIPART_FORM_DATA_TYPE.isCompatible(request.getHttpHeaders().getMediaType())) {
final Optional<EntityPart> part = request.getFormEntityPart(paramName);
return part.map(p -> {
try {
return p.getContent(String.class);
} catch (IOException e) {
throw new UncheckedIOException(Messages.MESSAGES.unableToExtractParameter(paramName, null), e);
}
}).orElse(null);
}
List<String> list = request.getDecodedFormParameters().get(paramName);
if (list != null && encode) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,11 @@ private static MediaType internalParse(String type) {
} else {
major = type.substring(0, typeIndex);
if (paramIndex > -1) {
subtype = type.substring(typeIndex + 1, paramIndex);
int beginIndex = typeIndex + 1;
if (beginIndex > paramIndex) {
throw new IllegalArgumentException(Messages.MESSAGES.failureParsingMediaType(type));
}
subtype = type.substring(beginIndex, paramIndex);
} else {
subtype = type.substring(typeIndex + 1);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.jboss.resteasy.plugins.delegates;

import org.junit.Test;

public class MediaTypeHeaderDelegateTest {

@Test(expected = IllegalArgumentException.class)
public void parsingBrokenMediaTypeShouldThrowIllegalArgumentException_minimized() {
MediaTypeHeaderDelegate.parse("x; /x");
}

@Test(expected = IllegalArgumentException.class)
public void parsingBrokenMediaTypeShouldThrowIllegalArgumentException_actual() {
MediaTypeHeaderDelegate.parse("() { ::}; echo \"NS:\" $(/bin/sh -c \"expr 123456 - 123456\")");
}
}

0 comments on commit 5435246

Please sign in to comment.