[
https://issues.apache.org/jira/browse/SLING-2039?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13012890#comment-13012890
]
Felix Meschberger commented on SLING-2039:
------------------------------------------
Investigation shows a problematic interfaction between three bundles:
* the Engine maintaining buffers per included resource
* Scripting Core using OnDemandWriter to postpone accessing the actual
writer until data is written
* JSP's JspWriter which itself buffers output (8K by default in Sling's
Jasper)
What happens is as follows:
(1) html.jsp writes to the JspWriter 1 which is based on OnDemandWriter 1. The
actual response writer is not retrieved yet
(2) list.html.jsp is included
(3) list.html.jsp writes to JspWriter 2 which is based on OnDemandWriter 2
(4) Once list.html.jsp writes data in excess of the JspWriter2's buffer the
data is written to OnDemandWriter 2.
(5) This causes OnDemandWriter 2 to write to JspWriter 1.
(6) This will immediately cause JspWriter 1 to have to write since the buffer
overflows.
(7) Thus OnDemandWriter 1 gets the PrintWriter from the
SlingHttpServletResponseImpl
(8) SlingHttpServlteResponseImpl gets a BufferedPrintWriter 2 from the
currentContentData (which is related to the list.html.jsp script)
(8a) the BufferedPrintWriter 2 is backed by BufferedPrintWriter 1 related to
the html.jsp script
(9) OnDemandWriter 1 writes to the BufferedPrintWriter
(10) list.html.jsp terminates and the of JspWriter 2 is flushed to
OnDemandWriter 2 and in turn to JspWriter 1 (buffering again)
(11) upon termination of list.html.jsp the currentContentData is disposed and
BufferedPrintWriter 2 is written to the BufferedPrintWriter 1
(11) html.jsp writes some more data to JspWriter 1
(12) html.jsp terminates and remaining data from JspWriter 1 is flushed to
OnDemandWriter 1 and thus BufferedPrintWriter 2
(13) upon termination of html.jsp the currentContentData is disposed and
BufferedPrintWriter 1 sent to the client
The problem is that the "lowest" OnDemandWriter 1 is backed by
BufferedPrintWriter 2 which belonged to the highest included request. But since
BufferedPrintWriter 2 is not flushed any more when the html.jsp script ends
(because it has already been flushed when list.html.jsp ended) some output
remains in the defunct buffer.
The simplest fix is to not use a buffer per ContentData but a single global
buffer for the RequestData. This also uses less memory, is easier to handle
(less cycles spent managing it), simpler to maintain. Having a buffer per
ContentData dates way back before Apache Sling and has probably (cannot
remember any more, sorry) done for some stupid reason in the
pre-HttpServletWrapper days.....
> Output lost with JSPs and sling:include
> ---------------------------------------
>
> Key: SLING-2039
> URL: https://issues.apache.org/jira/browse/SLING-2039
> Project: Sling
> Issue Type: Bug
> Components: Engine
> Affects Versions: Engine 2.2.2
> Reporter: Felix Meschberger
> Assignee: Felix Meschberger
> Fix For: Engine 2.2.4
>
>
> Using a single output buffer per included resource may lead to loss of
> response data.
> Consider this setup:
> - main request handled by html.jsp. Some data is written to "out"
> (buffering JspWriter)
> - html.jsp incudes another jsp (list.html.jsp) which in turn writes more
> data
> - html.jsp continues writing to the output
> If list.html.jsp sends less than the JspWriter's buffer, everything is fine.
> As soon as the JspWritter buffer overflows, though, only the first bytes of
> the actual response (exactly the size of the JspWriter buffer) is returned.
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira