You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by mt...@apache.org on 2002/06/25 09:08:03 UTC
cvs commit: jakarta-tomcat-connectors/jk/native/common jk_ajp_common.c
mturk 2002/06/25 00:08:03
Modified: jk/native/common jk_ajp_common.c
Log:
Introduced socket and cache timeout.
By Jan Singer, Henri Gomez and Mladen Turk.
Revision Changes Path
1.26 +376 -334 jakarta-tomcat-connectors/jk/native/common/jk_ajp_common.c
Index: jk_ajp_common.c
===================================================================
RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native/common/jk_ajp_common.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -r1.25 -r1.26
--- jk_ajp_common.c 10 May 2002 23:58:40 -0000 1.25
+++ jk_ajp_common.c 25 Jun 2002 07:08:03 -0000 1.26
@@ -115,23 +115,23 @@
} else if(0 == strcmp(method, "TRACE")) {
*sc = SC_M_TRACE;
} else if(0 == strcmp(method, "PROPFIND")) {
- *sc = SC_M_PROPFIND;
+ *sc = SC_M_PROPFIND;
} else if(0 == strcmp(method, "PROPPATCH")) {
- *sc = SC_M_PROPPATCH;
+ *sc = SC_M_PROPPATCH;
} else if(0 == strcmp(method, "MKCOL")) {
- *sc = SC_M_MKCOL;
+ *sc = SC_M_MKCOL;
} else if(0 == strcmp(method, "COPY")) {
- *sc = SC_M_COPY;
+ *sc = SC_M_COPY;
} else if(0 == strcmp(method, "MOVE")) {
- *sc = SC_M_MOVE;
+ *sc = SC_M_MOVE;
} else if(0 == strcmp(method, "LOCK")) {
- *sc = SC_M_LOCK;
+ *sc = SC_M_LOCK;
} else if(0 == strcmp(method, "UNLOCK")) {
- *sc = SC_M_UNLOCK;
+ *sc = SC_M_UNLOCK;
} else if(0 == strcmp(method, "ACL")) {
- *sc = SC_M_ACL;
+ *sc = SC_M_ACL;
} else if(0 == strcmp(method, "REPORT")) {
- *sc = SC_M_REPORT;
+ *sc = SC_M_REPORT;
} else if(0 == strcmp(method, "VERSION-CONTROL")) {
*sc = SC_M_VERSION_CONTROL;
} else if(0 == strcmp(method, "CHECKIN")) {
@@ -263,7 +263,7 @@
?ssl_cert (byte)(string)
?ssl_cipher (byte)(string)
?ssl_session (byte)(string)
- ?ssl_key_size (byte)(int) via JkOptions +ForwardKeySize
+ ?ssl_key_size (byte)(int) via JkOptions +ForwardKeySize
request_terminator (byte)
?body content_length*(var binary)
@@ -442,10 +442,10 @@
static int ajp_unmarshal_response(jk_msg_buf_t *msg,
jk_res_data_t *d,
- ajp_endpoint_t *ae,
+ ajp_endpoint_t *ae,
jk_logger_t *l)
{
- jk_pool_t * p = &ae->pool;
+ jk_pool_t * p = &ae->pool;
d->status = jk_b_get_int(msg);
@@ -533,16 +533,16 @@
void ajp_close_endpoint(ajp_endpoint_t *ae,
jk_logger_t *l)
{
- jk_log(l, JK_LOG_DEBUG, "In jk_endpoint_t::ajp_close_endpoint\n");
+ jk_log(l, JK_LOG_DEBUG, "In jk_endpoint_t::ajp_close_endpoint\n");
ajp_reset_endpoint(ae);
jk_close_pool(&(ae->pool));
if (ae->sd > 0) {
jk_close_socket(ae->sd);
- jk_log(l, JK_LOG_DEBUG, "In jk_endpoint_t::ajp_close_endpoint, closed sd = %d\n", ae->sd);
- ae->sd = -1; /* just to avoid twice close */
- }
+ jk_log(l, JK_LOG_DEBUG, "In jk_endpoint_t::ajp_close_endpoint, closed sd = %d\n", ae->sd);
+ ae->sd = -1; /* just to avoid twice close */
+ }
free(ae);
}
@@ -584,20 +584,22 @@
unsigned attempt;
for(attempt = 0 ; attempt < ae->worker->connect_retry_attempts ; attempt++) {
- ae->sd = jk_open_socket(&ae->worker->worker_inet_addr, JK_TRUE, l);
+ ae->sd = jk_open_socket(&ae->worker->worker_inet_addr, JK_TRUE, ae->worker->keepalive, l);
if(ae->sd >= 0) {
jk_log(l, JK_LOG_DEBUG, "In jk_endpoint_t::ajp_connect_to_endpoint, connected sd = %d\n", ae->sd);
- /* Check if we must execute a logon after the physical connect */
- if (ae->worker->logon != NULL)
- return (ae->worker->logon(ae, l));
+ /* set last_access */
+ ae->last_access = time(NULL);
+ /* Check if we must execute a logon after the physical connect */
+ if (ae->worker->logon != NULL)
+ return (ae->worker->logon(ae, l));
- return JK_TRUE;
+ return JK_TRUE;
}
}
jk_log(l, JK_LOG_ERROR, "In jk_endpoint_t::ajp_connect_to_endpoint, failed errno = %d\n", errno);
- return JK_FALSE;
+ return JK_FALSE;
}
/*
@@ -608,18 +610,18 @@
jk_msg_buf_t *msg,
jk_logger_t *l)
{
- if (ae->proto == AJP13_PROTO) {
- jk_b_end(msg, AJP13_WS_HEADER);
- jk_dump_buff(l, JK_LOG_DEBUG, "sending to ajp13", msg);
- }
- else if (ae->proto == AJP14_PROTO) {
- jk_b_end(msg, AJP14_WS_HEADER);
- jk_dump_buff(l, JK_LOG_DEBUG, "sending to ajp14", msg);
- }
- else {
- jk_log(l, JK_LOG_ERROR, "In jk_endpoint_t::ajp_connection_tcp_send_message, unknown protocol %d, supported are AJP13/AJP14\n", ae->proto);
- return JK_FALSE;
- }
+ if (ae->proto == AJP13_PROTO) {
+ jk_b_end(msg, AJP13_WS_HEADER);
+ jk_dump_buff(l, JK_LOG_DEBUG, "sending to ajp13", msg);
+ }
+ else if (ae->proto == AJP14_PROTO) {
+ jk_b_end(msg, AJP14_WS_HEADER);
+ jk_dump_buff(l, JK_LOG_DEBUG, "sending to ajp14", msg);
+ }
+ else {
+ jk_log(l, JK_LOG_ERROR, "In jk_endpoint_t::ajp_connection_tcp_send_message, unknown protocol %d, supported are AJP13/AJP14\n", ae->proto);
+ return JK_FALSE;
+ }
if(0 > jk_tcp_socket_sendfull(ae->sd, jk_b_get_buff(msg), jk_b_get_len(msg))) {
return JK_FALSE;
@@ -639,12 +641,12 @@
unsigned char head[AJP_HEADER_LEN];
int rc;
int msglen;
- unsigned int header;
+ unsigned int header;
- if ((ae->proto != AJP13_PROTO) && (ae->proto != AJP14_PROTO)) {
- jk_log(l, JK_LOG_ERROR, "ajp_connection_tcp_get_message: Can't handle unknown protocol %d\n", ae->proto);
- return JK_FALSE;
- }
+ if ((ae->proto != AJP13_PROTO) && (ae->proto != AJP14_PROTO)) {
+ jk_log(l, JK_LOG_ERROR, "ajp_connection_tcp_get_message: Can't handle unknown protocol %d\n", ae->proto);
+ return JK_FALSE;
+ }
rc = jk_tcp_socket_recvfull(ae->sd, head, AJP_HEADER_LEN);
@@ -653,30 +655,30 @@
return JK_FALSE;
}
- header = ((unsigned int)head[0] << 8) | head[1];
+ header = ((unsigned int)head[0] << 8) | head[1];
- if (ae->proto == AJP13_PROTO) {
- if (header != AJP13_SW_HEADER) {
+ if (ae->proto == AJP13_PROTO) {
+ if (header != AJP13_SW_HEADER) {
+
+ if (header == AJP14_SW_HEADER)
+ jk_log(l, JK_LOG_ERROR, "ajp_connection_tcp_get_message: Error - received AJP14 reply on an AJP13 connection\n");
+ else
+ jk_log(l, JK_LOG_ERROR, "ajp_connection_tcp_get_message: Error - Wrong message format 0x%04x\n", header);
+
+ return JK_FALSE;
+ }
+ }
+ else if (ae->proto == AJP14_PROTO) {
+ if (header != AJP14_SW_HEADER) {
- if (header == AJP14_SW_HEADER)
- jk_log(l, JK_LOG_ERROR, "ajp_connection_tcp_get_message: Error - received AJP14 reply on an AJP13 connection\n");
- else
- jk_log(l, JK_LOG_ERROR, "ajp_connection_tcp_get_message: Error - Wrong message format 0x%04x\n", header);
-
- return JK_FALSE;
- }
- }
- else if (ae->proto == AJP14_PROTO) {
- if (header != AJP14_SW_HEADER) {
-
- if (header == AJP13_SW_HEADER)
- jk_log(l, JK_LOG_ERROR, "ajp_connection_tcp_get_message: Error - received AJP13 reply on an AJP14 connection\n");
- else
- jk_log(l, JK_LOG_ERROR, "ajp_connection_tcp_get_message: Error - Wrong message format 0x%04x\n", header);
-
- return JK_FALSE;
- }
- }
+ if (header == AJP13_SW_HEADER)
+ jk_log(l, JK_LOG_ERROR, "ajp_connection_tcp_get_message: Error - received AJP13 reply on an AJP14 connection\n");
+ else
+ jk_log(l, JK_LOG_ERROR, "ajp_connection_tcp_get_message: Error - Wrong message format 0x%04x\n", header);
+
+ return JK_FALSE;
+ }
+ }
msglen = ((head[2]&0xff)<<8);
msglen += (head[3] & 0xFF);
@@ -695,11 +697,11 @@
return JK_FALSE;
}
- if (ae->proto == AJP13_PROTO)
- jk_dump_buff(l, JK_LOG_DEBUG, "received from ajp13", msg);
- else if (ae->proto == AJP14_PROTO)
- jk_dump_buff(l, JK_LOG_DEBUG, "received from ajp14", msg);
-
+ if (ae->proto == AJP13_PROTO)
+ jk_dump_buff(l, JK_LOG_DEBUG, "received from ajp13", msg);
+ else if (ae->proto == AJP14_PROTO)
+ jk_dump_buff(l, JK_LOG_DEBUG, "received from ajp14", msg);
+
return JK_TRUE;
}
@@ -718,7 +720,7 @@
unsigned padded_len = len;
if (s->is_chunked && s->no_more_chunks) {
- return 0;
+ return 0;
}
if (s->is_chunked) {
/* Corner case: buf must be large enough to hold next
@@ -737,9 +739,9 @@
}
if(0 == this_time) {
- if (s->is_chunked) {
- s->no_more_chunks = 1; /* read no more */
- }
+ if (s->is_chunked) {
+ s->no_more_chunks = 1; /* read no more */
+ }
break;
}
rdlen += this_time;
@@ -769,7 +771,7 @@
/* Pick the max size since we don't know the content_length */
if (r->is_chunked && len == 0) {
- len = AJP13_MAX_SEND_BODY_SZ;
+ len = AJP13_MAX_SEND_BODY_SZ;
}
if ((len = ajp_read_fully_from_server(r, read_buf, len)) < 0) {
@@ -778,17 +780,17 @@
}
if (!r->is_chunked) {
- ae->left_bytes_to_send -= len;
+ ae->left_bytes_to_send -= len;
}
if (len > 0) {
- /* Recipient recognizes empty packet as end of stream, not
- an empty body packet */
+ /* Recipient recognizes empty packet as end of stream, not
+ an empty body packet */
if(0 != jk_b_append_int(msg, (unsigned short)len)) {
jk_log(l, JK_LOG_ERROR,
"read_into_msg_buff: Error - jk_b_append_int failed\n");
return -1;
- }
+ }
}
jk_b_set_len(msg, jk_b_get_len(msg) + len);
@@ -809,89 +811,89 @@
* repmsg is the reply msg buffer which could be scratched
*/
static int ajp_send_request(jk_endpoint_t *e,
- jk_ws_service_t *s,
- jk_logger_t *l,
- ajp_endpoint_t *ae,
- ajp_operation_t *op)
+ jk_ws_service_t *s,
+ jk_logger_t *l,
+ ajp_endpoint_t *ae,
+ ajp_operation_t *op)
{
- /* Up to now, we can recover */
- op->recoverable = JK_TRUE;
+ /* Up to now, we can recover */
+ op->recoverable = JK_TRUE;
+
+ /*
+ * First try to reuse open connections...
+ */
+ while ((ae->sd > 0) && ! ajp_connection_tcp_send_message(ae, op->request, l)) {
+ jk_log(l, JK_LOG_ERROR, "Error sending request try another pooled connection\n");
+ jk_close_socket(ae->sd);
+ ae->sd = -1;
+ ajp_reuse_connection(ae, l);
+ }
+
+ /*
+ * If we failed to reuse a connection, try to reconnect.
+ */
+ if (ae->sd < 0) {
+ if (ajp_connect_to_endpoint(ae, l) == JK_TRUE) {
+ /*
+ * After we are connected, each error that we are going to
+ * have is probably unrecoverable
+ */
+ if (!ajp_connection_tcp_send_message(ae, op->request, l)) {
+ jk_log(l, JK_LOG_ERROR, "Error sending request on a fresh connection\n");
+ return JK_FALSE;
+ }
+ } else {
+ jk_log(l, JK_LOG_ERROR, "Error connecting to the Tomcat process.\n");
+ return JK_FALSE;
+ }
+ }
- /*
- * First try to reuse open connections...
- */
- while ((ae->sd > 0) && ! ajp_connection_tcp_send_message(ae, op->request, l)) {
- jk_log(l, JK_LOG_ERROR, "Error sending request try another pooled connection\n");
- jk_close_socket(ae->sd);
- ae->sd = -1;
- ajp_reuse_connection(ae, l);
- }
-
- /*
- * If we failed to reuse a connection, try to reconnect.
- */
- if (ae->sd < 0) {
- if (ajp_connect_to_endpoint(ae, l) == JK_TRUE) {
- /*
- * After we are connected, each error that we are going to
- * have is probably unrecoverable
- */
- if (!ajp_connection_tcp_send_message(ae, op->request, l)) {
- jk_log(l, JK_LOG_ERROR, "Error sending request on a fresh connection\n");
- return JK_FALSE;
- }
- } else {
- jk_log(l, JK_LOG_ERROR, "Error connecting to the Tomcat process.\n");
- return JK_FALSE;
- }
- }
-
- /*
- * From now on an error means that we have an internal server error
- * or Tomcat crashed. In any case we cannot recover this.
- */
-
- jk_log(l, JK_LOG_DEBUG, "ajp_send_request 2: request body to send %d - request body to resend %d\n",
- ae->left_bytes_to_send, jk_b_get_len(op->reply) - AJP_HEADER_LEN);
-
- /*
- * POST recovery job is done here.
- * It's not very fine to have posted data in reply but that's the only easy
- * way to do that for now. Sharing the reply is really a bad solution but
- * it will works for POST DATA less than 8k.
- * We send here the first part of data which was sent previously to the
- * remote Tomcat
- */
- if (jk_b_get_len(op->post) > AJP_HEADER_LEN) {
- if(!ajp_connection_tcp_send_message(ae, op->post, l)) {
- jk_log(l, JK_LOG_ERROR, "Error resending request body\n");
- return JK_FALSE;
- }
- }
- else
- {
- /* We never sent any POST data and we check it we have to send at
- * least of block of data (max 8k). These data will be kept in reply
- * for resend if the remote Tomcat is down, a fact we will learn only
- * doing a read (not yet)
- */
- if (s->is_chunked || ae->left_bytes_to_send > 0) {
- int len = ae->left_bytes_to_send;
- if (len > AJP13_MAX_SEND_BODY_SZ)
- len = AJP13_MAX_SEND_BODY_SZ;
- if ((len = ajp_read_into_msg_buff(ae, s, op->post, len, l)) < 0) {
- /* the browser stop sending data, no need to recover */
- op->recoverable = JK_FALSE;
- return JK_FALSE;
- }
- s->content_read = len;
- if (!ajp_connection_tcp_send_message(ae, op->post, l)) {
- jk_log(l, JK_LOG_ERROR, "Error sending request body\n");
- return JK_FALSE;
- }
- }
- }
- return (JK_TRUE);
+ /*
+ * From now on an error means that we have an internal server error
+ * or Tomcat crashed. In any case we cannot recover this.
+ */
+
+ jk_log(l, JK_LOG_DEBUG, "ajp_send_request 2: request body to send %d - request body to resend %d\n",
+ ae->left_bytes_to_send, jk_b_get_len(op->reply) - AJP_HEADER_LEN);
+
+ /*
+ * POST recovery job is done here.
+ * It's not very fine to have posted data in reply but that's the only easy
+ * way to do that for now. Sharing the reply is really a bad solution but
+ * it will works for POST DATA less than 8k.
+ * We send here the first part of data which was sent previously to the
+ * remote Tomcat
+ */
+ if (jk_b_get_len(op->post) > AJP_HEADER_LEN) {
+ if(!ajp_connection_tcp_send_message(ae, op->post, l)) {
+ jk_log(l, JK_LOG_ERROR, "Error resending request body\n");
+ return JK_FALSE;
+ }
+ }
+ else
+ {
+ /* We never sent any POST data and we check it we have to send at
+ * least of block of data (max 8k). These data will be kept in reply
+ * for resend if the remote Tomcat is down, a fact we will learn only
+ * doing a read (not yet)
+ */
+ if (s->is_chunked || ae->left_bytes_to_send > 0) {
+ int len = ae->left_bytes_to_send;
+ if (len > AJP13_MAX_SEND_BODY_SZ)
+ len = AJP13_MAX_SEND_BODY_SZ;
+ if ((len = ajp_read_into_msg_buff(ae, s, op->post, len, l)) < 0) {
+ /* the browser stop sending data, no need to recover */
+ op->recoverable = JK_FALSE;
+ return JK_FALSE;
+ }
+ s->content_read = len;
+ if (!ajp_connection_tcp_send_message(ae, op->post, l)) {
+ jk_log(l, JK_LOG_ERROR, "Error sending request body\n");
+ return JK_FALSE;
+ }
+ }
+ }
+ return (JK_TRUE);
}
/*
@@ -924,21 +926,21 @@
return JK_CLIENT_ERROR;
}
}
- break;
+ break;
case JK_AJP13_SEND_BODY_CHUNK:
{
- unsigned len = (unsigned)jk_b_get_int(msg);
+ unsigned len = (unsigned)jk_b_get_int(msg);
if(!r->write(r, jk_b_get_buff(msg) + jk_b_get_pos(msg), len)) {
jk_log(l, JK_LOG_ERROR, "Error ajp_process_callback - write failed\n");
return JK_CLIENT_ERROR;
}
}
- break;
+ break;
case JK_AJP13_GET_BODY_CHUNK:
{
- int len = (int)jk_b_get_int(msg);
+ int len = (int)jk_b_get_int(msg);
if(len > AJP13_MAX_SEND_BODY_SZ) {
len = AJP13_MAX_SEND_BODY_SZ;
@@ -946,20 +948,20 @@
if(len > ae->left_bytes_to_send) {
len = ae->left_bytes_to_send;
}
- if(len < 0) {
- len = 0;
- }
-
- /* the right place to add file storage for upload */
- if ((len = ajp_read_into_msg_buff(ae, r, pmsg, len, l)) >= 0) {
- r->content_read += len;
- return JK_AJP13_HAS_RESPONSE;
- }
+ if(len < 0) {
+ len = 0;
+ }
+
+ /* the right place to add file storage for upload */
+ if ((len = ajp_read_into_msg_buff(ae, r, pmsg, len, l)) >= 0) {
+ r->content_read += len;
+ return JK_AJP13_HAS_RESPONSE;
+ }
- jk_log(l, JK_LOG_ERROR, "Error ajp_process_callback - ajp_read_into_msg_buff failed\n");
- return JK_INTERNAL_ERROR;
+ jk_log(l, JK_LOG_ERROR, "Error ajp_process_callback - ajp_read_into_msg_buff failed\n");
+ return JK_INTERNAL_ERROR;
}
- break;
+ break;
case JK_AJP13_END_RESPONSE:
{
@@ -976,11 +978,11 @@
ae->reuse = JK_TRUE;
}
return JK_AJP13_END_RESPONSE;
- break;
+ break;
default:
- jk_log(l, JK_LOG_ERROR, "Error ajp_process_callback - Invalid code: %d\n", code);
- return JK_AJP13_ERROR;
+ jk_log(l, JK_LOG_ERROR, "Error ajp_process_callback - Invalid code: %d\n", code);
+ return JK_AJP13_ERROR;
}
return JK_AJP13_NO_RESPONSE;
@@ -1002,40 +1004,40 @@
static int ajp_get_reply(jk_endpoint_t *e,
jk_ws_service_t *s,
jk_logger_t *l,
- ajp_endpoint_t *p,
- ajp_operation_t *op)
+ ajp_endpoint_t *p,
+ ajp_operation_t *op)
{
- /* Start read all reply message */
- while(1) {
- int rc = 0;
-
- if(!ajp_connection_tcp_get_message(p, op->reply, l)) {
- jk_log(l, JK_LOG_ERROR, "Error reading reply\n");
- /* we just can't recover, unset recover flag */
- return JK_FALSE;
- }
-
- rc = ajp_process_callback(op->reply, op->post, p, s, l);
-
- /* no more data to be sent, fine we have finish here */
- if(JK_AJP13_END_RESPONSE == rc)
- return JK_TRUE;
- else if(JK_AJP13_HAS_RESPONSE == rc) {
- /*
- * in upload-mode there is no second chance since
- * we may have allready send part of uploaded data
- * to Tomcat.
- * In this case if Tomcat connection is broken we must
- * abort request and indicate error.
- * A possible work-around could be to store the uploaded
- * data to file and replay for it
- */
- op->recoverable = JK_FALSE;
- rc = ajp_connection_tcp_send_message(p, op->post, l);
- if (rc < 0) {
- jk_log(l, JK_LOG_ERROR, "Error sending request data %d\n", rc);
- return JK_FALSE;
- }
+ /* Start read all reply message */
+ while(1) {
+ int rc = 0;
+
+ if(!ajp_connection_tcp_get_message(p, op->reply, l)) {
+ jk_log(l, JK_LOG_ERROR, "Error reading reply\n");
+ /* we just can't recover, unset recover flag */
+ return JK_FALSE;
+ }
+
+ rc = ajp_process_callback(op->reply, op->post, p, s, l);
+
+ /* no more data to be sent, fine we have finish here */
+ if(JK_AJP13_END_RESPONSE == rc)
+ return JK_TRUE;
+ else if(JK_AJP13_HAS_RESPONSE == rc) {
+ /*
+ * in upload-mode there is no second chance since
+ * we may have allready send part of uploaded data
+ * to Tomcat.
+ * In this case if Tomcat connection is broken we must
+ * abort request and indicate error.
+ * A possible work-around could be to store the uploaded
+ * data to file and replay for it
+ */
+ op->recoverable = JK_FALSE;
+ rc = ajp_connection_tcp_send_message(p, op->post, l);
+ if (rc < 0) {
+ jk_log(l, JK_LOG_ERROR, "Error sending request data %d\n", rc);
+ return JK_FALSE;
+ }
} else if(JK_FATAL_ERROR == rc) {
/*
* we won't be able to gracefully recover from this so
@@ -1052,13 +1054,13 @@
* un-recoverable error. We just won't log it as such.
*/
return JK_TRUE;
- } else if(rc < 0) {
- return (JK_FALSE); /* XXX error */
- }
- }
+ } else if(rc < 0) {
+ return (JK_FALSE); /* XXX error */
+ }
+ }
}
-#define JK_RETRIES 3
+#define JK_RETRIES 3
/*
* service is now splitted in ajp_send_request and ajp_get_reply
@@ -1072,95 +1074,95 @@
jk_logger_t *l,
int *is_recoverable_error)
{
- int i;
- ajp_operation_t oper;
- ajp_operation_t *op = &oper;
-
- jk_log(l, JK_LOG_DEBUG, "Into jk_endpoint_t::service\n");
-
- if(e && e->endpoint_private && s && is_recoverable_error) {
- ajp_endpoint_t *p = e->endpoint_private;
- op->request = jk_b_new(&(p->pool));
- jk_b_set_buffer_size(op->request, DEF_BUFFER_SZ);
- jk_b_reset(op->request);
+ int i;
+ ajp_operation_t oper;
+ ajp_operation_t *op = &oper;
+
+ jk_log(l, JK_LOG_DEBUG, "Into jk_endpoint_t::service\n");
+
+ if(e && e->endpoint_private && s && is_recoverable_error) {
+ ajp_endpoint_t *p = e->endpoint_private;
+ op->request = jk_b_new(&(p->pool));
+ jk_b_set_buffer_size(op->request, DEF_BUFFER_SZ);
+ jk_b_reset(op->request);
- op->reply = jk_b_new(&(p->pool));
- jk_b_set_buffer_size(op->reply, DEF_BUFFER_SZ);
- jk_b_reset(op->reply);
-
- op->post = jk_b_new(&(p->pool));
- jk_b_set_buffer_size(op->post, DEF_BUFFER_SZ);
- jk_b_reset(op->post);
-
- op->recoverable = JK_TRUE;
- op->uploadfd = -1; /* not yet used, later ;) */
-
- p->left_bytes_to_send = s->content_length;
- p->reuse = JK_FALSE;
- *is_recoverable_error = JK_TRUE;
+ op->reply = jk_b_new(&(p->pool));
+ jk_b_set_buffer_size(op->reply, DEF_BUFFER_SZ);
+ jk_b_reset(op->reply);
+
+ op->post = jk_b_new(&(p->pool));
+ jk_b_set_buffer_size(op->post, DEF_BUFFER_SZ);
+ jk_b_reset(op->post);
+
+ op->recoverable = JK_TRUE;
+ op->uploadfd = -1; /* not yet used, later ;) */
+
+ p->left_bytes_to_send = s->content_length;
+ p->reuse = JK_FALSE;
+ *is_recoverable_error = JK_TRUE;
s->secret = p->worker->secret;
- /*
- * We get here initial request (in reqmsg)
- */
- if (!ajp_marshal_into_msgb(op->request, s, l, p)) {
- *is_recoverable_error = JK_FALSE;
- return JK_FALSE;
- }
-
- /*
- * JK_RETRIES could be replaced by the number of workers in
- * a load-balancing configuration
- */
- for (i = 0; i < JK_RETRIES; i++)
- {
- /*
- * We're using reqmsg which hold initial request
- * if Tomcat is stopped or restarted, we will pass reqmsg
- * to next valid tomcat.
- */
- if (ajp_send_request(e, s, l, p, op)) {
-
- /* If we have the no recoverable error, it's probably because the sender (browser)
- * stop sending data before the end (certainly in a big post)
- */
- if (! op->recoverable) {
- *is_recoverable_error = JK_FALSE;
- jk_log(l, JK_LOG_ERROR, "In jk_endpoint_t::service, ajp_send_request failed without recovery in send loop %d\n", i);
- return JK_FALSE;
- }
-
- /* Up to there we can recover */
- *is_recoverable_error = JK_TRUE;
- op->recoverable = JK_TRUE;
-
- if (ajp_get_reply(e, s, l, p, op))
- return (JK_TRUE);
-
- /* if we can't get reply, check if no recover flag was set
- * if is_recoverable_error is cleared, we have started received
- * upload data and we must consider that operation is no more recoverable
- */
- if (! op->recoverable) {
- *is_recoverable_error = JK_FALSE;
- jk_log(l, JK_LOG_ERROR, "In jk_endpoint_t::service, ajp_get_reply failed without recovery in send loop %d\n", i);
- return JK_FALSE;
- }
-
- jk_log(l, JK_LOG_ERROR, "In jk_endpoint_t::service, ajp_get_reply failed in send loop %d\n", i);
- }
- else
- jk_log(l, JK_LOG_ERROR, "In jk_endpoint_t::service, ajp_send_request failed in send loop %d\n", i);
-
- jk_close_socket(p->sd);
- p->sd = -1;
- ajp_reuse_connection(p, l);
- }
- } else {
- jk_log(l, JK_LOG_ERROR, "In jk_endpoint_t::service, NULL parameters\n");
- }
+ /*
+ * We get here initial request (in reqmsg)
+ */
+ if (!ajp_marshal_into_msgb(op->request, s, l, p)) {
+ *is_recoverable_error = JK_FALSE;
+ return JK_FALSE;
+ }
+
+ /*
+ * JK_RETRIES could be replaced by the number of workers in
+ * a load-balancing configuration
+ */
+ for (i = 0; i < JK_RETRIES; i++)
+ {
+ /*
+ * We're using reqmsg which hold initial request
+ * if Tomcat is stopped or restarted, we will pass reqmsg
+ * to next valid tomcat.
+ */
+ if (ajp_send_request(e, s, l, p, op)) {
+
+ /* If we have the no recoverable error, it's probably because the sender (browser)
+ * stop sending data before the end (certainly in a big post)
+ */
+ if (! op->recoverable) {
+ *is_recoverable_error = JK_FALSE;
+ jk_log(l, JK_LOG_ERROR, "In jk_endpoint_t::service, ajp_send_request failed without recovery in send loop %d\n", i);
+ return JK_FALSE;
+ }
+
+ /* Up to there we can recover */
+ *is_recoverable_error = JK_TRUE;
+ op->recoverable = JK_TRUE;
+
+ if (ajp_get_reply(e, s, l, p, op))
+ return (JK_TRUE);
+
+ /* if we can't get reply, check if no recover flag was set
+ * if is_recoverable_error is cleared, we have started received
+ * upload data and we must consider that operation is no more recoverable
+ */
+ if (! op->recoverable) {
+ *is_recoverable_error = JK_FALSE;
+ jk_log(l, JK_LOG_ERROR, "In jk_endpoint_t::service, ajp_get_reply failed without recovery in send loop %d\n", i);
+ return JK_FALSE;
+ }
+
+ jk_log(l, JK_LOG_ERROR, "In jk_endpoint_t::service, ajp_get_reply failed in send loop %d\n", i);
+ }
+ else
+ jk_log(l, JK_LOG_ERROR, "In jk_endpoint_t::service, ajp_send_request failed in send loop %d\n", i);
+
+ jk_close_socket(p->sd);
+ p->sd = -1;
+ ajp_reuse_connection(p, l);
+ }
+ } else {
+ jk_log(l, JK_LOG_ERROR, "In jk_endpoint_t::service, NULL parameters\n");
+ }
- return JK_FALSE;
+ return JK_FALSE;
}
/*
* Validate the worker (ajp13/ajp14)
@@ -1170,25 +1172,25 @@
jk_map_t *props,
jk_worker_env_t *we,
jk_logger_t *l,
- int proto)
+ int proto)
{
- int port;
- char * host;
+ int port;
+ char * host;
jk_log(l, JK_LOG_DEBUG, "Into jk_worker_t::validate\n");
- if (proto == AJP13_PROTO) {
- port = AJP13_DEF_PORT;
- host = AJP13_DEF_HOST;
- }
- else if (proto == AJP14_PROTO) {
- port = AJP14_DEF_PORT;
- host = AJP14_DEF_HOST;
- }
- else {
- jk_log(l, JK_LOG_DEBUG, "In jk_worker_t::validate unknown protocol %d\n", proto);
- return JK_FALSE;
- }
+ if (proto == AJP13_PROTO) {
+ port = AJP13_DEF_PORT;
+ host = AJP13_DEF_HOST;
+ }
+ else if (proto == AJP14_PROTO) {
+ port = AJP14_DEF_PORT;
+ host = AJP14_DEF_HOST;
+ }
+ else {
+ jk_log(l, JK_LOG_DEBUG, "In jk_worker_t::validate unknown protocol %d\n", proto);
+ return JK_FALSE;
+ }
if (pThis && pThis->worker_private) {
ajp_worker_t *p = pThis->worker_private;
@@ -1216,10 +1218,10 @@
jk_map_t *props,
jk_worker_env_t *we,
jk_logger_t *l,
- int proto)
+ int proto)
{
- int cache;
-
+ int cache;
+
/*
* start the connection cache
*/
@@ -1232,21 +1234,29 @@
cache = AJP13_DEF_CACHE_SZ;
}
else {
- jk_log(l, JK_LOG_DEBUG, "In jk_worker_t::validate unknown protocol %d\n", proto);
+ jk_log(l, JK_LOG_DEBUG, "In jk_worker_t::init, unknown protocol %d\n", proto);
return JK_FALSE;
}
if (pThis && pThis->worker_private) {
ajp_worker_t *p = pThis->worker_private;
int cache_sz = jk_get_worker_cache_size(props, p->name, cache);
-
+ int socket_timeout = jk_get_worker_socket_timeout(props, p->name, AJP13_DEF_TIMEOUT);
+ int socket_keepalive = jk_get_worker_socket_keepalive(props, p->name, JK_FALSE);
+ int cache_timeout = jk_get_worker_cache_timeout(props, p->name, AJP_DEF_CACHE_TIMEOUT);
+
+ jk_log(l, JK_LOG_DEBUG, "In jk_worker_t::init, setting socket timeout to %d\n", socket_timeout);
+ p->socket_timeout = socket_timeout;
+ p->keepalive = socket_keepalive;
+ p->cache_timeout = cache_timeout;
/*
* Need to initialize secret here since we could return from inside
* of the following loop
*/
p->secret = jk_get_worker_secret(props, p->name );
-
+ p->ep_cache_sz = 0;
+ p->ep_mincache_sz = 0;
if (cache_sz > 0) {
p->ep_cache = (ajp_endpoint_t **)malloc(sizeof(ajp_endpoint_t *) * cache_sz);
if(p->ep_cache) {
@@ -1270,16 +1280,16 @@
int ajp_destroy(jk_worker_t **pThis,
jk_logger_t *l,
- int proto)
+ int proto)
{
jk_log(l, JK_LOG_DEBUG, "Into jk_worker_t::destroy\n");
if (pThis && *pThis && (*pThis)->worker_private) {
ajp_worker_t *aw = (*pThis)->worker_private;
- free(aw->name);
+ free(aw->name);
- jk_log(l, JK_LOG_DEBUG, "Into jk_worker_t::destroy up to %d endpoint to close\n", aw->ep_cache_sz);
+ jk_log(l, JK_LOG_DEBUG, "Into jk_worker_t::destroy up to %d endpoint to close\n", aw->ep_cache_sz);
if(aw->ep_cache_sz) {
unsigned i;
@@ -1292,10 +1302,10 @@
JK_DELETE_CS(&(aw->cs), i);
}
- if (aw->login) {
- free(aw->login);
- aw->login = NULL;
- }
+ if (aw->login) {
+ free(aw->login);
+ aw->login = NULL;
+ }
free(aw);
return JK_TRUE;
@@ -1330,8 +1340,8 @@
}
JK_LEAVE_CS(&w->cs, rc);
if(i < w->ep_cache_sz) {
- jk_log(l, JK_LOG_DEBUG, "Into jk_endpoint_t::done, recycling connection\n");
- return JK_TRUE;
+ jk_log(l, JK_LOG_DEBUG, "Into jk_endpoint_t::done, recycling connection\n");
+ return JK_TRUE;
}
}
}
@@ -1350,7 +1360,7 @@
int ajp_get_endpoint(jk_worker_t *pThis,
jk_endpoint_t **je,
jk_logger_t *l,
- int proto)
+ int proto)
{
jk_log(l, JK_LOG_DEBUG, "Into jk_worker_t::get_endpoint\n");
@@ -1363,7 +1373,10 @@
JK_ENTER_CS(&aw->cs, rc);
if (rc) {
unsigned i;
-
+ time_t now;
+ if (aw->socket_timeout > 0 || aw->cache_timeout) {
+ now = time(NULL);
+ }
for (i = 0 ; i < aw->ep_cache_sz ; i++) {
if (aw->ep_cache[i]) {
ae = aw->ep_cache[i];
@@ -1371,8 +1384,36 @@
break;
}
}
+ /* Handle enpoint cache timeouts */
+ if (aw->cache_timeout) {
+ for ( ; i < aw->ep_cache_sz ; i++) {
+ if (aw->ep_cache[i]) {
+ unsigned elapsed = (unsigned)(now - ae->last_access);
+ if (elapsed > aw->cache_timeout) {
+ jk_log(l, JK_LOG_DEBUG,
+ "In jk_endpoint_t::ajp_get_endpoint," \
+ " cleaning cache slot = %d elapsed %d\n",
+ i, elapsed);
+ ajp_close_endpoint(aw->ep_cache[i], l);
+ aw->ep_cache[i] = NULL;
+ }
+ }
+ }
+ }
JK_LEAVE_CS(&aw->cs, rc);
if (ae) {
+ if (ae->sd > 0) {
+ /* Handle timeouts for open sockets */
+ unsigned elapsed = (unsigned)(now - ae->last_access);
+ ae->last_access = now;
+ jk_log(l, JK_LOG_DEBUG, "In jk_endpoint_t::ajp_get_endpoint, time elapsed since last request = %d seconds\n", elapsed);
+ if (aw->socket_timeout > 0 && elapsed > aw->socket_timeout) {
+ jk_close_socket(ae->sd);
+ jk_log(l, JK_LOG_DEBUG,
+ "In jk_endpoint_t::ajp_get_endpoint, reached socket timeout, closed sd = %d\n", ae->sd);
+ ae->sd = -1; /* just to avoid twice close */
+ }
+ }
*je = &ae->endpoint;
return JK_TRUE;
}
@@ -1383,10 +1424,11 @@
if (ae) {
ae->sd = -1;
ae->reuse = JK_FALSE;
+ ae->last_access = time(NULL);
jk_open_pool(&ae->pool, ae->buf, sizeof(ae->buf));
ae->worker = pThis->worker_private;
ae->endpoint.endpoint_private = ae;
- ae->proto = proto;
+ ae->proto = proto;
ae->endpoint.service = ajp_service;
ae->endpoint.done = ajp_done;
*je = &ae->endpoint;
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>