You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Wolfgang Hoschek <wo...@cern.ch> on 2001/09/29 01:56:08 UTC
Re: Filters and Transfer-Encoding: chunked
> > I am facing a problem when useing a filter. The problem is that the
>"Transfer-Encoding" header does not appear to be getting set. In this case
>the filter is doing some simple xsl transformations and passing on the
>results to the response's output stream. Unfortunatly because the content
>is not being chunked by Tomcat the socket just sits there open.
> >
> > I'm not sure how tomcat knows to chunk the data. When working with an
>unfiltered jsp page the data gets chunked as expected. Does the filter need
>to do anything to "chunk" the data?
>
>No, I don't think so. I was able to use filter to set different headers
>including "Content-Encoding" to write out to the response's outputstream
>just fine. Hope this help.
Somwhat related problem here (TC4 stand-alone).
I would like to use response chunked encoding with http.HttpConnector but
so far fail to do so.
Let me try and explain: The servlet in use does not set the response
content-length. This apparently switches off chunked encoding. Browsing
through the TC4 source it seems that a servlet can effectively switch off
chunked encoding with a single outputStream.flush() early on, say flushing
a couple of bytes (even though the servlet buffer size may be very large),
which might be the cause of my problems.
ResponseStream.flush() reads
/**
* Flush any buffered data for this output stream, which also
causes the
* response to be committed.
*/
public void flush() throws IOException {
if (closed)
throw new
IOException(sm.getString("responseStream.flush.closed"));
if (commit)
response.getResponse().flushBuffer();
}
Q1: Is this behaviour defined somewhere in the spec? Open to
interpretation? Intuitively I'd think only response.flushBuffer() should
really flush to the socket and ResponseStream.flush() above should copy
into the buffer as long as it does not overflow. (response.flushBuffer() is
automatically called finally anyway).
Now I can't fix the closed source third party servlet (big XSLT stuff). As
a work-around I've been trying to write a filter, but so far no luck.
Q2: Probably needs a custom Outputstream to go with the filter!? Any
suggestions on how to do the buffer handling properly in such a custom stream?
The other option would perhaps be to turn off the commit flag above. The
source seems to toggle the flag on/off repeatadly for PrintWriters (huh?),
and always keeps it on for straight OutputStreams.
Q3: Why does it do this and where would be the right place to switch the
commit flag off permanently.
Thanks,
Wolfgang.
Re: Filters and Transfer-Encoding: chunked
Posted by Remy Maucherat <rm...@home.com>.
> > > I am facing a problem when useing a filter. The problem is that the
> >"Transfer-Encoding" header does not appear to be getting set. In this
case
> >the filter is doing some simple xsl transformations and passing on the
> >results to the response's output stream. Unfortunatly because the
content
> >is not being chunked by Tomcat the socket just sits there open.
> > >
> > > I'm not sure how tomcat knows to chunk the data. When working with an
> >unfiltered jsp page the data gets chunked as expected. Does the filter
need
> >to do anything to "chunk" the data?
> >
> >No, I don't think so. I was able to use filter to set different headers
> >including "Content-Encoding" to write out to the response's outputstream
> >just fine. Hope this help.
>
> Somwhat related problem here (TC4 stand-alone).
> I would like to use response chunked encoding with http.HttpConnector but
> so far fail to do so.
> Let me try and explain: The servlet in use does not set the response
> content-length. This apparently switches off chunked encoding. Browsing
> through the TC4 source it seems that a servlet can effectively switch off
> chunked encoding with a single outputStream.flush() early on, say flushing
> a couple of bytes (even though the servlet buffer size may be very large),
> which might be the cause of my problems.
>
> ResponseStream.flush() reads
>
> /**
> * Flush any buffered data for this output stream, which also
> causes the
> * response to be committed.
> */
> public void flush() throws IOException {
>
> if (closed)
> throw new
> IOException(sm.getString("responseStream.flush.closed"));
>
> if (commit)
> response.getResponse().flushBuffer();
>
> }
>
> Q1: Is this behaviour defined somewhere in the spec? Open to
> interpretation? Intuitively I'd think only response.flushBuffer() should
> really flush to the socket and ResponseStream.flush() above should copy
> into the buffer as long as it does not overflow. (response.flushBuffer()
is
> automatically called finally anyway).
>
> Now I can't fix the closed source third party servlet (big XSLT stuff). As
> a work-around I've been trying to write a filter, but so far no luck.
>
> Q2: Probably needs a custom Outputstream to go with the filter!? Any
> suggestions on how to do the buffer handling properly in such a custom
stream?
>
> The other option would perhaps be to turn off the commit flag above. The
> source seems to toggle the flag on/off repeatadly for PrintWriters (huh?),
> and always keeps it on for straight OutputStreams.
>
> Q3: Why does it do this and where would be the right place to switch the
> commit flag off permanently.
I don't understand what your servlet is doing. According to your description
(at least as I understand it), it does the same as the HelloWorld servlet
from the examples, which will produce chunked output.
Also, the current standalone HTTP connector won't really prevent you from
breaking the protocol from a servlet (by setting some special headers).
Remy
Re: Filters and Transfer-Encoding: chunked
Posted by Wolfgang Hoschek <wo...@cern.ch>.
>I don't understand what your servlet is doing. According to your description
>(at least as I understand it), it does the same as the HelloWorld servlet
>from the examples, which will produce chunked output.
>
>Also, the current standalone HTTP connector won't really prevent you from
>breaking the protocol from a servlet (by setting some special headers).
>
>Remy
Yes, since the servlet in question is closed source I can only guess what
it is doing.
Current status is that if I switch off chunking in the connector via
allowChunking="false", and have a preprocess filter that just sets a large
setBufferSize() I get very good performance with Java and C Clients.
Here are all 4 combinations (TC4 standalone):
(1) With allowChunking="false" AND buffersize > response --> 25 MB/s (C
and Java)
(2) With allowChunking="false" AND buffersize < response --> 2 MB/s (C and
Java)
(3) With allowChunking="true" AND buffersize < response --> 2 MB/s (C)
and 0.3 MB/s (Java)
(4) With allowChunking="true" AND buffersize > response --> 25 MB/s (C)
and 0.3 MB/s (Java)
Where a response is 10 MB large. The Java client lib is 'HTTPClient', the C
client is 'wget'.
Discussion:
(1) is fine, probably because TC seems to automatically set the ContentLength.
(2) is not fine, but probably there is nothing that can't be done about it.
(3) is not fine, and I'm wondering why. 'HTTPClient' has a performance
problem with chunked reads. But also the wget behaves poorly.
(4) Now wget is doing fine and HTTPClient does not improve at all.
The preliminary conclusion is that chunking doesn't work well and that only
(1) gives decent performance for C and Java, at least for this given
servlet. But clearly huge buffer sizes are not desirable if there are many
concurrent clients.
I tried having allowChunking="true" and patching flushBuffer() and/or
finishResponse() in ReponseBase, HTTPResponseBase and HTTPResponseImpl and
ended up with some improvement for the given request, although most likely
not correct in the general case.
I'll see whether I can come up with someting more useful.
BTW, Sorry for not being subscribed. I read this list a lot, but only post
occasionally, so http://marc.theaimsgroup.com/?l=tomcat-dev is a good way
for keeping up to date without drowning in local mail.
Wolfgang.