in native/apache-2.0/mod_jk.c [803:1215]
static int init_ws_service(apache_private_data_t * private_data,
jk_ws_service_t *s, jk_server_conf_t * conf)
{
int size;
request_rec *r = private_data->r;
char *ssl_temp = NULL;
char *uri = NULL;
const char *reply_timeout = NULL;
const char *sticky_ignore = NULL;
const char *stateless = NULL;
const char *route = NULL;
rule_extension_t *e;
jk_request_conf_t *rconf;
jk_log_context_t *l = apr_pcalloc(r->pool, sizeof(jk_log_context_t));
l->logger = conf->log;
l->id = NULL;
/* 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;
s->done = ws_done;
s->add_log_items = ws_add_log_items;
s->next_vhost = ws_next_vhost;
s->vhost_to_text = ws_vhost_to_text;
s->vhost_to_uw_map = ws_vhost_to_uw_map;
rconf = (jk_request_conf_t *)ap_get_module_config(r->request_config, &jk_module);
l->id = rconf->request_id;
s->auth_type = get_env_string(r, r->ap_auth_type,
conf->auth_type_indicator, 1);
s->remote_user = get_env_string(r, r->user,
conf->remote_user_indicator, 1);
s->log_ctx = l;
s->protocol = r->protocol;
s->remote_host = (char *)ap_get_remote_host(r->connection,
r->per_dir_config,
REMOTE_HOST, NULL);
s->remote_host = get_env_string(r, s->remote_host,
conf->remote_host_indicator, 1);
if (conf->options & JK_OPT_FWDLOCAL) {
s->remote_addr = r->connection->local_ip;
/* We don't know the client port of the backend connection. */
s->remote_port = "0";
}
else {
#if (MODULE_MAGIC_NUMBER_MAJOR >= 20111130)
if (conf->options & JK_OPT_FWDPHYSICAL) {
s->remote_addr = r->connection->client_ip;
s->remote_port = apr_itoa(r->pool, r->connection->client_addr->port);
}
else {
s->remote_addr = r->useragent_ip;
s->remote_port = apr_itoa(r->pool, r->useragent_addr->port);
}
#else
s->remote_addr = r->connection->remote_ip;
s->remote_port = apr_itoa(r->pool, r->connection->remote_addr->port);
#endif
}
s->remote_addr = get_env_string(r, s->remote_addr,
conf->remote_addr_indicator, 1);
s->remote_port = get_env_string(r, s->remote_port,
conf->remote_port_indicator, 1);
if (conf->options & JK_OPT_FLUSHPACKETS)
s->flush_packets = 1;
if (conf->options & JK_OPT_FLUSHEADER)
s->flush_header = 1;
e = rconf->rule_extensions;
if (e) {
s->extension.reply_timeout = e->reply_timeout;
s->extension.sticky_ignore = e->sticky_ignore;
s->extension.stateless = e->stateless;
s->extension.use_server_error_pages = e->use_server_error_pages;
if (e->activation) {
s->extension.activation = apr_palloc(r->pool, e->activation_size * sizeof(int));
memcpy(s->extension.activation, e->activation, e->activation_size * sizeof(int));
}
if (e->fail_on_status_size > 0) {
s->extension.fail_on_status_size = e->fail_on_status_size;
s->extension.fail_on_status = apr_palloc(r->pool, e->fail_on_status_size * sizeof(int));
memcpy(s->extension.fail_on_status, e->fail_on_status, e->fail_on_status_size * sizeof(int));
}
if (e->session_cookie) {
s->extension.session_cookie = apr_pstrdup(r->pool, e->session_cookie);
}
if (e->session_path) {
s->extension.session_path = apr_pstrdup(r->pool, e->session_path);
}
if (e->set_session_cookie) {
s->extension.set_session_cookie = e->set_session_cookie;
}
if (e->session_cookie_path) {
s->extension.session_cookie_path = apr_pstrdup(r->pool, e->session_cookie_path);
}
}
reply_timeout = apr_table_get(r->subprocess_env, JK_ENV_REPLY_TIMEOUT);
if (reply_timeout) {
int r = atoi(reply_timeout);
if (r >= 0)
s->extension.reply_timeout = r;
}
sticky_ignore = apr_table_get(r->subprocess_env, JK_ENV_STICKY_IGNORE);
if (sticky_ignore) {
if (*sticky_ignore == '\0') {
s->extension.sticky_ignore = JK_TRUE;
}
else {
int r = atoi(sticky_ignore);
if (r) {
s->extension.sticky_ignore = JK_TRUE;
}
else {
s->extension.sticky_ignore = JK_FALSE;
}
}
}
stateless = apr_table_get(r->subprocess_env, JK_ENV_STATELESS);
if (stateless) {
if (*stateless == '\0') {
s->extension.stateless = JK_TRUE;
}
else {
int r = atoi(stateless);
if (r) {
s->extension.stateless = JK_TRUE;
}
else {
s->extension.stateless = JK_FALSE;
}
}
}
if (conf->options & JK_OPT_DISABLEREUSE)
s->disable_reuse = 1;
/* get route if known */
route = apr_table_get(r->subprocess_env, JK_ENV_ROUTE);
if (route && *route) {
s->route = route;
}
/* get server name */
s->server_name = get_env_string(r, (char *)ap_get_server_name(r),
conf->local_name_indicator, 0);
/* get the local IP address */
s->local_addr = get_env_string(r, r->connection->local_ip,
conf->local_addr_indicator, 0);
/* 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 = get_env_int(r, ap_get_server_port(r),
conf->local_port_indicator);
#if ((AP_MODULE_MAGIC_AT_LEAST(20051115,4)) && !defined(API_COMPATIBILITY)) || (MODULE_MAGIC_NUMBER_MAJOR >= 20060905)
s->server_software = (char *)ap_get_server_description();
#else
s->server_software = (char *)ap_get_server_version();
#endif
s->method = (char *)r->method;
s->content_length = get_content_length(r);
s->is_chunked = r->read_chunked;
if (s->content_length > 0 &&
get_env_string(r, NULL, conf->ignore_cl_indicator, 0) != NULL) {
s->content_length = 0;
s->is_chunked = 1;
}
s->no_more_chunks = 0;
#if defined(AS400) && !defined(AS400_UTF8)
/* 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
/*
* 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 recommended 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 compatibility with mod_rewrite with old Tomcats
*/
uri = rconf->orig_uri ? rconf->orig_uri : r->uri;
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 = uri;
break;
case JK_OPT_FWDURIPROXY:
size = 3 * (int)strlen(uri) + 1;
s->req_uri = apr_palloc(r->pool, size);
jk_canonenc(uri, s->req_uri, size);
break;
case JK_OPT_FWDURIESCAPED:
s->req_uri = ap_escape_uri(r->pool, uri);
break;
default:
return JK_FALSE;
}
if (conf->ssl_enable || conf->envvars) {
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 (conf->options & JK_OPT_FWDCERTCHAIN) {
const apr_array_header_t *t = apr_table_elts(r->subprocess_env);
if (t && t->nelts) {
int i;
const apr_table_entry_t *elts = (const apr_table_entry_t *) t->elts;
apr_array_header_t *certs = apr_array_make(r->pool, 1, sizeof(char *));
*(const char **)apr_array_push(certs) = s->ssl_cert;
for (i = 0; i < t->nelts; i++) {
if (!elts[i].key)
continue;
if (!strncasecmp(elts[i].key, conf->certchain_prefix,
strlen(conf->certchain_prefix)))
*(const char **)apr_array_push(certs) = elts[i].val;
}
s->ssl_cert = apr_array_pstrcat(r->pool, certs, '\0');
}
}
if (s->ssl_cert) {
s->ssl_cert_len = (unsigned int)strlen(s->ssl_cert);
if (JK_IS_DEBUG_LEVEL(l)) {
jk_log(l, JK_LOG_DEBUG,
"SSL client certificate (%d bytes): %s",
s->ssl_cert_len, s->ssl_cert);
}
}
s->ssl_protocol =
(char *)apr_table_get(r->subprocess_env,
conf->ssl_protocol_indicator);
/* 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) {
const apr_array_header_t *t = conf->envvar_items;
if (t && t->nelts) {
int i;
int j = 0;
envvar_item *elts = (envvar_item *) 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 - j] = elts[i].name;
s->attributes_values[i - j] =
(char *)apr_table_get(r->subprocess_env, elts[i].name);
if (!s->attributes_values[i - j]) {
if (elts[i].has_default) {
s->attributes_values[i - j] = elts[i].value;
}
else {
s->attributes_values[i - j] = "";
s->attributes_names[i - j] = "";
j++;
}
}
}
s->num_attributes = t->nelts - j;
}
}
}
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;
int off = 0;
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);
if (!strcasecmp(hname, "content-length")) {
if (need_content_length_header) {
need_content_length_header = JK_FALSE;
} else if (s->is_chunked) {
s->num_headers--;
off++;
continue;
}
}
s->headers_values[i - off] = apr_pstrdup(r->pool, elts[i].val);
s->headers_names[i - off] = hname;
}
/* 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;
/* Dump all connection param so we can trace what's going to
* the remote tomcat
*/
if (JK_IS_DEBUG_LEVEL(l)) {
jk_log(l, JK_LOG_DEBUG,
"Service protocol=%s method=%s ssl=%s host=%s addr=%s name=%s port=%d auth=%s user=%s laddr=%s raddr=%s uaddr=%s uri=%s",
STRNULL_FOR_NULL(s->protocol),
STRNULL_FOR_NULL(s->method),
s->is_ssl ? "true" : "false",
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),
#if (MODULE_MAGIC_NUMBER_MAJOR >= 20111130)
STRNULL_FOR_NULL(r->connection->client_ip),
STRNULL_FOR_NULL(r->useragent_ip),
#else
STRNULL_FOR_NULL(r->connection->remote_ip),
STRNULL_FOR_NULL(r->connection->remote_ip),
#endif
STRNULL_FOR_NULL(s->req_uri));
}
return JK_TRUE;
}