Uploaded image for project: 'RESTEasy'
  1. RESTEasy
  2. RESTEASY-1784

Exception during chunked transfer is suppressed

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • Major
    • 4.6.0.Final
    • 3.6.2.Final
    • None
    • None

    Description

      Regression seen with resteasy 3.1.4: An exception thrown during chunked transfer is erroneously suppressed by resteasy. Thus the servlet container deems the call successful and writes a valid end-chunk, the client has no chance to see that there was an error. One common usecase would be to detect whether a large download was completed successfully.

      Reproducable by e.g.:

          @Path("ErrorAfterFlushWithoutBody")
          @GET
          @Produces(MediaType.APPLICATION_OCTET_STREAM)
          public void errorAfterFlushWithoutBody(@Context HttpServletResponse response) throws IOException {
              response.getOutputStream().flush();
              throw new IOException("a strange io error");
          }
      
          @Test
          public void testFlushWithoutBody() throws Exception {
              String data = NetworkClient.readIgnoreException("localhost", service.getPort(), "/ErrorAfterFlushWithoutBody");
      
              Assert.assertTrue(data.startsWith("HTTP/1.1 200 "));
              Assert.assertTrue(data.contains("Transfer-Encoding: chunked"));
              // there must be no end-chunk
              Assert.assertFalse(data.endsWith("0"));
          }
      
      

      It seems this problem was introduced by this change in SynchronousDispatcher:writeException during RESTEASY-1238 since 3.0.23.Final, 3.1.3.Final .

      Unable to find source-code formatter for language: diff. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
      -      if (response.isCommitted()) throw new UnhandledException(Messages.MESSAGES.responseIsCommitted(), e);
      +      if (response.isCommitted())
      +      {
      +         LogMessages.LOGGER.debug(Messages.MESSAGES.responseIsCommitted());
      +         return;
      +      }
      

      (... Error handling during chunked transfers is a long sore point. Tomcat was broken until early tomcat8: wrote a valid end-chunk on exception although it should terminate the connection without end-chunk. Apache HttpClient until ~2 years ago was also broken, it simply ignored missing end-chunks due to some broken IIS which always omitted end-chunks. Browsers always ignore missing end-chunks because users have no good options on how to deal with it. The Problem was finally fixed in tomcat+httpclient and i am unhappy to see it resurface with resteasy)

      Attachments

        1. 4CFA345F-D5BE-46F0-98C6-B3054FAD0422.png
          4CFA345F-D5BE-46F0-98C6-B3054FAD0422.png
          814 kB
        2. 9C3F5FA8-42ED-4D4D-9A48-CE64E50DBD2E.png
          9C3F5FA8-42ED-4D4D-9A48-CE64E50DBD2E.png
          645 kB
        3. image-2020-01-07-13-55-01-011.png
          image-2020-01-07-13-55-01-011.png
          296 kB
        4. screenshot-1.png
          screenshot-1.png
          690 kB
        5. screenshot-2.png
          screenshot-2.png
          124 kB
        6. screenshot-3.png
          screenshot-3.png
          705 kB
        7. screenshot-4.png
          screenshot-4.png
          1.17 MB
        8. screenshot-5.png
          screenshot-5.png
          664 kB
        9. screenshot-6.png
          screenshot-6.png
          280 kB

        Issue Links

          Activity

            People

              weinanli Weinan Li
              markuskull Markus Kull (Inactive)
              Votes:
              1 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: