You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by bu...@apache.org on 2017/06/25 12:48:10 UTC

[Bug 61217] New: Tomcat dose not send all buffer in case of response was modify

https://bz.apache.org/bugzilla/show_bug.cgi?id=61217

            Bug ID: 61217
           Summary: Tomcat dose not send all buffer in case of response
                    was modify
           Product: Tomcat 8
           Version: 8.0.33
          Hardware: Macintosh
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Catalina
          Assignee: dev@tomcat.apache.org
          Reporter: tzachi.strugo@behalf.com
  Target Milestone: ----

IdentityOutputFilter not write all bytes in case the response was increased in
servlet filter

scenario:
1. Add filter servlet that changed the content of the response(increase the
size).
2. add controller that create response with header content-type

Example:
  originalResponse message - 'Example of response to request-1'
  modify response - 'Example of response to cmVxdWVzdC0x' 

the size of original is 33 
the size of the modify is 36

The response of the servlet will be only 33 chars from the modify response: 
'Example of response to cmVxdWVzd'

The reason is that response initialize IdentityOutputFilter with content length
of the original.
the doWrite method get byte chunk but it remove the bytes that bigger than 
in case response contains Content-Length header the IdentityOutputFilter will
try to write buffer. 

 if (result > remaining) {
                    // The chunk is longer than the number of bytes remaining
                    // in the body; changing the chunk length to the number
                    // of bytes remaining
                    chunk.setBytes(chunk.getBytes(), chunk.getStart(),
                                   (int) remaining);
                    result = (int) remaining;
                    remaining = 0;
                }

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 61217] Tomcat does not send all buffer in case of response was modify

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=61217

--- Comment #3 from tzachi.strugo@behalf.com ---
Guys thank you for the quick response! 

Chuck,
before i opened the bug i saw source code of version 44 and
IdentityOutputFilter class have the same logic as 33. 
i will try to run it with 8.0.44.  

Mark,

it is a good question.

but before i answer that i want to share the info that i am running embedded
tomcat version 8.0.33 via spring boot. 

as you can see from below stack trace spring invoke my controller and flush the
response right after that.
so IdentityOutputFilter initialize at that point.

Then the thread return back to my filter that responsible to modify it and
write it again. 
response.getOriginalResponse().getWriter().write(modifyResponseContent);
The IdentityOutputFilter instance is already initialized with remaining of the
original response.

StackTrace:
http-nio-9999-exec-5@12102" daemon prio=5 tid=0x19 nid=NA runnable
  java.lang.Thread.State: RUNNABLE
          at
org.apache.coyote.http11.filters.IdentityOutputFilter.setResponse(IdentityOutputFilter.java:118)
          at
org.apache.coyote.http11.AbstractOutputBuffer.addActiveFilter(AbstractOutputBuffer.java:200)
          at
org.apache.coyote.http11.AbstractHttp11Processor.prepareResponse(AbstractHttp11Processor.java:1492)
          at
org.apache.coyote.http11.AbstractHttp11Processor.action(AbstractHttp11Processor.java:739)
          at org.apache.coyote.Response.action(Response.java:179)
          at org.apache.coyote.Response.sendHeaders(Response.java:350)
          at
org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:335)
          at
org.apache.catalina.connector.OutputBuffer.flush(OutputBuffer.java:317)
          at
org.apache.catalina.connector.Response.flushBuffer(Response.java:496)
          at
org.apache.catalina.connector.ResponseFacade.flushBuffer(ResponseFacade.java:318)
          at
javax.servlet.ServletResponseWrapper.flushBuffer(ServletResponseWrapper.java:176)
          at
com.zazma.bewebapp.filter.ResponseWrapper.flushBuffer(ResponseWrapper.java:70)
          at
org.springframework.http.server.ServletServerHttpResponse.flush(ServletServerHttpResponse.java:96)
          at
org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:206)
          at
org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:81)

Questions:
1. In case the controller return JSON (without header Content-Length)it execute
ChunkedOutputFilter. 
        1.1 what is the different between dose output filter?
        1.2 why in IdentityOutputFilter ignore the bytes that bigger than
remaining
                        // The chunk is longer than the number of bytes
remaining
            // in the body; changing the chunk length to the number
            // of bytes remaining
            chunk.setBytes(chunk.getBytes(), chunk.getStart(),
                                (int) remaining);

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 61217] Tomcat does not send all buffer in case of response was modify

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=61217

Mark Thomas <ma...@apache.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |INVALID

--- Comment #4 from Mark Thomas <ma...@apache.org> ---
When the response is flushed, the HTTP headers are written to the client. At
that point, if a content-length is set, that content-length is fixed.

If you don't want this behaviour, wrap the response and prevent the application
setting the content-length header. This will cause a switch to chunked
encoding.

Note that the only spec compliant way to modify the output is to wrap the
response and handle all the changes in the wrapped response. This can get quite
tricky, quite quickly.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 61217] Tomcat does not send all buffer in case of response was modify

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=61217

--- Comment #1 from Chuck Caldarale <ch...@unisys.com> ---
Version 8.0.33 is over a year old, and many changes have been implemented since
then.  Please try your test with the current level (8.0.44) and see if the
problem still exists.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 61217] Tomcat does not send all buffer in case of response was modify

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=61217

Chuck Caldarale <ch...@unisys.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Tomcat dose not send all    |Tomcat does not send all
                   |buffer in case of response  |buffer in case of response
                   |was modify                  |was modify

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 61217] Tomcat does not send all buffer in case of response was modify

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=61217

--- Comment #2 from Mark Thomas <ma...@apache.org> ---
What sets the Content-Length header to 33?

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org