Repository navigation
Malformed application/x-www-form-urlencoded and multipart/form-data request bodies result in 500 instead of 400 #57827
Copy link
Copy link
Open
Labels
Description
Describe the bug
In Quarkus REST, some malformed form request bodies result in 500 Internal Server Error instead of 400 Bad Request:
- An
application/x-www-form-urlencodedbody with an invalid percent-encoding (e.g.name=%zz).FormEncodedDataDefinitionpasses the value toURLUtils.decode(), which throws anIllegalArgumentExceptionthat is not handled. The same invalid encoding in the query string correctly results in a 400. - A
multipart/form-databody that ends without the closing boundary.MultiPartParserDefinitionthrowsIOException("Connection terminated parsing multipart request")when the input ends before the parser is complete. The request is then treated like a client disconnect: a 500 is returned and only a DEBUG message saying that "the client likely terminated the connection" is logged, although the body was sent completely. Other malformed multipart bodies already result in a 400 (MalformedMessageException).
Expected behavior
400 Bad Request.
Actual behavior
500 Internal Server Error. For case 1:
ERROR [io.quarkus.vertx.http.runtime.QuarkusErrorHandler] (executor-thread-2) HTTP Request to /echo/form failed, error id: ...: java.lang.IllegalArgumentException: Failed to decode URL %zz to UTF-8
at org.jboss.resteasy.reactive.common.util.URLUtils.failedToDecodeURL(URLUtils.java:221)
at org.jboss.resteasy.reactive.common.util.URLUtils.decode(URLUtils.java:155)
at org.jboss.resteasy.reactive.common.util.URLUtils.decode(URLUtils.java:81)
at org.jboss.resteasy.reactive.server.core.multipart.FormEncodedDataDefinition$FormEncodedDataParser.decodeParameterValue(FormEncodedDataDefinition.java:208)
For case 2 nothing is logged at the default log level.
How to Reproduce?
- Create a project:
mvn io.quarkus.platform:quarkus-maven-plugin:3.40.1.1:create \ -DprojectGroupId=org.acme -DprojectArtifactId=rest-repro \ -Dextensions=rest -DnoCode cd rest-repro - Add
src/main/java/org/acme/EchoResource.java:package org.acme; import jakarta.ws.rs.Consumes; import jakarta.ws.rs.FormParam; import jakarta.ws.rs.POST; import jakarta.ws.rs.Path; import jakarta.ws.rs.core.MediaType; import org.jboss.resteasy.reactive.RestForm; @Path("/echo") public class EchoResource { @POST @Path("/form") @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public String form(@FormParam("name") String name) { return name; } @POST @Path("/multipart") @Consumes(MediaType.MULTIPART_FORM_DATA) public String multipart(@RestForm String name) { return name; } }
- Run
./mvnw quarkus:dev. - Send requests:
curl -s -o /dev/null -w "%{http_code}\n" -X POST localhost:8080/echo/form -H 'Content-Type: application/x-www-form-urlencoded' -d 'name=foo' # 200 curl -s -o /dev/null -w "%{http_code}\n" -X POST localhost:8080/echo/form -H 'Content-Type: application/x-www-form-urlencoded' -d 'name=%zz' # 500 printf -- '--xyz\r\nContent-Disposition: form-data; name="name"\r\n\r\nfoo\r\n--xyz--\r\n' | curl -s -o /dev/null -w "%{http_code}\n" -X POST localhost:8080/echo/multipart -H 'Content-Type: multipart/form-data; boundary=xyz' --data-binary @- # 200 printf -- '--xyz\r\nContent-Disposition: form-data; name="name"\r\n\r\nfoo' | curl -s -o /dev/null -w "%{http_code}\n" -X POST localhost:8080/echo/multipart -H 'Content-Type: multipart/form-data; boundary=xyz' --data-binary @- # 500
The same result with 4.0.0.Beta1 instead of 3.40.1.1 in step 1.
Output of uname -a or ver
Linux 6.18.54.1-microsoft-standard-WSL2 x86_64 GNU/Linux
Output of java -version
OpenJDK 21.0.12.1 (Temurin-21.0.12.1+1)
Quarkus version or git rev
3.40.1.1, 4.0.0.Beta1, main (5e98984)
Build tool (ie. output of mvnw --version or gradlew --version)
Apache Maven 3.9.9
Additional information
Related to #52767, which fixed the empty multipart body case. I'll open a PR with a fix and tests.
Reactions are currently unavailable
Activity