⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jk_ajp_common.c

📁 精通tomcat书籍原代码,希望大家共同学习
💻 C
📖 第 1 页 / 共 5 页
字号:
            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 + -