You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by hg...@apache.org on 2001/05/03 16:36:13 UTC
cvs commit: jakarta-tomcat/proposals/web-connector/native/common jk_uri_worker_map.c jk_uri_worker_map.h
hgomez 01/05/03 07:36:13
Added: proposals/web-connector/native/common jk_uri_worker_map.c
jk_uri_worker_map.h
Log:
uri stuff
Revision Changes Path
1.1 jakarta-tomcat/proposals/web-connector/native/common/jk_uri_worker_map.c
Index: jk_uri_worker_map.c
===================================================================
/*
* Copyright (c) 1997-1999 The Java Apache Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Java Apache
* Project for use in the Apache JServ servlet engine project
* <http://java.apache.org/>."
*
* 4. The names "Apache JServ", "Apache JServ Servlet Engine" and
* "Java Apache Project" must not be used to endorse or promote products
* derived from this software without prior written permission.
*
* 5. Products derived from this software may not be called "Apache JServ"
* nor may "Apache" nor "Apache JServ" appear in their names without
* prior written permission of the Java Apache Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Java Apache
* Project for use in the Apache JServ servlet engine project
* <http://java.apache.org/>."
*
* THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "AS IS" AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JAVA APACHE PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Java Apache Group. For more information
* on the Java Apache Project and the Apache JServ Servlet Engine project,
* please see <http://java.apache.org/>.
*
*/
/***************************************************************************
* Description: URI to worker map object. *
* Maps can be *
* *
* Exact Context -> /exact/uri=worker e.g. /examples/do*=ajp12 *
* Context Based -> /context/*=worker e.g. /examples/*=ajp12 *
* Context and suffix ->/context/*.suffix=worker e.g. /examples/*.jsp=ajp12*
* *
* This lets us either partition the work among the web server and the *
* servlet container. *
* *
* Author: Gal Shachor <sh...@il.ibm.com> *
* Version: $Revision: 1.1 $ *
***************************************************************************/
#include "jk_pool.h"
#include "jk_util.h"
#include "jk_uri_worker_map.h"
#define MATCH_TYPE_EXACT (0)
#define MATCH_TYPE_CONTEXT (1)
#define MATCH_TYPE_SUFFIX (2)
struct uri_worker_record {
/* Original uri for logging */
char *uri;
/* Name of worker mapped */
char *worker_name;
/* Suffix of uri */
char *suffix;
/* Base context */
char *context;
/* char length of the context */
unsigned ctxt_len;
int match_type;
};
typedef struct uri_worker_record uri_worker_record_t;
struct jk_uri_worker_map {
jk_pool_t p;
jk_pool_atom_t buf[SMALL_POOL_SIZE];
uri_worker_record_t *maps;
unsigned size;
};
/*
* We are now in a security nightmare, it maybe that somebody sent
* us a uri that looks like /top-secret.jsp. and the web server will
* fumble and return the jsp content.
*
* To solve that we will check for path info following the suffix, we
* will also check that the end of the uri is not .suffix.
*/
static int check_security_fraud(jk_uri_worker_map_t *uw_map,
const char *uri,
jk_logger_t *l)
{
unsigned i;
for(i = 0 ; i < uw_map->size ; i++) {
if(MATCH_TYPE_SUFFIX == uw_map->maps[i].match_type) {
char *suffix_start;
for(suffix_start = strstr(uri, uw_map->maps[i].suffix) ;
suffix_start ;
suffix_start = strstr(suffix_start + 1, uw_map->maps[i].suffix)) {
if('.' != *(suffix_start - 1)) {
continue;
} else {
char *after_suffix = suffix_start + strlen(uw_map->maps[i].suffix) + 1;
if((('.' == *after_suffix) || ('/' == *after_suffix)) &&
(0 == strncmp(uw_map->maps[i].context, uri, uw_map->maps[i].ctxt_len))) {
/*
* Security violation !!!
* this is a fraud.
*/
return i;
}
}
}
}
}
return -1;
}
int uri_worker_map_alloc(jk_uri_worker_map_t **uw_map,
jk_map_t *init_data,
jk_logger_t *l)
{
jk_log(l, JK_LOG_DEBUG,
"Into jk_uri_worker_map_t::uri_worker_map_alloc\n");
if(init_data && uw_map) {
return uri_worker_map_open(*uw_map = (jk_uri_worker_map_t *)malloc(sizeof(jk_uri_worker_map_t)),
init_data,
l);
}
jk_log(l, JK_LOG_ERROR,
"In jk_uri_worker_map_t::uri_worker_map_alloc, NULL parameters\n");
return JK_FALSE;
}
int uri_worker_map_free(jk_uri_worker_map_t **uw_map,
jk_logger_t *l)
{
jk_log(l, JK_LOG_DEBUG,
"Into jk_uri_worker_map_t::uri_worker_map_free\n");
if(uw_map && *uw_map) {
uri_worker_map_close(*uw_map, l);
free(*uw_map);
*uw_map = NULL;
return JK_TRUE;
}
else
jk_log(l, JK_LOG_ERROR,
"In jk_uri_worker_map_t::uri_worker_map_free, NULL parameters\n");
return JK_FALSE;
}
int uri_worker_map_open(jk_uri_worker_map_t *uw_map,
jk_map_t *init_data,
jk_logger_t *l)
{
int rc = JK_FALSE;
jk_log(l, JK_LOG_DEBUG,
"Into jk_uri_worker_map_t::uri_worker_map_open\n");
if(uw_map) {
int sz;
rc = JK_TRUE;
jk_open_pool(&uw_map->p,
uw_map->buf,
sizeof(jk_pool_atom_t) * SMALL_POOL_SIZE);
uw_map->size = 0;
uw_map->maps = NULL;
sz = map_size(init_data);
jk_log(l, JK_LOG_DEBUG,
"jk_uri_worker_map_t::uri_worker_map_open, rule map size is %d\n",
sz);
if(sz > 0) {
uw_map->maps = jk_pool_alloc(&uw_map->p, sz * sizeof(uri_worker_record_t));
if(uw_map->maps) {
int i, j;
for(i = 0, j = 0 ; i < sz ; i++) {
char *uri = jk_pool_strdup(&uw_map->p, map_name_at(init_data, i));
char *worker = jk_pool_strdup(&uw_map->p, map_value_at(init_data, i));
if(!uri || ! worker) {
jk_log(l, JK_LOG_ERROR,
"jk_uri_worker_map_t::uri_worker_map_open, malloc failed\n");
break;
}
if('/' == uri[0]) {
char *asterisk = strchr(uri, '*');
if(asterisk) {
uw_map->maps[j].uri = jk_pool_strdup(&uw_map->p, uri);
if(!uw_map->maps[j].uri) {
jk_log(l, JK_LOG_ERROR,
"jk_uri_worker_map_t::uri_worker_map_open, malloc failed\n");
break;
}
/*
* Now, lets check that the pattern is /context/*.suffix
* or /context/*
* we need to have a '/' then a '*' and the a '.' or a
* '/' then a '*'
*/
asterisk--;
if('/' == asterisk[0]) {
if('.' == asterisk[2]) {
/* suffix rule */
asterisk[1] = asterisk[2] = '\0';
uw_map->maps[j].worker_name = worker;
uw_map->maps[j].context = uri;
uw_map->maps[j].suffix = asterisk + 3;
uw_map->maps[j].match_type = MATCH_TYPE_SUFFIX;
jk_log(l, JK_LOG_DEBUG,
"Into jk_uri_worker_map_t::uri_worker_map_open, suffix rule %s.%s=%s was added\n",
uri, asterisk + 3, worker);
j++;
} else {
/* context based */
asterisk[1] = '\0';
uw_map->maps[j].worker_name = worker;
uw_map->maps[j].context = uri;
uw_map->maps[j].suffix = NULL;
uw_map->maps[j].match_type = MATCH_TYPE_CONTEXT;
jk_log(l, JK_LOG_DEBUG,
"Into jk_uri_worker_map_t::uri_worker_map_open, match rule %s=%s was added\n",
uri, worker);
j++;
}
} else {
/* not leagal !!! */
jk_log(l, JK_LOG_ERROR,
"jk_uri_worker_map_t::uri_worker_map_open, [%s=%s] not a leagal rule\n",
uri, worker);
continue;
}
} else {
uw_map->maps[j].uri = uri;
uw_map->maps[j].worker_name = worker;
uw_map->maps[j].context = uri;
uw_map->maps[j].suffix = NULL;
uw_map->maps[j].match_type = MATCH_TYPE_EXACT;
jk_log(l, JK_LOG_DEBUG,
"Into jk_uri_worker_map_t::uri_worker_map_open, exact rule %s=%s was added\n",
uri, worker);
j++;
}
uw_map->maps[j - 1].ctxt_len = strlen(uw_map->maps[j - 1].context);
}
}
if(i == sz) {
jk_log(l, JK_LOG_DEBUG, "Into jk_uri_worker_map_t::uri_worker_map_open, there are %d rules\n", j);
uw_map->size = j;
} else {
jk_log(l, JK_LOG_ERROR,
"jk_uri_worker_map_t::uri_worker_map_open, There was a parsing error\n");
rc = JK_FALSE;
}
} else {
jk_log(l, JK_LOG_ERROR,
"jk_uri_worker_map_t::uri_worker_map_open, malloc failed\n");
rc = JK_FALSE;
}
}
if(!rc) {
jk_close_pool(&uw_map->p);
}
}
jk_log(l, JK_LOG_DEBUG,
"jk_uri_worker_map_t::uri_worker_map_open, done\n");
return rc;
}
int uri_worker_map_close(jk_uri_worker_map_t *uw_map,
jk_logger_t *l)
{
jk_log(l, JK_LOG_DEBUG,
"Into jk_uri_worker_map_t::uri_worker_map_close\n");
if(uw_map) {
jk_close_pool(&uw_map->p);
return JK_TRUE;
}
jk_log(l, JK_LOG_ERROR,
"jk_uri_worker_map_t::uri_worker_map_close, NULL parameter\n");
return JK_FALSE;
}
char *map_uri_to_worker(jk_uri_worker_map_t *uw_map,
const char *uri,
jk_logger_t *l)
{
jk_log(l, JK_LOG_DEBUG,
"Into jk_uri_worker_map_t::map_uri_to_worker\n");
if(uw_map && uri && '/' == uri[0]) {
unsigned i;
unsigned best_match = -1;
unsigned longest_match = 0;
char clean_uri[4096];
char *url_rewrite = strstr(uri, JK_PATH_SESSION_IDENTIFIER);
if(url_rewrite) {
strcpy(clean_uri, uri);
url_rewrite = strstr(clean_uri, JK_PATH_SESSION_IDENTIFIER);
*url_rewrite = '\0';
uri = clean_uri;
}
jk_log(l, JK_LOG_DEBUG, "Attempting to map URI %s\n", uri);
for(i = 0 ; i < uw_map->size ; i++) {
if(uw_map->maps[i].ctxt_len < longest_match) {
continue; /* can not be a best match anyway */
}
if(0 == strncmp(uw_map->maps[i].context,
uri,
uw_map->maps[i].ctxt_len)) {
if(MATCH_TYPE_EXACT == uw_map->maps[i].match_type) {
if(strlen(uri) == uw_map->maps[i].ctxt_len) {
jk_log(l,
JK_LOG_DEBUG,
"jk_uri_worker_map_t::map_uri_to_worker, Found an exact match %s ->%s\n",
uw_map->maps[i].worker_name,
uw_map->maps[i].context );
return uw_map->maps[i].worker_name;
}
} else if(MATCH_TYPE_CONTEXT == uw_map->maps[i].match_type) {
if(uw_map->maps[i].ctxt_len > longest_match) {
jk_log(l,
JK_LOG_DEBUG,
"jk_uri_worker_map_t::map_uri_to_worker, Found a context match %s -> %s\n",
uw_map->maps[i].worker_name,
uw_map->maps[i].context );
longest_match = uw_map->maps[i].ctxt_len;
best_match = i;
}
} else /* suffix match */ {
int suffix_start;
for(suffix_start = strlen(uri) - 1 ;
suffix_start > 0 && '.' != uri[suffix_start];
suffix_start--)
;
if('.' == uri[suffix_start]) {
const char *suffix = uri + suffix_start + 1;
/* for WinXX, fix the JsP != jsp problems */
#ifdef WIN32
if(0 == strcasecmp(suffix, uw_map->maps[i].suffix)) {
#else
if(0 == strcmp(suffix, uw_map->maps[i].suffix)) {
#endif
if(uw_map->maps[i].ctxt_len >= longest_match) {
jk_log(l,
JK_LOG_DEBUG,
"jk_uri_worker_map_t::map_uri_to_worker, Found a suffix match %s -> *.%s\n",
uw_map->maps[i].worker_name,
uw_map->maps[i].suffix );
longest_match = uw_map->maps[i].ctxt_len;
best_match = i;
}
}
}
}
}
}
if(-1 != best_match) {
return uw_map->maps[best_match].worker_name;
} else {
/*
* We are now in a security nightmare, it maybe that somebody sent
* us a uri that looks like /top-secret.jsp. and the web server will
* fumble and return the jsp content.
*
* To solve that we will check for path info following the suffix, we
* will also check that the end of the uri is not .suffix.
*/
int fraud = check_security_fraud(uw_map, uri, l);
if(fraud >= 0) {
jk_log(l, JK_LOG_EMERG,
"In jk_uri_worker_map_t::map_uri_to_worker, found a security fraud in [%s]\n",
uri);
return uw_map->maps[fraud].worker_name;
}
}
} else {
jk_log(l, JK_LOG_ERROR,
"In jk_uri_worker_map_t::map_uri_to_worker, wrong parameters\n");
}
jk_log(l, JK_LOG_DEBUG,
"jk_uri_worker_map_t::map_uri_to_worker, done without a match\n");
return NULL;
}
1.1 jakarta-tomcat/proposals/web-connector/native/common/jk_uri_worker_map.h
Index: jk_uri_worker_map.h
===================================================================
/*
* Copyright (c) 1997-1999 The Java Apache Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Java Apache
* Project for use in the Apache JServ servlet engine project
* <http://java.apache.org/>."
*
* 4. The names "Apache JServ", "Apache JServ Servlet Engine" and
* "Java Apache Project" must not be used to endorse or promote products
* derived from this software without prior written permission.
*
* 5. Products derived from this software may not be called "Apache JServ"
* nor may "Apache" nor "Apache JServ" appear in their names without
* prior written permission of the Java Apache Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Java Apache
* Project for use in the Apache JServ servlet engine project
* <http://java.apache.org/>."
*
* THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "AS IS" AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JAVA APACHE PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Java Apache Group. For more information
* on the Java Apache Project and the Apache JServ Servlet Engine project,
* please see <http://java.apache.org/>.
*
*/
/***************************************************************************
* Description: URI to worker mapper header file *
* Author: Gal Shachor <sh...@il.ibm.com> *
* Version: $Revision: 1.1 $ *
***************************************************************************/
#ifndef JK_URI_WORKER_MAP_H
#define JK_URI_WORKER_MAP_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include "jk_global.h"
#include "jk_map.h"
#include "jk_logger.h"
struct jk_uri_worker_map;
typedef struct jk_uri_worker_map jk_uri_worker_map_t;
int uri_worker_map_alloc(jk_uri_worker_map_t **uw_map,
jk_map_t *init_data,
jk_logger_t *l);
int uri_worker_map_free(jk_uri_worker_map_t **uw_map,
jk_logger_t *l);
int uri_worker_map_open(jk_uri_worker_map_t *uw_map,
jk_map_t *init_data,
jk_logger_t *l);
int uri_worker_map_close(jk_uri_worker_map_t *uw_map,
jk_logger_t *l);
char *map_uri_to_worker(jk_uri_worker_map_t *uw_map,
const char *uri,
jk_logger_t *l);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* JK_URI_WORKER_MAP_H */