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

RESTEasy Reactive multipart form file upload hangs when using Reactive Routes failure handler #19154

Closed
sashamc opened this issue Aug 1, 2021 · 6 comments · Fixed by #19189
Closed
Labels
area/rest kind/bug Something isn't working
Milestone

Comments

@sashamc
Copy link

sashamc commented Aug 1, 2021

Describe the bug

When RESTEasy Reactive service should process multipart form file uploads from clients, if service contains failure handler -- @route(type = Route.HandlerType.FAILURE) -- file upload causes hanging.
This occurs only with Quarkus 2.1.0.Final and only with the presence of that failure handler.

Without Reactive Routes failure handler file uploads work OK.
The same project created with Quarkus 2.0.3.Final works OK.

Expected behavior

Successful file upload

% curl -v -F [email protected] http://127.0.0.1:8080/rest/form
*   Trying 127.0.0.1:8080...
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> POST /rest/form HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.77.0
> Accept: */*
> Content-Length: 4845
> Content-Type: multipart/form-data; boundary=------------------------aea3a41b009307dd
> 
* We are completely uploaded and fine
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-length: 151
< Content-Type: text/plain
< 
* Connection #0 to host 127.0.0.1 left intact
file: pom.xml, content type: application/xml, uploaded file: /var/folders/h_/t7f0c9kj02q79yj5nn0k33140000gn/T/uploads/undertow1736355395262476198upload%

Actual behavior

When the curl command tries to upload file, upload process hangs.

% curl -v -F [email protected] http://127.0.0.1:8080/rest/form
*   Trying 127.0.0.1:8080...
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> POST /rest/form HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.77.0
> Accept: */*
> Content-Length: 4845
> Content-Type: multipart/form-data; boundary=------------------------ec25671b52288ad7
> 
* We are completely uploaded and fine
^C

How to Reproduce?

Simple reproducer

Steps to reproduce the behavior:

  • Create project using quarkus maven plugin (Quarkus 2.1.0.Final) with extensions: quarkus-resteasy-reactive, quarkus-resteasy-reactive-jsonb, quarkus-vertx-web.
  • Create ReactiveResource class with method:
  @POST
  @Produces(MediaType.TEXT_PLAIN)
  @Consumes(MediaType.MULTIPART_FORM_DATA)
  @Path("form")
  public String form(@MultipartForm FormData formData) { 
    java.nio.file.Path path = fileUpload.uploadedFile();
    return "Uploaded file: " + path.toString();
 }
  • Create FormData class
public class FormData {
  @RestForm("payload")
  public FileUpload file;
}
  • Create Failure Handler
@ApplicationScoped
public class FailureEndpoint {
  @Route(type = Route.HandlerType.FAILURE)
  void responseFailure(UnsupportedOperationException e, HttpServerResponse response) {
    response.setStatusCode(501).end(e.getMessage());
  }
}
  • Start service ./mvnw compile quarkus:dev
  • Run command curl -v -F [email protected] http://127.0.0.1:8080/rest/form from project folder to upload for example pom.xml file: upload hangs
  • Then remove FailureEndpoint.java file, restart service ./mvnw clean compile quarkus:dev : upload works Ok.

Output of uname -a or ver

macOS 10.15.7; Darwin Kernel Version 19.6.0: Tue Jun 22 19:49:55 PDT 2021; root:xnu-6153.141.35~1/RELEASE_X86_64 x86_64

Output of java -version

OpenJDK Runtime Environment AdoptOpenJDK-11.0.11+9 (build 11.0.11+9)

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.1.0.Final; 2.0.3.Final

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.8.1 (05c21c65bdfed0f71a2f2ada8b84da59348c4c5d)

Additional information

No response

@sashamc sashamc added the kind/bug Something isn't working label Aug 1, 2021
@quarkus-bot
Copy link

quarkus-bot bot commented Aug 1, 2021

/cc @FroMage, @geoand, @stuartwdouglas

@quarkus-bot quarkus-bot bot added the area/rest label Aug 1, 2021
@geoand
Copy link
Contributor

geoand commented Aug 2, 2021

I will have a quick look, but I have the following question:

Is there a specific reason you are trying to handle failures with @Route(type = Route.HandlerType.FAILURE)?
That is a construct from Reactive Routes and it has not been tested with RESTEasy Reactive.
In RESTEasy Reactive you would handle the error as is mentioned here.

@sashamc
Copy link
Author

sashamc commented Aug 2, 2021

No, there is not. Ok if using them both simultaneously considered as bad practice.
Thank You.

@geoand
Copy link
Contributor

geoand commented Aug 2, 2021

For posterity, the reason the @Route messes up with RESTEasy Reactive's multipart handling starting from version 2.1, is because we have pivoted to our own Multipart handling instead of relying on Vert.x.
The reason this does not play well with Reactive Routes is because Reactive Routes installs a BodyHandler for all requests which then gets executed before the multipart in RESTEasy Reactive.

@cescoffier @stuartwdouglas this raises the question about whether or not we should disallow the use of Rective Routes with RESTEasy Reactive, since more problems like this could surface in the future.

@stuartwdouglas
Copy link
Member

We should be able to handle the BodyHandler case, as there are other extensions that install it as well.

@geoand
Copy link
Contributor

geoand commented Aug 3, 2021

Is there a way to remove the existing body handler?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/rest kind/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants