OK, I have studied Doug's patch and do not see how it can cause any potential
regression problems.  Therefore, I've committed the patch to the 3.2 code base.
Henri/Doug/others could you please to a fresh checkout of the "tomcat_32" branch
and try this out?  There is still time to revert the patch before 3.2 final if
it causes any unanticipated problems.

Craig McClanahan



"Clinton, Doug" wrote:

> Further to my earlier message, I've been investigating the problem with
> ajp13 and found the following.
>
> RequestDispatcher.forward() calls realResponse.finish() as its final action.
> However, ContextManager.service() also calls finish() on the response which
> results in two packets of type JK_AJP13_END_RESPONSE being written back to
> the mod_jk stream. This means that the next time mod_jk makes a request the
> first thing it will get back from tomcat is the second END_RESPONSE packet.
> The real response to the request gets left, buffered in the socket stream.
>
> Hence, every time mod_jk makes a request which must be passed through
> forward, the whole reponse stream gets one more step behind.
>
> My first fix to the problem was to remove the call to finish() from
> RequestDispatcher.forward(). However, I am unsure as to what possible side
> effects this might have, hence I have produced the patch below to
> Ajp13ConnectorResponse.java which prevents multiple calls to finish() from
> producing more than one END_RESPONSE packet. The flag to check for this is
> reset in the recycle() method so that the Ajp13ConnectorResponse can be
> reused.
>
> Since this is the first time I've delved into the tomcat code I'm concerned
> that I may have missed something critical so if anyone who has more
> experience of this area of the code can look over the patch I'd appreciate
> it.  In particular I'm not sure whether the call to super.finish() should be
> made regardless of whether it has been called already.
>
> thanks,
> Doug Clinton
> [EMAIL PROTECTED]
>
> diff -p Ajp13ConnectorResponse.java Ajp13ConnectorResponse.java.orig
> *** Ajp13ConnectorResponse.java Fri Nov 24 13:53:37 2000
> --- Ajp13ConnectorResponse.java.orig    Tue Nov 21 03:24:06 2000
> *************** public class Ajp13ConnectorResponse exte
> *** 97,104 ****
>
>       MsgConnector con;
>
> -     private boolean finished = false;
> -
>       public Ajp13ConnectorResponse()
>       {
>       }
> --- 97,102 ----
> *************** public class Ajp13ConnectorResponse exte
> *** 150,165 ****
>
>       public void finish() throws IOException
>       {
> !         if (!finished) {
> !             super.finish();
> !             finished = true;
> !             MsgBuffer msg = con.getMsgBuffer();
> !             msg.reset();
> !             msg.appendByte(JK_AJP13_END_RESPONSE);
> !             msg.appendByte((byte)1);
> !             msg.end();
> !             con.send(msg);
> !         }
>       }
>
>       protected int headerNameToSc(String name)
> --- 148,160 ----
>
>       public void finish() throws IOException
>       {
> !         super.finish();
> !         MsgBuffer msg = con.getMsgBuffer();
> !         msg.reset();
> !         msg.appendByte(JK_AJP13_END_RESPONSE);
> !         msg.appendByte((byte)1);
> !         msg.end();
> !         con.send(msg);
>       }
>
>       protected int headerNameToSc(String name)
> *************** public class Ajp13ConnectorResponse exte
> *** 215,221 ****
>       public void recycle()
>       {
>           super.recycle();
> -         finished = false;
>       }
>
>       public void setConnector(MsgConnector con)
> --- 210,215 ----

Reply via email to