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

StreamingOutput flush/close doesn't work in 3.1.4

    Details

    • Type: Bug
    • Status: Closed (View Workflow)
    • Priority: Major
    • Resolution: Done
    • Affects Version/s: 3.1.4.Final
    • Fix Version/s: 4.0.0.Beta1
    • Component/s: jaxrs
    • Labels:
      None
    • Steps to Reproduce:
      Hide

      Example failing code (works fine in 3.0.9):

      @GET
      	@Path("test")
      	@Produces("text/event-stream")
      	public StreamingOutput test(
      			@Context HttpServletRequest request,
      			@Context HttpServletResponse response) {
      		response.setStatus(HttpServletResponse.SC_OK);
      		response.setContentType("text/event-stream");
      		response.addHeader("Connection", "close");
      		try {
      			response.flushBuffer();
      		} catch (IOException e) {
      			throw new RuntimeException(e.getMessage(), e);
      		}
       
      		AsyncContext async = request.startAsync();
      		async.setTimeout(0);
      		
      		return new StreamingOutput() {
      			public void write(OutputStream outputStream)
      					throws IOException, WebApplicationException {
      				Writer writer = new BufferedWriter(new OutputStreamWriter(outputStream));
      				
      				for (int i = 0; i < 10; i++) {
      					writer.write("test " + i + "\n");
      					writer.flush();
       
      					try {
      						Thread.sleep(1000);
      					} catch (InterruptedException e) {
      						throw new RuntimeException(e.getMessage(), e);
      					}
       
      				}
      			}
      		};
      	}
      

      Show
      Example failing code (works fine in 3.0.9): @GET @Path ( "test" ) @Produces ( "text/event-stream" ) public StreamingOutput test( @Context HttpServletRequest request, @Context HttpServletResponse response) { response.setStatus(HttpServletResponse.SC_OK); response.setContentType( "text/event-stream" ); response.addHeader( "Connection" , "close" ); try { response.flushBuffer(); } catch (IOException e) { throw new RuntimeException(e.getMessage(), e); }   AsyncContext async = request.startAsync(); async.setTimeout( 0 ); return new StreamingOutput() { public void write(OutputStream outputStream) throws IOException, WebApplicationException { Writer writer = new BufferedWriter( new OutputStreamWriter(outputStream)); for ( int i = 0 ; i < 10 ; i++) { writer.write( "test " + i + "\n" ); writer.flush();   try { Thread.sleep( 1000 ); } catch (InterruptedException e) { throw new RuntimeException(e.getMessage(), e); }   } } }; }
    • Workaround:
      Workaround Exists
    • Workaround Description:
      Hide

      javax.servlet.ServletResponse#flushBuffer method could be used. But servletResponse instance should be passed to StreamingOutput instance in advance, and also in this case any wrapping OutputStreams won't be flushed.

      Show
      javax.servlet.ServletResponse#flushBuffer method could be used. But servletResponse instance should be passed to StreamingOutput instance in advance, and also in this case any wrapping OutputStreams won't be flushed.

      Description

      Hi, after changing resteasy dependency from 3.0.9 to 3.1.4, our StreamingOutput implementation stopped flushing data. So, the data is flushed only on exitting StreamingOutput.method.
      After investigating resteasy source code, I've found that the root cause is empty flush method in HttpServletResponseWrapper.DeferredOutputStream (code removed in https://issues.jboss.org/browse/RESTEASY-1650).

      We are using jetty 9.2.19 as a container and ServletRequest.startAsync feature to make responses async. This async invocation makes jetty not to close response (and output stream) on exit.
      Also, since jetty doesn't close the output with this async, we should take care of it ourselves, but with empty close method, it's also impossible from OutputStream

        Gliffy Diagrams

          Attachments

            Issue Links

              Activity

                People

                • Assignee:
                  asoldano Alessio Soldano
                  Reporter:
                  buggy Iaroslav Shepilov
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  2 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved: