To make repro easier: https://gist.github.com/mwisnicki/6df71b2b5f7712306fca27bf34c24e94
On Tue, 10 Aug 2021 at 04:00, Marcin Wisnicki <mwisni...@gmail.com> wrote: > > However I've noticed that in Tomcat the behaviour can only be achieved > by throwing an exception before close. > If I don't throw and simply return or call close before exception > Tomcat will write terminal '0'. > > Is there a way to trigger immediate close without that write('0') > without using exceptions? > > On Tue, 10 Aug 2021 at 03:27, Marcin Wisnicki <mwisni...@gmail.com> wrote: > > > > Thanks, it seems like it must be one of Spring Boot's filters breaking > > it. I should've tried without it first, mea culpa. > > In a pure tomcat container it works as you described whereas with > > Spring something inserts final 0 so the aborted connection looks like > > a valid chunked response to clients. > > > > I'll move my question to a more appropriate forum. > > > > On Tue, 10 Aug 2021 at 02:45, Mark Thomas <ma...@apache.org> wrote: > > > > > > 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