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

📄 mod_jk.c

📁 精通tomcat书籍原代码,希望大家共同学习
💻 C
📖 第 1 页 / 共 5 页
字号:
                 * directly to the wire.
                 */
                int toSend = (ll > CHUNK_SIZE) ? CHUNK_SIZE : ll;
                r = ap_rwrite(bb, toSend, p->r);
#else
                r = ap_rwrite(bb, ll, p->r);
#endif
                if (JK_IS_DEBUG_LEVEL(main_log))
                    jk_log(main_log, JK_LOG_DEBUG,
                           "written %d out of %d", r, ll);

                if (r < 0)
                    return JK_FALSE;
                ll -= r;
                bb += r;
            }
        }

        return JK_TRUE;
    }
    return JK_FALSE;
}

/* ========================================================================= */
/* Utility functions                                                         */
/* ========================================================================= */

/* ========================================================================= */
/* Log something to Jk log file then exit */
static void jk_error_exit(const char *file,
                          int line,
                          int level,
                          const server_rec * s,
                          apr_pool_t * p, const char *fmt, ...)
{
    va_list ap;
    char *res;

    va_start(ap, fmt);
    res = apr_pvsprintf(s->process->pool, fmt, ap);
    va_end(ap);

    ap_log_error(file, line, level, 0, s, res);

    /* Exit process */
    exit(1);
}

static int get_content_length(request_rec * r)
{
    if (r->clength > 0) {
        return (int)r->clength;
    }
    else if (r->main == NULL || r->main == r) {
        char *lenp = (char *)apr_table_get(r->headers_in, "Content-Length");

        if (lenp) {
            int rc = atoi(lenp);
            if (rc > 0) {
                return rc;
            }
        }
    }

    return 0;
}

static int init_ws_service(apache_private_data_t * private_data,
                           jk_ws_service_t *s, jk_server_conf_t * conf)
{
    request_rec *r = private_data->r;

    char *ssl_temp = NULL;
    s->jvm_route = NULL;        /* Used for sticky session routing */

    /* Copy in function pointers (which are really methods) */
    s->start_response = ws_start_response;
    s->read = ws_read;
    s->write = ws_write;
    s->flush = ws_flush;

    /* Clear RECO status */
    s->reco_status = RECO_NONE;

    s->auth_type = NULL_FOR_EMPTY(r->ap_auth_type);
    s->remote_user = NULL_FOR_EMPTY(r->user);

    s->protocol = r->protocol;
    s->remote_host = (char *)ap_get_remote_host(r->connection,
                                                r->per_dir_config,
                                                REMOTE_HOST, NULL);
    s->remote_host = NULL_FOR_EMPTY(s->remote_host);
    if (conf->options & JK_OPT_FWDLOCAL)
        s->remote_addr = NULL_FOR_EMPTY(r->connection->local_ip);
    else
        s->remote_addr = NULL_FOR_EMPTY(r->connection->remote_ip);
    if (conf->options & JK_OPT_FLUSHPACKETS)
        s->flush_packets = 1;
    else
        s->flush_packets = 0;
    /* get server name */
    s->server_name = (char *)ap_get_server_name(r);

    /* get the real port (otherwise redirect failed) */
    /* XXX: use apache API for getting server port
     *
     * Pre 1.2.7 versions used:
     * s->server_port = r->connection->local_addr->port;
     */
    s->server_port  = ap_get_server_port(r);

    s->server_software = (char *)ap_get_server_version();
    s->method = (char *)r->method;
    s->content_length = get_content_length(r);
    s->is_chunked = r->read_chunked;
    s->no_more_chunks = 0;
#ifdef AS400
    /* Get the query string that is not translated to EBCDIC  */
    s->query_string = ap_get_original_query_string(r);
#else
    s->query_string = r->args;
#endif

    /* Dump all connection param so we can trace what's going to
     * the remote tomcat
     */
    if (JK_IS_DEBUG_LEVEL(conf->log)) {
        jk_log(conf->log, JK_LOG_DEBUG,
               "Service protocol=%s method=%s host=%s addrr=%s name=%s port=%d auth=%s user=%s laddr=%s raddr=%s",
               STRNULL_FOR_NULL(s->protocol),
               STRNULL_FOR_NULL(s->method),
               STRNULL_FOR_NULL(s->remote_host),
               STRNULL_FOR_NULL(s->remote_addr),
               STRNULL_FOR_NULL(s->server_name),
               s->server_port,
               STRNULL_FOR_NULL(s->auth_type),
               STRNULL_FOR_NULL(s->remote_user),
               STRNULL_FOR_NULL(r->connection->local_ip),
               STRNULL_FOR_NULL(r->connection->remote_ip));
    }

    /*
     * The 2.2 servlet spec errata says the uri from
     * HttpServletRequest.getRequestURI() should remain encoded.
     * [http://java.sun.com/products/servlet/errata_042700.html]
     *
     * We use JkOptions to determine which method to be used
     *
     * ap_escape_uri is the latest recommanded but require
     *               some java decoding (in TC 3.3 rc2)
     *
     * unparsed_uri is used for strict compliance with spec and
     *              old Tomcat (3.2.3 for example)
     *
     * uri is use for compatibilty with mod_rewrite with old Tomcats
     */

    switch (conf->options & JK_OPT_FWDURIMASK) {

    case JK_OPT_FWDURICOMPATUNPARSED:
        s->req_uri = r->unparsed_uri;
        if (s->req_uri != NULL) {
            char *query_str = strchr(s->req_uri, '?');
            if (query_str != NULL) {
                *query_str = 0;
            }
        }

        break;

    case JK_OPT_FWDURICOMPAT:
        s->req_uri = r->uri;
        break;

    case JK_OPT_FWDURIESCAPED:
        s->req_uri = ap_escape_uri(r->pool, r->uri);
        break;

    default:
        return JK_FALSE;
    }

    s->is_ssl = JK_FALSE;
    s->ssl_cert = NULL;
    s->ssl_cert_len = 0;
    s->ssl_cipher = NULL;       /* required by Servlet 2.3 Api,
                                   allready in original ajp13 */
    s->ssl_session = NULL;
    s->ssl_key_size = -1;       /* required by Servlet 2.3 Api, added in jtc */

    if (conf->ssl_enable || conf->envvars_in_use) {
        ap_add_common_vars(r);

        if (conf->ssl_enable) {
            ssl_temp =
                (char *)apr_table_get(r->subprocess_env,
                                      conf->https_indicator);
            if (ssl_temp && !strcasecmp(ssl_temp, "on")) {
                s->is_ssl = JK_TRUE;
                s->ssl_cert =
                    (char *)apr_table_get(r->subprocess_env,
                                          conf->certs_indicator);
                if (s->ssl_cert) {
                    s->ssl_cert_len = strlen(s->ssl_cert);
                }
                /* Servlet 2.3 API */
                s->ssl_cipher =
                    (char *)apr_table_get(r->subprocess_env,
                                          conf->cipher_indicator);
                s->ssl_session =
                    (char *)apr_table_get(r->subprocess_env,
                                          conf->session_indicator);

                if (conf->options & JK_OPT_FWDKEYSIZE) {
                    /* Servlet 2.3 API */
                    ssl_temp = (char *)apr_table_get(r->subprocess_env,
                                                     conf->
                                                     key_size_indicator);
                    if (ssl_temp)
                        s->ssl_key_size = atoi(ssl_temp);
                }
            }
        }

        if (conf->envvars_in_use) {
            const apr_array_header_t *t = apr_table_elts(conf->envvars);
            if (t && t->nelts) {
                int i;
                apr_table_entry_t *elts = (apr_table_entry_t *) t->elts;
                s->attributes_names = apr_palloc(r->pool,
                                                 sizeof(char *) * t->nelts);
                s->attributes_values = apr_palloc(r->pool,
                                                  sizeof(char *) * t->nelts);

                for (i = 0; i < t->nelts; i++) {
                    s->attributes_names[i] = elts[i].key;
                    s->attributes_values[i] =
                        (char *)apr_table_get(r->subprocess_env, elts[i].key);
                    if (!s->attributes_values[i]) {
                        s->attributes_values[i] = elts[i].val;
                    }
                }

                s->num_attributes = t->nelts;
            }
        }
    }

    s->headers_names = NULL;
    s->headers_values = NULL;
    s->num_headers = 0;
    if (r->headers_in && apr_table_elts(r->headers_in)) {
        int need_content_length_header = (!s->is_chunked
                                          && s->content_length ==
                                          0) ? JK_TRUE : JK_FALSE;
        const apr_array_header_t *t = apr_table_elts(r->headers_in);
        if (t && t->nelts) {
            int i;
            apr_table_entry_t *elts = (apr_table_entry_t *) t->elts;
            s->num_headers = t->nelts;
            /* allocate an extra header slot in case we need to add a content-length header */
            s->headers_names =
                apr_palloc(r->pool, sizeof(char *) * (t->nelts + 1));
            s->headers_values =
                apr_palloc(r->pool, sizeof(char *) * (t->nelts + 1));
            if (!s->headers_names || !s->headers_values)
                return JK_FALSE;
            for (i = 0; i < t->nelts; i++) {
                char *hname = apr_pstrdup(r->pool, elts[i].key);
                s->headers_values[i] = apr_pstrdup(r->pool, elts[i].val);
                s->headers_names[i] = hname;
                if (need_content_length_header &&
                    !strcasecmp(s->headers_values[i], "content-length")) {
                    need_content_length_header = JK_FALSE;
                }
            }
            /* Add a content-length = 0 header if needed.
             * Ajp13 assumes an absent content-length header means an unknown,
             * but non-zero length body.
             */
            if (need_content_length_header) {
                s->headers_names[s->num_headers] = "content-length";
                s->headers_values[s->num_headers] = "0";
                s->num_headers++;
            }
        }
        /* Add a content-length = 0 header if needed. */
        else if (need_content_length_header) {
            s->headers_names = apr_palloc(r->pool, sizeof(char *));
            s->headers_values = apr_palloc(r->pool, sizeof(char *));
            if (!s->headers_names || !s->headers_values)
                return JK_FALSE;
            s->headers_names[0] = "content-length";
            s->headers_values[0] = "0";
            s->num_headers++;
        }
    }
    s->uw_map = conf->uw_map;
    return JK_TRUE;
}

/*
 * The JK module command processors
 *
 * The below are all installed so that Apache calls them while it is
 * processing its config files.  This allows configuration info to be
 * copied into a jk_server_conf_t object, which is then used for request
 * filtering/processing.
 *
 * See jk_cmds definition below for explanations of these options.
 */

/*
 * JkMountCopy directive handling
 *
 * JkMountCopy On/Off
 */

static const char *jk_set_mountcopy(cmd_parms * cmd, void *dummy, int flag)
{
    server_rec *s = cmd->server;
    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);

    /* Set up our value */
    conf->mountcopy = flag ? JK_TRUE : JK_FALSE;

    return NULL;
}

/*
 * JkMount directive handling
 *
 * JkMount URI(context) worker
 */

static const char *jk_mount_context(cmd_parms * cmd,
                                    void *dummy,
                                    const char *context,
                                    const char *worker)
{
    server_rec *s = cmd->server;
    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);
    const char *c, *w;

    if (worker != NULL && cmd->path == NULL ) {
        c = context;
        w = worker;
    }
    else if (worker == NULL && cmd->path != NULL) {
        c = cmd->path;
        w = context;
    }
    else {
        if (worker == NULL)
            return "JkMount needs a path when not defined in a location";
        else
            return "JkMount can not have a path when defined in a location";
    }

    if (c[0] != '/')
        return "JkMount context should start with /";

    /*
     * Add the new worker to the alias map.
     */
    jk_map_put(conf->uri_to_context, c, w, NULL);
    return NULL;
}

/*
 * JkUnMount directive handling
 *
 * JkUnMount URI(context) worker
 */

static const char *jk_unmount_context(cmd_parms * cmd,
                                      void *dummy,
                                      const char *context,
                                      const char *worker)
{
    server_rec *s = cmd->server;
    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);
    char *uri;
    const char *c, *w;

    if (worker != NULL && cmd->path == NULL ) {
        c = context;
        w = worker;
    }
    else if (worker == NULL && cmd->path != NULL) {
        c = cmd->path;
        w = context;
    }
    else {
        if (worker == NULL)
            return "JkUnMount needs a path when not defined in a location";
        else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -