You are viewing a plain text version of this content. The canonical link for it is here.
Posted to apache-bugdb@apache.org by Hans Bergsten <ha...@gefionsoftware.com> on 1998/07/12 08:16:37 UTC

other/2591: Setting headers from SSI Servlet doesn't work

>Number:         2591
>Category:       other
>Synopsis:       Setting headers from SSI Servlet doesn't work
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    apache
>State:          open
>Class:          sw-bug
>Submitter-Id:   apache
>Arrival-Date:   Sat Jul 11 23:20:00 PDT 1998
>Last-Modified:
>Originator:     hans@gefionsoftware.com
>Organization:
apache
>Release:        JServ 0.9.11/Apache 1.3.0
>Environment:
Any OS, problem in Java code
>Description:
Setting headers from an SSI Servlet doesn't work since all headers
are sent to the client on the first write() call in JServOutputStream,
and for SSI Servlets JServSSI has already written at least
"<HTML><BODY>" to the stream.
>How-To-Repeat:
Try setting any header, e.g. with addCookie(), from a Servlet called
through a <SERVLET> tag in a jhtml file.
>Fix:
A simple solution is to buffer the output stream and only
send it to the client on flush() and close(), with the headers
the first time. This way headers can be set upto the first
flush() or close(). The following changes work:

1) Add
     private ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
   to JServOutputStream.
2) Modify write() and write(int) and write(byte[], int, int) so
   they write to os instead of out.
3) Rewrite flush() as
     public void flush() throws IOException {
       sendHttpHeaders();
       byte[] outbuff = os.toByteArray();
       os.reset();
       out.write(outbuff, 0, outbuff.length);
       out.flush();
     }
4) Rewrite close() as
     public void close() throws IOException {
       flush();
       out.close();
     }


An even better solution is to not really close the stream in 
close() since that causes problems in case a jhtml page contains 
multiple SSI Servlets and one of them calls close(). If close()
just calls flush() and another package scope function called
reallyClose() closes the stream, it solves the problem.
reallyClose() must then be called when the service() call returns
in JServ.
>Audit-Trail:
>Unformatted:
[In order for any reply to be added to the PR database, ]
[you need to include <ap...@Apache.Org> in the Cc line ]
[and leave the subject line UNCHANGED.  This is not done]
[automatically because of the potential for mail loops. ]