📄 jk_ajp_common.c
字号:
rc = ajp_connection_tcp_send_message(p, op->post, l);
if (rc < 0) {
jk_log(l, JK_LOG_ERROR,
"Tomcat is down or network problems.", rc);
JK_TRACE_EXIT(l);
return JK_FALSE;
}
}
else if (JK_FATAL_ERROR == rc) {
/*
* we won't be able to gracefully recover from this so
* set recoverable to false and get out.
*/
op->recoverable = JK_FALSE;
JK_TRACE_EXIT(l);
return JK_FALSE;
}
else if (JK_CLIENT_ERROR == rc) {
/*
* Client has stop talking to us, so get out.
* We assume this isn't our fault, so just a normal exit.
* In most (all?) cases, the ajp13_endpoint::reuse will still be
* false here, so this will be functionally the same as an
* un-recoverable error. We just won't log it as such.
*/
JK_TRACE_EXIT(l);
return JK_CLIENT_ERROR;
}
else if (rc < 0) {
JK_TRACE_EXIT(l);
return (JK_FALSE); /* XXX error */
}
}
/* XXX: Not reached? */
JK_TRACE_EXIT(l);
return JK_FALSE;
}
/*
* service is now splitted in ajp_send_request and ajp_get_reply
* much more easier to do errors recovery
*
* We serve here the request, using AJP13/AJP14 (e->proto)
*
*/
static int JK_METHOD ajp_service(jk_endpoint_t *e,
jk_ws_service_t *s,
jk_logger_t *l, int *is_error)
{
int i, err;
ajp_operation_t oper;
ajp_operation_t *op = &oper;
JK_TRACE_ENTER(l);
if (is_error)
*is_error = JK_HTTP_SERVER_ERROR;
if (e && e->endpoint_private && s && is_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;
s->secret = p->worker->secret;
/*
* We get here initial request (in reqmsg)
*/
if (!ajp_marshal_into_msgb(op->request, s, l, p)) {
*is_error = JK_REQUEST_TOO_LARGE;
jk_log(l, JK_LOG_INFO,
"Creating AJP message failed, "
"without recovery");
JK_TRACE_EXIT(l);
return JK_CLIENT_ERROR;
}
if (JK_IS_DEBUG_LEVEL(l))
jk_log(l, JK_LOG_DEBUG, "processing with %d retries", s->retries);
/*
* JK_RETRIES could be replaced by the number of workers in
* a load-balancing configuration
*/
for (i = 0; i < s->retries; i++) {
/*
* We're using reqmsg which hold initial request
* if Tomcat is stopped or restarted, we will pass reqmsg
* to next valid tomcat.
*/
err = ajp_send_request(e, s, l, p, op);
if (err == JK_TRUE) {
/* If we have the no recoverable error, it's probably because
* the sender (browser) stopped sending data before the end
* (certainly in a big post)
*/
if (!op->recoverable) {
*is_error = JK_HTTP_SERVER_ERROR;
jk_log(l, JK_LOG_ERROR,
"sending request to tomcat failed "
"without recovery in send loop %d", i);
JK_TRACE_EXIT(l);
return JK_FALSE;
}
/* Up to there we can recover */
err = ajp_get_reply(e, s, l, p, op);
if (err == JK_TRUE) {
*is_error = JK_HTTP_OK;
/* Done with the request */
JK_TRACE_EXIT(l);
return JK_TRUE;
}
if (err != JK_CLIENT_ERROR) {
/* if we can't get reply, check if no recover flag was set
* if is_recoverable_error is cleared, we have started
* receiving upload data and we must consider that
* operation is no more recoverable
*/
if (!op->recoverable) {
*is_error = JK_HTTP_BAD_GATEWAY;
jk_log(l, JK_LOG_ERROR,
"receiving reply from tomcat failed "
"without recovery in send loop %d", i);
JK_TRACE_EXIT(l);
return JK_FALSE;
}
jk_log(l, JK_LOG_INFO,
"Receiving from tomcat failed, "
"recoverable operation attempt=%d", i);
/* Check for custom retries */
if (i >= JK_RETRIES) {
jk_sleep_def();
}
}
else {
*is_error = JK_HTTP_BAD_REQUEST;
jk_log(l, JK_LOG_INFO,
"Receiving from tomcat failed, "
"because of client error "
"without recovery in send loop %d", i);
JK_TRACE_EXIT(l);
return JK_CLIENT_ERROR;
}
}
if (err == JK_CLIENT_ERROR) {
*is_error = JK_HTTP_BAD_REQUEST;
jk_log(l, JK_LOG_INFO,
"Sending request to tomcat failed, "
"because of client error "
"without recovery in send loop %d", i);
JK_TRACE_EXIT(l);
return JK_CLIENT_ERROR;
}
else {
jk_log(l, JK_LOG_INFO,
"Sending request to tomcat failed, "
"recoverable operation attempt=%d", i + 1);
}
/* Get another connection from the pool and try again */
ajp_next_connection(p, l);
}
*is_error = JK_HTTP_SERVER_BUSY;
/* Log the error only once per failed request. */
jk_log(l, JK_LOG_ERROR,
"Error connecting to tomcat. Tomcat is probably not started "
"or is listening on the wrong port. worker=%s failed",
p->worker->name);
}
else {
jk_log(l, JK_LOG_ERROR, "end of service with error");
}
JK_TRACE_EXIT(l);
return JK_FALSE;
}
/*
* Validate the worker (ajp13/ajp14)
*/
int ajp_validate(jk_worker_t *pThis,
jk_map_t *props,
jk_worker_env_t *we, jk_logger_t *l, int proto)
{
int port;
const char *host;
JK_TRACE_ENTER(l);
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_ERROR,
"unknown protocol %d", proto);
JK_TRACE_EXIT(l);
return JK_FALSE;
}
if (pThis && pThis->worker_private) {
ajp_worker_t *p = pThis->worker_private;
p->port = jk_get_worker_port(props, p->name, port);
p->host = jk_get_worker_host(props, p->name, host);
if (JK_IS_DEBUG_LEVEL(l))
jk_log(l, JK_LOG_DEBUG,
"worker %s contact is '%s:%d'",
p->name, p->host, p->port);
if (p->port > 1024) {
if (jk_resolve(p->host, p->port, &p->worker_inet_addr)) {
JK_TRACE_EXIT(l);
return JK_TRUE;
}
jk_log(l, JK_LOG_ERROR,
"can't resolve tomcat address %s", host);
}
jk_log(l, JK_LOG_ERROR,
"invalid host and port %s %d",
((p->host == NULL) ? "NULL" : p->host), p->port);
}
else {
JK_LOG_NULL_PARAMS(l);
}
JK_TRACE_EXIT(l);
return JK_FALSE;
}
static int ajp_create_endpoint_cache(ajp_worker_t *p, int proto, jk_logger_t *l)
{
unsigned int i;
time_t now = time(NULL);
JK_TRACE_ENTER(l);
p->ep_cache = (ajp_endpoint_t **)calloc(1, sizeof(ajp_endpoint_t *) *
p->ep_cache_sz);
if (!p->ep_cache) {
JK_TRACE_EXIT(l);
return JK_FALSE;
}
if (JK_IS_DEBUG_LEVEL(l))
jk_log(l, JK_LOG_DEBUG,
"setting connection cache size to %d",
p->ep_cache_sz);
for (i = 0; i < p->ep_cache_sz; i++) {
p->ep_cache[i] = (ajp_endpoint_t *)calloc(1, sizeof(ajp_endpoint_t));
if (!p->ep_cache[i]) {
jk_log(l, JK_LOG_ERROR,
"creating endpont cache slot %d errno=%d",
i, errno);
JK_TRACE_EXIT(l);
return JK_FALSE;
}
p->ep_cache[i]->sd = -1;
p->ep_cache[i]->reuse = JK_FALSE;
p->ep_cache[i]->last_access = now;
jk_open_pool(&(p->ep_cache[i]->pool), p->ep_cache[i]->buf,
sizeof(p->ep_cache[i]->buf));
p->ep_cache[i]->worker = p;
p->ep_cache[i]->endpoint.endpoint_private = p->ep_cache[i];
p->ep_cache[i]->proto = proto;
p->ep_cache[i]->endpoint.service = ajp_service;
p->ep_cache[i]->endpoint.done = ajp_done;
}
JK_TRACE_EXIT(l);
return JK_TRUE;
}
int ajp_init(jk_worker_t *pThis,
jk_map_t *props, jk_worker_env_t *we, jk_logger_t *l, int proto)
{
int rc = JK_FALSE;
int cache;
/*
* start the connection cache
*/
JK_TRACE_ENTER(l);
cache = jk_get_worker_def_cache_size(proto);
if (pThis && pThis->worker_private) {
ajp_worker_t *p = pThis->worker_private;
p->ep_cache_sz = jk_get_worker_cache_size(props, p->name, cache);
p->socket_timeout =
jk_get_worker_socket_timeout(props, p->name, AJP_DEF_SOCKET_TIMEOUT);
p->socket_buf =
jk_get_worker_socket_buffer(props, p->name, 8192);
p->keepalive =
jk_get_worker_socket_keepalive(props, p->name, JK_FALSE);
jk_log(l, JK_LOG_DEBUG,
"setting socket keepalive to %d",
p->keepalive);
p->recycle_timeout =
jk_get_worker_recycle_timeout(props, p->name, AJP13_DEF_TIMEOUT);
p->cache_timeout =
jk_get_worker_cache_timeout(props, p->name,
AJP_DEF_CACHE_TIMEOUT);
p->connect_timeout =
jk_get_worker_connect_timeout(props, p->name,
AJP_DEF_CONNECT_TIMEOUT);
p->reply_timeout =
jk_get_worker_reply_timeout(props, p->name,
AJP_DEF_REPLY_TIMEOUT);
p->prepost_timeout =
jk_get_worker_prepost_timeout(props, p->name,
AJP_DEF_PREPOST_TIMEOUT);
p->recovery_opts =
jk_get_worker_recovery_opts(props, p->name,
AJP_DEF_RECOVERY_OPTS);
pThis->retries =
jk_get_worker_retries(props, p->name,
JK_RETRIES);
if (pThis->retries < 1) {
jk_log(l, JK_LOG_INFO,
"number of retries must be grater then 1. Setting to default=%d",
JK_RETRIES);
pThis->retries = JK_RETRIES;
}
if (JK_IS_DEBUG_LEVEL(l)) {
jk_log(l, JK_LOG_DEBUG,
"setting socket timeout to %d",
p->socket_timeout);
jk_log(l, JK_LOG_DEBUG,
"setting socket buffer size to %d",
p->socket_buf);
jk_log(l, JK_LOG_DEBUG,
"setting connection recycle timeout to %d",
p->recycle_timeout);
jk_log(l, JK_LOG_DEBUG,
"setting cache timeout to %d",
p->cache_timeout);
jk_log(l, JK_LOG_DEBUG,
"setting connect timeout to %d",
p->connect_timeout);
jk_log(l, JK_LOG_DEBUG,
"setting reply timeout to %d",
p->reply_timeout);
jk_log(l, JK_LOG_DEBUG,
"setting prepost timeout to %d",
p->prepost_timeout);
jk_log(l, JK_LOG_DEBUG,
"setting recovery opts to %d",
p->recovery_opts);
jk_log(l, JK_LOG_DEBUG,
"setting number of retries to %d",
pThis->retries);
}
/*
* Need to initialize secret here since we could return from inside
* of the foll
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -