in native/apache-2.0/mod_jk.c [3829:4045]
static int jk_translate(request_rec * r)
{
jk_request_conf_t *rconf = apr_palloc(r->pool, sizeof(jk_request_conf_t));
rconf->jk_handled = JK_FALSE;
rconf->rule_extensions = NULL;
rconf->orig_uri = NULL;
ap_set_module_config(r->request_config, &jk_module, rconf);
if (!r->proxyreq) {
jk_log_context_t log_ctx;
jk_log_context_t *l = &log_ctx;
jk_server_conf_t *conf =
(jk_server_conf_t *) ap_get_module_config(r->server->
module_config,
&jk_module);
l->logger = conf->log;
l->id = "JK_TRANSLATE";
if (conf) {
char *clean_uri;
int rc;
const char *worker;
JK_TRACE_ENTER(l);
rconf->request_id = get_env_string(r, NULL,
conf->request_id_indicator, 1);
if (rconf->request_id == NULL) {
rconf->request_id = get_env_string(r, NULL, JK_ENV_REQUEST_ID, 1);
}
l->id = rconf->request_id;
if ((r->handler != NULL) && (!strcmp(r->handler, JK_HANDLER))) {
/* Somebody already set the handler, probably manual config
* or "native" configuration, no need for extra overhead
*/
if (JK_IS_DEBUG_LEVEL(l))
jk_log(l, JK_LOG_DEBUG,
"Manually mapped, no need to call uri_to_worker");
JK_TRACE_EXIT(l);
return DECLINED;
}
if (apr_table_get(r->subprocess_env, "no-jk")) {
if (JK_IS_DEBUG_LEVEL(l))
jk_log(l, JK_LOG_DEBUG,
"Into translate no-jk env var detected for uri=%s, declined",
r->uri);
JK_TRACE_EXIT(l);
return DECLINED;
}
clean_uri = apr_pstrdup(r->pool, r->uri);
rc = jk_servlet_normalize(clean_uri, l);
if (rc != 0) {
JK_TRACE_EXIT(l);
return HTTP_BAD_REQUEST;
}
/* Special case to make sure that apache can serve a directory
listing if there are no matches for the DirectoryIndex and
Tomcat webapps are mapped into apache using JkAutoAlias. */
if (r->main != NULL && r->main->handler != NULL &&
(conf->alias_dir != NULL) &&
!strcmp(r->main->handler, DIR_MAGIC_TYPE)) {
/* Append the request uri to the JkAutoAlias directory and
determine if the file exists. */
apr_finfo_t finfo;
finfo.filetype = APR_NOFILE;
/* Map uri to a context static file */
if (strlen(clean_uri) > 1) {
char *context_path = NULL;
context_path = apr_pstrcat(r->pool, conf->alias_dir, clean_uri, NULL);
if (context_path != NULL) {
apr_stat(&finfo, context_path, APR_FINFO_TYPE,
r->pool);
}
}
if (finfo.filetype != APR_REG) {
if (JK_IS_DEBUG_LEVEL(l))
jk_log(l, JK_LOG_DEBUG,
"JkAutoAlias, no DirectoryIndex file for URI %s",
r->uri);
JK_TRACE_EXIT(l);
return DECLINED;
}
}
if (!conf->uw_map) {
if (JK_IS_DEBUG_LEVEL(l))
jk_log(l, JK_LOG_DEBUG,
"missing uri map for %s:%s",
conf->s->server_hostname ? conf->s->server_hostname : "_default_",
r->uri);
JK_TRACE_EXIT(l);
return DECLINED;
}
else {
rule_extension_t *e;
worker = map_uri_to_worker_ext(conf->uw_map, clean_uri,
NULL, &e, NULL, l);
if (worker) {
rconf->rule_extensions = e;
rconf->orig_uri = r->uri;
r->uri = clean_uri;
}
}
if (worker) {
r->handler = apr_pstrdup(r->pool, JK_HANDLER);
apr_table_setn(r->notes, JK_NOTE_WORKER_NAME, worker);
/* This could be a sub-request, possibly from mod_dir */
/* Also add the the HANDLER to the main request */
if (r->main) {
r->main->handler = apr_pstrdup(r->main->pool, JK_HANDLER);
apr_table_setn(r->main->notes, JK_NOTE_WORKER_NAME, worker);
}
JK_TRACE_EXIT(l);
return OK;
}
else if (conf->alias_dir != NULL) {
/* Automatically map uri to a context static file */
if (JK_IS_DEBUG_LEVEL(l))
jk_log(l, JK_LOG_DEBUG,
"check alias_dir: %s",
conf->alias_dir);
if (strlen(clean_uri) > 1) {
/* Get the context directory name */
char *context_dir = NULL;
char *context_path = NULL;
char *child_dir = NULL;
char *index = clean_uri;
char *suffix = strchr(index + 1, '/');
if (suffix != NULL) {
int size = (int)(suffix - index);
context_dir = apr_pstrndup(r->pool, index, size);
/* Get the context child directory name */
index = index + size + 1;
suffix = strchr(index, '/');
if (suffix != NULL) {
size = (int)(suffix - index);
child_dir = apr_pstrndup(r->pool, index, size);
}
else {
child_dir = index;
}
/* Deny access to WEB-INF and META-INF directories */
if (child_dir != NULL) {
if (JK_IS_DEBUG_LEVEL(l))
jk_log(l, JK_LOG_DEBUG,
"AutoAlias child_dir: %s",
child_dir);
if (!strcasecmp(child_dir, "WEB-INF")
|| !strcasecmp(child_dir, "META-INF")) {
if (JK_IS_DEBUG_LEVEL(l))
jk_log(l, JK_LOG_DEBUG,
"AutoAlias HTTP_NOT_FOUND for URI: %s",
r->uri);
JK_TRACE_EXIT(l);
return HTTP_NOT_FOUND;
}
}
}
else {
context_dir = apr_pstrdup(r->pool, index);
}
context_path = apr_pstrcat(r->pool, conf->alias_dir, context_dir, NULL);
if (context_path != NULL) {
apr_finfo_t finfo;
finfo.filetype = APR_NOFILE;
apr_stat(&finfo, context_path, APR_FINFO_TYPE,
r->pool);
if (finfo.filetype == APR_DIR) {
char *ret = apr_pstrcat(r->pool, conf->alias_dir, clean_uri, NULL);
/* Add code to verify real path ap_os_canonical_name */
if (ret != NULL) {
if (JK_IS_DEBUG_LEVEL(l))
jk_log(l, JK_LOG_DEBUG,
"AutoAlias OK for file: %s",
ret);
r->filename = ret;
JK_TRACE_EXIT(l);
return OK;
}
}
else {
/* Deny access to war files in web app directory */
int size = (int)strlen(context_dir);
if (size > 4
&& !strcasecmp(context_dir + (size - 4),
".war")) {
if (JK_IS_DEBUG_LEVEL(l))
jk_log(l, JK_LOG_DEBUG,
"AutoAlias HTTP_FORBIDDEN for URI: %s",
r->uri);
JK_TRACE_EXIT(l);
return HTTP_FORBIDDEN;
}
}
}
}
}
else {
if (JK_IS_DEBUG_LEVEL(l))
jk_log(l, JK_LOG_DEBUG,
"no match for %s found",
r->uri);
}
}
}
return DECLINED;
}