Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[UNDERTOW-2509] Add 413 response code to overflowing multipart in default async handler #1693

Merged
merged 1 commit into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,10 @@ public void handleEvent(StreamSourceChannel channel) {
pooled.close();
}

} catch(FileTooLargeException e) {
UndertowLogger.REQUEST_IO_LOGGER.debug("Exception parsing data", e);
exchange.setStatusCode(StatusCodes.REQUEST_ENTITY_TOO_LARGE);
exchange.endExchange();
} catch (Throwable e) {
UndertowLogger.REQUEST_IO_LOGGER.debug("Exception parsing data", e);
exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
import io.undertow.server.handlers.BlockingHandler;
import io.undertow.server.handlers.form.MultiPartParserDefinition.FileTooLargeException;
import io.undertow.testutils.DefaultServer;
import io.undertow.testutils.HttpClientUtils;
import io.undertow.testutils.TestHttpClient;
Expand Down Expand Up @@ -198,33 +199,44 @@ public void testFileUploadWithEagerParsingAndNonASCIIFilename() throws Exception
client.getConnectionManager().shutdown();
}
}

private static HttpHandler createInMemoryReadingHandler(final long fileSizeThreshold) {
return createInMemoryReadingHandler(fileSizeThreshold, -1, null);
}

private static HttpHandler createInMemoryReadingHandler(final long fileSizeThreshold, final long maxInvidualFileThreshold, final HttpHandler async) {
return new HttpHandler() {
@Override
public void handleRequest(final HttpServerExchange exchange) throws Exception {
MultiPartParserDefinition multiPartParserDefinition = new MultiPartParserDefinition();
multiPartParserDefinition.setFileSizeThreshold(fileSizeThreshold);
multiPartParserDefinition.setMaxIndividualFileSize(maxInvidualFileThreshold);
final FormDataParser parser = FormParserFactory.builder(false)
.addParsers(new FormEncodedDataDefinition(), multiPartParserDefinition)
.build().createParser(exchange);
try {
FormData data = parser.parseBlocking();
exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR);
if (data.getFirst("formValue").getValue().equals("myValue")) {
FormData.FormValue file = data.getFirst("file");
if (file.isFileItem()) {
exchange.setStatusCode(StatusCodes.OK);
logResult(exchange, file.getFileItem().isInMemory(), file.getFileName(), stream2String(file));
if (async == null) {
try {
FormData data = parser.parseBlocking();
exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR);
if (data.getFirst("formValue").getValue().equals("myValue")) {
FormData.FormValue file = data.getFirst("file");
if (file.isFileItem()) {
exchange.setStatusCode(StatusCodes.OK);
logResult(exchange, file.getFileItem().isInMemory(), file.getFileName(), stream2String(file));
}
}
exchange.endExchange();
} catch (FileTooLargeException e) {
exchange.setStatusCode(StatusCodes.REQUEST_ENTITY_TOO_LARGE);
exchange.endExchange();
} catch (Throwable e) {
e.printStackTrace();
exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR);
exchange.endExchange();
} finally {
IoUtils.safeClose(parser);
}
exchange.endExchange();
} catch (Throwable e) {
e.printStackTrace();
exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR);
exchange.endExchange();
} finally {
IoUtils.safeClose(parser);
} else {
parser.parse(async);
}
}

Expand Down Expand Up @@ -373,6 +385,56 @@ public void testLargeContentWithoutFileNameWithSmallFileSizeThreshold() throws E
}
}

@Test
public void testFileUploadWithFileSizeThresholdOverflow_Sync() throws Exception {
DefaultServer.setRootHandler(new BlockingHandler(createInMemoryReadingHandler(10, 1, null)));

TestHttpClient client = new TestHttpClient();
try {

HttpPost post = new HttpPost(DefaultServer.getDefaultServerURL() + "/path");
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

entity.addPart("formValue", new StringBody("myValue", "text/plain", StandardCharsets.UTF_8));
entity.addPart("file", new FileBody(new File(MultipartFormDataParserTestCase.class.getResource("uploadfile.txt").getFile())));

post.setEntity(entity);
HttpResponse result = client.execute(post);
Assert.assertEquals(StatusCodes.REQUEST_ENTITY_TOO_LARGE, result.getStatusLine().getStatusCode());

} finally {
client.getConnectionManager().shutdown();
}
}

@Test
public void testFileUploadWithFileSizeThresholdOverflow_ASync() throws Exception {
DefaultServer.setRootHandler(new BlockingHandler(createInMemoryReadingHandler(10, 1, new HttpHandler() {

@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
throw new Exception();
}
})));

TestHttpClient client = new TestHttpClient();
try {

HttpPost post = new HttpPost(DefaultServer.getDefaultServerURL() + "/path");
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

entity.addPart("formValue", new StringBody("myValue", "text/plain", StandardCharsets.UTF_8));
entity.addPart("file", new FileBody(new File(MultipartFormDataParserTestCase.class.getResource("uploadfile.txt").getFile())));

post.setEntity(entity);
HttpResponse result = client.execute(post);
Assert.assertEquals(StatusCodes.REQUEST_ENTITY_TOO_LARGE, result.getStatusLine().getStatusCode());

} finally {
client.getConnectionManager().shutdown();
}
}

private void writeLargeFileContent(File file, int size) throws IOException {
int textLength = "content".getBytes().length;
FileOutputStream fos = new FileOutputStream(file);
Expand Down
Loading