[jira] [Commented] (CXF-8356) JAXRS Multipart-Handling broken for InputStream/Datasource parameters

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

[jira] [Commented] (CXF-8356) JAXRS Multipart-Handling broken for InputStream/Datasource parameters

Andriy Redko (Jira)

    [ https://issues.apache.org/jira/browse/CXF-8356?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17214512#comment-17214512 ]

Lars Ködderitzsch commented on CXF-8356:

The client is a JAXRS-Proxy based on the annotated service interface, so I am not doing anything special there with regards to HTTP Headers.

I investigated a bit more and it seems the problem - Content-Type header missing - only presents itself when using LocalTransport (for testing).
In this case only the `Content-Type` message property ("(String)message.get(Message.CONTENT_TYPE);") seems to be present.

When testing a real deployment over HTTP the header is set and the service works just fine.

So effectively it appears that (https://github.com/apache/cxf/blob/dc71ce1635330136e472e0b6fb5ce4a71ae0d474/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java#L873):
- if using LocalTransport `mc.getHttpHeaders().getMediaType()` returns null, but `message.get(Message.CONTENT_TYPE)` still yields the proper content type (`multipart/form-data; boundary="uuid:faf5b92a-65ae-4783-a1e7-a2575060c8ae"`)
- mt being null leads to the stream being copied and closed, leading to a closed stream in the actual service

> JAXRS Multipart-Handling broken for InputStream/Datasource parameters
> ---------------------------------------------------------------------
>                 Key: CXF-8356
>                 URL: https://issues.apache.org/jira/browse/CXF-8356
>             Project: CXF
>          Issue Type: Bug
>          Components: JAX-RS
>    Affects Versions: 3.4.0, 3.3.7
>            Reporter: Lars Ködderitzsch
>            Priority: Major
> Multipart attachements mapped to InputStream/Datasource parameters are currently broken, due to their respective DelegatingInputStream being closed too early.
> As of cxf-3.3.4 this was still working.
> As far as I can see, the early closing happens here:
> {code:java}
> Daemon System Thread [default-workqueue-1] (Suspended (breakpoint at line 46 in DelegatingInputStream))
> owns: PhaseInterceptorChain  (id=49)
> DelegatingInputStream.close() line: 46
> JAXRSUtils.copyAndGetEntityStream(Message) line: 1897
> JAXRSUtils.processRequestBodyParameter(Class<?>, Type, Annotation[], Message, OperationResourceInfo) line: 884
> JAXRSUtils.processParameters(OperationResourceInfo, MultivaluedMap<String,String>, Message) line: 832
> JAXRSInInterceptor.processRequest(Message, Exchange) line: 214
> JAXRSInInterceptor.handleMessage(Message) line: 78
> PhaseInterceptorChain.doIntercept(Message) line: 308
> ChainInitiationObserver.onMessage(Message) line: 121
> LocalConduit$LocalConduitOutputStream$1.run() line: 88
> AutomaticWorkQueueImpl$3.run() line: 412
> AutomaticWorkQueueImpl$1(ThreadPoolExecutor).runWorker(ThreadPoolExecutor$Worker) line: 1128
> ThreadPoolExecutor$Worker.run() line: 628
> AutomaticWorkQueueImpl$AWQThreadFactory$1.run() line: 345
> Thread.run() line: 834
> {code}
> I believe this change (https://github.com/apache/cxf/commit/dc71ce1635330136e472e0b6fb5ce4a71ae0d474) led to this issue, due to `contentType` and `mt` (Mediatype) variable disagreeing, leading to unwanted? copy and closing of the stream.
> A few lines below the `contentType` is used again to derive the MediaType, which leads me to believe the first`mt` variable is incorrect.
> A local patch for this line made it working again for me, although I am uncertain this is the correct fix:
> {code:java}
> MediaType mt = toMediaType(contentType);
> {code}
> For reference, one of the annotated methods producing this issue for us:
> {code:java}
>     @POST
>     @Path("/pdf")
>     @Consumes(MediaType.MULTIPART_FORM_DATA)
>     @Operation(summary = "Rendert das übergebene TemplateModel mit Hilfe des übergebenen Templates")
>     Response getPDF(
>             @Parameter(
>                     description = "Das Template, das zum Rendern der Daten benutzt wird",
>                     content = @Content(schema = @Schema(implementation = TemplatePart.class))) @Multipart(
>                             value = "template", type = "application/octet-stream") InputStream template,
>             @Parameter(description = "Charset des Templates") @QueryParam("charset") String charset,
>             @RequestBody(
>                     description = "Die Daten, die mit Hilfe des übergebenen Templates gerendert werden") @Multipart(
>                             value = "data", type = "application/json") TemplateModel data);
> {code}
> In this case this issue led to `template` being a `DelegatingInputStream` wrapping another (closed) `DelegatingInputStream` on the server side.

This message was sent by Atlassian Jira