On 10/08/2021 02:25, Marcin Wisnicki wrote:
I have a servlet (it's really a SpringBoot controller but it shouldn't
matter?) in Tomcat 9.0.46 that streams responses of unknown size to
the browser.

I've discovered that if the streaming process fails in the middle of
the write, the client will simply get an incomplete file and think it
was successful.

Then you have a broken client.

Indeed there is no way to tell from the browser side there was an error.

That statement is incorrect.

   void doGet(HttpServletResponse resp) {
     resp.setStatus(200);
     resp.setHeader("Content-Disposition", "...");
     resp.setContentType("application/octet-stream");
     var out = resp.getOutputStream();
     out.flush();
     if (true) throw new RuntimeException("simulated error");
     // status is already sent here, can't change it!
   }

As far as I can tell a web server should close connection with TCP RST
or write some garbage that's not a valid chunked response.

You won't see a TCP RST. You will see invalid chunked encoding.

This is what some other servers do such as express.js.

Unfortunately Tomcat does neither and also there seems to be no way to
trigger that using either Servlet or Tomcat api.

Again, that statement is incorrect.

I've tested it by setting "Connection: close" then writing garbage and
it seems browser recognized download error.
But then I lose chunking in the output stream and can't actually write
a response.

How do people solve it?

Look at the following from a test using telnet to make a request to the sample servlet above:

$ telnet localhost 8080
Trying ::1...
Connected to localhost.
Escape character is '^]'.
GET /tomcat-bugs/user004 HTTP/1.1
Host: localhost

HTTP/1.1 200
Content-Type: text/plain
Transfer-Encoding: chunked
Date: Tue, 10 Aug 2021 06:38:06 GMT

Connection closed by foreign host.
$

The headers are sent when the Servlet flushes the response. That is as required by the Servlet specification.

What tells the client that the response is incomplete is that chunked encoding is being used but there is no final chunk.

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to