> > THIS DOES NOT FIX the problem with the output when tomcat already sent
> > data to the client (see my mail date Thu, 12 Feb 2004 23:33:34 +0100),
> >
> > My two cents: when the tomcat fails after data has been sent to the
> > client, assume that the request is complete, i.e. return JK_TRUE
> > (otherwise apache will add some error messages to the reply).
>
> Ok, if you have fix for jk AND jk2, thanks to provide them quickly so we
> could include in in 2.0.4 and 1.2.6 release.

This is not as easy as I thought: I have extended ajp_get_reply() and
ajp_process_callback() to keep track if the headers have already been
sent.

The following considerations have been made:

   * after data has been sent to the client don't try to recover
     from a tomcat has failure

   * if I return JK_FALSE with recoverable = JK_FALSE apache will
     append its standard error page. This might look quite ugly, but
     this way we get proper access.log entries. This might also trigger
     some error handling in apache (closing the socket even if client
     tried keepalive and tomcat sent a content length?)

   * it's up to you to decide if mod_jk should try to recover after
     when no headers have been sent (see tag DISCUSSION in code)

The best thing to do after a tomcat failure (after data has been already
sent to the client) would be to mark it as not recoverable, write a proper
log entry in access.log and to force apache to close this connection
immediately without sending any other data. This should handle any
problems arising from chunked responses and/or content-length headers. But
I don't know how to implement that.

The included patch is only for jk, not jk2.

Alex.

-- 
Alexander Schwartz ([EMAIL PROTECTED])
http://www.ahus1.de

? jtc.20040208.zip
? jtc.20040215.zip
? jk/native/autom4te.cache
? jk/native/out
? jk/native/apache-1.3/mod_jk.so.0.0.0
? jk/native/jni/Makefile
? jk/native/scripts/build/unix/config.guess
? jk/native/scripts/build/unix/config.sub
? jk/native/scripts/build/unix/install-sh
? jk/native/scripts/build/unix/ltmain.sh
? jk/native/scripts/build/unix/missing
? jk/native/scripts/build/unix/mkinstalldirs
Index: jk/native/common/jk_ajp_common.c
===================================================================
RCS file: /home/cvspublic/jakarta-tomcat-connectors/jk/native/common/jk_ajp_common.c,v
retrieving revision 1.47
diff -u -b -r1.47 jk_ajp_common.c
--- jk/native/common/jk_ajp_common.c    11 Feb 2004 09:49:49 -0000      1.47
+++ jk/native/common/jk_ajp_common.c    16 Feb 2004 11:49:35 -0000
@@ -1174,7 +1174,8 @@
                                   (const char * const *)res.header_values,
                                   res.num_headers);
             }
-        break;
+        // break;
+       return JK_AJP13_SEND_HEADERS;
 
         case JK_AJP13_SEND_BODY_CHUNK:
             {
@@ -1261,6 +1262,7 @@
                          ajp_endpoint_t *p,
                          ajp_operation_t *op)
 {
+    int headeratclient = JK_FALSE;
     /* Start read all reply message */
     while(1) {
         int rc = 0;
@@ -1279,11 +1281,40 @@
                }
                
         if(!ajp_connection_tcp_get_message(p, op->reply, l)) {
+            /* we just can't recover, unset recover flag */
+           if(JK_FALSE == headeratclient) {
             jk_log(l, JK_LOG_ERROR,
                    "Error reading reply from tomcat. "
-                   "Tomcat is down or network problems.\n");
-            /* we just can't recover, unset recover flag */
+                   "Tomcat is down or network problems. "
+                  "No response has been sent to the client (yet)\n");
+               /* communication with tomcat has been interrupted BEFORE 
+                * headers have been sent to the client. */
+               /* DISCUSSION: As we suppose that tomcat has already started
+                * to process the query we think it's unrecoverable (and we
+                * should not retry or switch to another tomcat in the 
+                * cluster). */
+               op->recoverable = JK_FALSE;
+               /* we want to display the webservers error page, therefore
+                * we return JK_FALSE */
             return JK_FALSE;
+           } else {
+                jk_log(l, JK_LOG_ERROR,
+                   "Error reading reply from tomcat. "
+                   "Tomcat is down or network problems. "
+                  "Part of the response has already been sent to the client\n");
+               /* communication with tomcat has been interrupted AFTER 
+                * headers have been sent to the client. */
+               /* headers (and maybe parts of the body) have already been
+                * sent, therefore the response is "complete" in a sense
+                * that nobody should append any data, especially no 500 error 
+                * page of the webserver! */
+               /* BUT if you retrun JK_TRUE you have a 200 (OK) code in your
+                * in your apache access.log instead of a 500 (Error). 
+                * Therefore return FALSE/FALSE */
+                // return JK_TRUE;
+               op->recoverable = JK_FALSE;
+               return JK_FALSE;
+           }
         }
 
         rc = ajp_process_callback(op->reply, op->post, p, s, l);
@@ -1291,6 +1322,8 @@
         /* no more data to be sent, fine we have finish here */
         if(JK_AJP13_END_RESPONSE == rc) {
             return JK_TRUE;
+       } else if(JK_AJP13_SEND_HEADERS == rc) {
+           headeratclient = JK_TRUE;
         } else if(JK_AJP13_HAS_RESPONSE == rc) {
             /* 
              * in upload-mode there is no second chance since
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to