[
https://issues.apache.org/jira/browse/CXF-9057?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Johannes Herr updated CXF-9057:
-------------------------------
Attachment: chunked-reproducer.tar.gz
> Chunked Stream is closed regularly when Exception is thrown
> -----------------------------------------------------------
>
> Key: CXF-9057
> URL: https://issues.apache.org/jira/browse/CXF-9057
> Project: CXF
> Issue Type: Bug
> Affects Versions: 3.5.8
> Reporter: Johannes Herr
> Priority: Major
> Attachments: chunked-reproducer.tar.gz
>
>
> In response to SOAP requests served by Apache CXF we send large datasets
> streamed directly from a database. Because of the size of the data, chunked
> encoding is used. Unfortunately when a database error occurs and an exception
> is thrown while data is sent, the client will receive a regular ending to the
> chunked data stream. That means he has no way to recognise that an error
> occurred and that he has only received a partial file.
> To be more specific the response looks somewhat like this:
> {code:java}
> HTTP/1.1 200 OK
> Date: Tue, 10 Sep 2024 16:17:45 GMT
> Content-Type: multipart/related; type="application/xop+xml";
> boundary="uuid:49aa53f9-ec29-4f1a-bc07-a21256c2f940";
> start="<[email protected]>"; start-info="text/xml"
> Transfer-Encoding: chunked
> Server: Jetty(10.0.21)
> 8000
> --uuid:49aa53f9-ec29-4f1a-bc07-a21256c2f940
> Content-Type: application/xop+xml; charset=UTF-8; type="text/xml"
> Content-Transfer-Encoding: binary
> Content-ID: <[email protected]>
> <soap:Envelope
> xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">[...]</soap:Envelope>
> --uuid:49aa53f9-ec29-4f1a-bc07-a21256c2f940
> Content-Type:
> Content-Transfer-Encoding: binary
> Content-ID: <[email protected]>
> xxxxxxxxxxxx[...]xxxxxxx
> 356
> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
> 0
> {code}
> That means the response ends with the "0" entry, indicating that the transfer
> is complete.
> What should happen instead is that the response should be closed without
> sending the final 0 entry. ([https://stackoverflow.com/a/17203961/136247])
> For example when we use a Servlet to stream data to a client a throw an
> exception the result will look something like this:
> {code:java}
> HTTP/1.1 200 OK
> Date: Fri, 13 Sep 2024 09:31:48 GMT
> Content-Type: text/plain;charset=utf-8
> Transfer-Encoding: chunked
> Server: Jetty(10.0.21)
> 8
> Chunk 1
> 8
> Chunk 2
> 8
> Chunk 3
> 8
> Chunk 4
> 8
> Chunk 5
> {code}
> Here there is no closing 0 marker. As a result clients can recognise the
> error. (Curl will report "curl: (18) transfer closed with outstanding read
> data remaining", Chrome "Failed to load resource:
> net::ERR_INCOMPLETE_CHUNKED_ENCODING")
> CXF should do the same and not end the chunked stream regularly, when an
> exception is thrown.
> I have tested with Tomcat and Jetty. Both show the same behaviour.
> To provide some detail, Exceptions are caught by CXF here:
> org/apache/cxf/phase/PhaseInterceptorChain.java:328
> {code:java}
> } catch (RuntimeException ex) {
> if (!faultOccurred) {
> faultOccurred = true;
> wrapExceptionAsFault(message, ex);
> }
> state = State.ABORTED;
> }
> {code}
> The exception is logged, but not rethrown.
> If the exception would be thrown, for instance Tomcats ErrorReportValve would
> shut down the output and thereby prevent the end of the input and closing 0
> to be written.
> org/apache/catalina/valves/ErrorReportValve.java:112
> {code:java}
> // Now close immediately to signal to the client that
> // something went wrong
> response.getCoyoteResponse().action(ActionCode.CLOSE_NOW,
>
> request.getAttribute(RequestDispatcher.ERROR_EXCEPTION));
> {code}
> Without an exception to prevent this, a regular end of the stream will be
> written by
> org/apache/catalina/connector/CoyoteAdapter.java:371
> response.finishResponse();
> In Summary: CXF ends a chunked encoded stream in a regular way in spite of
> exceptions occurring, which makes it impossible for clients to recognise that
> they have downloaded partial and therefore corrupt data.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)