Hi, Some intro:
Here is the result of the previous discussions regarding using regular expressions for uri mappings. I didn't change or enable the conditional build (need some ideas how or why to do that), although this was the +1 case, so I didn't commit nothing, and will be pleased if someone can spare some time to test this (on unix preferably). The reason for using pcre was simple (?). It is well tested library, and our uri mapping code is basically tries to be something like that on the lower scale, not to mention the increased power. How to compile: 1. replace the provided files 2. copy the pcre dir from apache2/srclib to the j-t-c/jk/native2 3. add the pcre to the include path 4. build pcre 5. add the pcre.lib and pcreposix.lib to the mod_jk2 Win users can simply include the dftables.dsp, pcre.dsp, pcreposix.dsp to the project, and add the reference to the pcre and pcreposix. How to use: It's very simple :-), use the regular expressions! This is the same: [uri:/examples] info=Example webapp in the default context. context=/examples debug=0 Instead of /* use the \w* (meaning) zero or more 'word' characters. [uri:/examples/\w*] info=Map the whole webapp Here lies the real power! [uri:/examples/(?!\w*\.(gif|jpg)$)] info=Map the whole webapp except *.gif and *.jpg files [uri:/\w+\.jsp$] info=Map the extension MT.
/* ========================================================================= * * * * The Apache Software License, Version 1.1 * * * * Copyright (c) 1999-2001 The Apache Software Foundation. * * All rights reserved. * * * * ========================================================================= * * * * Redistribution and use in source and binary forms, with or without modi- * * fication, are permitted provided that the following conditions are met: * * * * 1. Redistributions of source code must retain the above copyright notice * * 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. The end-user documentation included with the redistribution, if any, * * must include the following acknowlegement: * * * * "This product includes software developed by the Apache Software * * Foundation <http://www.apache.org/>." * * * * Alternately, this acknowlegement may appear in the software itself, if * * and wherever such third-party acknowlegements normally appear. * * * * 4. The names "The Jakarta Project", "Jk", and "Apache Software * * Foundation" must not be used to endorse or promote products derived * * from this software without prior written permission. For written * * permission, please contact <[EMAIL PROTECTED]>. * * * * 5. Products derived from this software may not be called "Apache" nor may * * "Apache" appear in their names without prior written permission of the * * Apache Software Foundation. * * * * THIS SOFTWARE IS PROVIDED "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 APACHE SOFTWARE FOUNDATION 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 indivi- * * duals on behalf of the Apache Software Foundation. For more information * * on the Apache Software Foundation, please see <http://www.apache.org/>. * * * * ========================================================================= */ /** * URI enviroment. All properties associated with a particular URI will be * stored here. This coresponds to a per_dir structure in Apache. * * Replaces uri_worker_map, etc. * * Author: Costin Manolache */ #ifndef JK_URIENV_H #define JK_URIENV_H #include "jk_logger.h" #include "jk_endpoint.h" #include "jk_worker.h" #include "jk_map.h" #include "jk_uriMap.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ struct jk_worker; struct jk_endpoint; struct jk_env; struct jk_uri_worker_map; struct jk_map; struct jk_webapp; struct jk_uriEnv; typedef struct jk_uriEnv jk_uriEnv_t; /* Standard exact mapping */ #define MATCH_TYPE_EXACT (0) /* Standard prefix mapping */ #define MATCH_TYPE_PREFIX (1) /* Standard suffix mapping ( *.jsp ) */ #define MATCH_TYPE_SUFFIX (2) /* Special: match all URIs of the form *ext */ #define MATCH_TYPE_GENERAL_SUFFIX (3) /* Special: match all context path URIs with a path component suffix */ #define MATCH_TYPE_CONTEXT_PATH (4) /* The uriEnv corresponds to a virtual host */ #define MATCH_TYPE_HOST (5) /* Top level context mapping. WEB-INF and META-INF will be checked, and the information will be passed to tomcat */ #define MATCH_TYPE_CONTEXT (6) struct jk_uriEnv { struct jk_bean *mbean; struct jk_pool *pool; struct jk_workerEnv *workerEnv; struct jk_uriMap *uriMap; /* Generic name/value properties. */ struct jk_map *properties; /* -------------------- Properties extracted from the URI name ---------- */ /** Full name */ char *name; /* Virtual server handled - NULL means 'global' ( visible in all * virtual servers ). Part of the uri name. */ char *virtual; /* Original uri ( unparsed ). Part of the uri name. */ char *uri; /* -------------------- Properties set using setAttribute ---------- */ /** ContextPath. Set with 'context' attribute. */ char *contextPath; int ctxt_len; /** ServletName. Set with 'servlet' attribute. */ char *servlet; int servletId; /** Group, set with 'group' attribute. Defaults to 'lb'. */ char *workerName; struct jk_worker *worker; /** For MATCH_TYPE_HOST, the list of aliases for the virtual host. * Set using (multi-value ) 'alias' attribute on vhost uris. */ struct jk_map *aliases; /* If set we'll use apr_time to get the request time in microseconds and update the scoreboard to reflect that. */ int timing; /* Regular Expression structure */ void *regexp; int uri_len; int match_type; /** For MATCH_TYPE_HOST, the list of webapps in that host */ struct jk_map *webapps; /** For MATCH_TYPE_CONTEXT, the list of local mappings */ struct jk_map *exactMatch; /** For MATCH_TYPE_CONTEXT, the config used to read properties for that context. For MATCH_TYPE_HOST, the config used to read contexts For MATCH_TYPE_HOST/default it also contains all vhosts If NULL - no config was attached. ( this will be used in future for run-time deployment ) */ struct jk_config *config; /* -------------------- Other properties -------------------- */ /** Different apps can have different loggers. */ struct jk_logger *l; /* Environment variables support */ int envvars_in_use; struct jk_map *envvars; int merged; /* Reverse mappings */ int reverse; /** XXX . */ /* int status; */ /* int virtualPort; */ /* -------------------- Methods -------------------- */ int (*init)( struct jk_env *env, struct jk_uriEnv *_this); }; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* JK_URIENV_H */
/* ========================================================================= * * * * The Apache Software License, Version 1.1 * * * * Copyright (c) 1999-2002 The Apache Software Foundation. * * All rights reserved. * * * * ========================================================================= * * * * Redistribution and use in source and binary forms, with or without modi- * * fication, are permitted provided that the following conditions are met: * * * * 1. Redistributions of source code must retain the above copyright notice * * 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. The end-user documentation included with the redistribution, if any, * * must include the following acknowlegement: * * * * "This product includes software developed by the Apache Software * * Foundation <http://www.apache.org/>." * * * * Alternately, this acknowlegement may appear in the software itself, if * * and wherever such third-party acknowlegements normally appear. * * * * 4. The names "The Jakarta Project", "Jk", and "Apache Software * * Foundation" must not be used to endorse or promote products derived * * from this software without prior written permission. For written * * permission, please contact <[EMAIL PROTECTED]>. * * * * 5. Products derived from this software may not be called "Apache" nor may * * "Apache" appear in their names without prior written permission of the * * Apache Software Foundation. * * * * THIS SOFTWARE IS PROVIDED "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 APACHE SOFTWARE FOUNDATION 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 indivi- * * duals on behalf of the Apache Software Foundation. For more information * * on the Apache Software Foundation, please see <http://www.apache.org/>. * * * * ========================================================================= */ /** * Description: URI to worker map object. * Maps can be * * Exact Context -> /exact/uri=worker e.g. /examples/do[STAR]=ajp12 * Context Based -> /context/[STAR]=worker e.g. /examples/[STAR]=ajp12 * Context and suffix ->/context/[STAR].suffix=worker e.g. /examples/[STAR].jsp=ajp12 * * This lets us either partition the work among the web server and the * servlet container. * * @author: Gal Shachor <[EMAIL PROTECTED]> * @author: Costin Manolache * @author: Mladen Turk */ #include "jk_pool.h" #include "jk_env.h" #include "jk_uriMap.h" #include "jk_registry.h" #include "apr_lib.h" #include "apr_pools.h" #include "apr_strings.h" #include "pcreposix.h" static jk_uriEnv_t *jk2_uriMap_mapUri(jk_env_t *env, jk_uriMap_t *uriMap, const char *vhost, const char *uri); /* * Was: check_security_fraud */ static int jk2_uriMap_checkUri(jk_env_t *env, jk_uriMap_t *uriMap, const char *uri) { /* Use the apr_uri */ return JK_OK; } /** Add a uri mapping. Called during uri: initialization. Will just copy the uri in the table ( XXX use a map keyed on name ). In init() we process this and set the right structures. */ static int jk2_uriMap_addUriEnv( jk_env_t *env, jk_uriMap_t *uriMap, jk_uriEnv_t *uriEnv ) { uriMap->maps->put(env, uriMap->maps, uriEnv->name, uriEnv, NULL); if (uriMap->mbean->debug > 0) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "uriMap.addUriEnv() %s %s %s\n", uriEnv->name, uriEnv->virtual, uriEnv->uri); return JK_OK; } static int JK_METHOD jk2_uriMap_setProperty(jk_env_t *env, jk_bean_t *mbean, char *name, void *valueP) { jk_uriMap_t *uriMap = mbean->object; char *value = valueP; return JK_OK; } static jk_uriEnv_t *jk2_uriMap_findMap(jk_env_t *env, jk_uriMap_t *uriMap, jk_map_t *mapTable, const char *uri, int uriLen) { int i; int sz = mapTable->size(env, mapTable); for (i = 0; i < sz; i++) { jk_uriEnv_t *uwr=mapTable->valueAt(env, mapTable, i); if (uwr->regexp) { regex_t *r = (regex_t *)uwr->regexp; regmatch_t regm[10]; if (!regexec(r, uri, r->re_nsub + 1, regm, 0)) { return uwr; } } else { if (uriLen != uwr->uri_len) continue; if (strncmp(uri, uwr->uri, uwr->uri_len) == 0) { return uwr; } } } return NULL; } static jk_uriEnv_t *jk2_uriMap_prefixMap(jk_env_t *env, jk_uriMap_t *uriMap, jk_map_t *mapTable, const char *uri, int uriLen) { int best_match = 0; jk_uriEnv_t *match = NULL; int i; int sz = mapTable->size(env, mapTable); for (i = 0; i < sz; i++) { jk_uriEnv_t *uwr = mapTable->valueAt(env, mapTable, i); if (uriLen < uwr->uri_len) continue; if (strncmp(uri, uwr->uri, uwr->uri_len) == 0) { if (uwr->uri_len > best_match) { best_match = uwr->uri_len; match = uwr; } } } return match; } /* Find the vhost */ static jk_uriEnv_t *jk2_uriMap_hostMap(jk_env_t *env, jk_uriMap_t *uriMap, const char *vhost) { int i; if( vhost != NULL) { int sz = uriMap->vhosts->size(env, uriMap->vhosts); for (i = 0; i < sz; i++) { char *name = uriMap->vhosts->nameAt(env, uriMap->vhosts, i); /* Host name is not case sensitive */ if (strcasecmp(name, vhost) == 0) { return uriMap->vhosts->valueAt(env, uriMap->vhosts, i); } } /* Can't find vhost, return default */ } return uriMap->defaultVhost; } static int jk2_uriMap_init(jk_env_t *env, jk_uriMap_t *uriMap) { int rc = JK_OK; int i; jk_workerEnv_t *workerEnv = uriMap->workerEnv; jk_bean_t *mbean; jk_uriEnv_t *uriEnv; mbean=env->getBean2(env, "uri", ""); if (mbean==NULL ) mbean = env->createBean2(env, workerEnv->pool,"uri", ""); if (mbean == NULL || mbean->object == NULL ) { env->l->jkLog(env, env->l, JK_LOG_ERROR, "uriMap.factory() Fail to create default host\n"); return JK_ERR; } uriMap->defaultVhost = mbean->object; if (uriMap->mbean->debug > 5) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "uriMap.init() set default host\n"); /* Initialize the vhosts table */ for (i = 0; i < uriMap->maps->size(env, uriMap->maps ); i++) { uriEnv = uriMap->maps->valueAt(env, uriMap->maps, i); if (uriEnv == NULL) continue; if (uriEnv->match_type == MATCH_TYPE_HOST ) { jk2_map_default_create(env, &uriEnv->webapps, uriMap->pool); if (uriEnv->virtual != NULL) { uriMap->vhosts->put(env, uriMap->vhosts, uriEnv->virtual, uriEnv, NULL); } if (uriMap->mbean->debug > 5) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "uriMap.init() loaded host %s\n",uriEnv->virtual); } } /* Add the vhost aliases ( for each vhost, by looking in the aliases ) */ for (i = 0; i < uriMap->maps->size(env, uriMap->maps); i++) { uriEnv=uriMap->maps->valueAt( env, uriMap->maps, i ); if (uriEnv->match_type == MATCH_TYPE_HOST && uriEnv->virtual != NULL) { /* XXX TODO */ } } /** Make sure each vhost has a default context */ for (i = 0; i < uriMap->vhosts->size(env, uriMap->vhosts); i++) { jk_uriEnv_t *hostEnv = uriMap->vhosts->valueAt(env, uriMap->vhosts, i); jk_uriEnv_t *rootCtx; char *uriPath; if (hostEnv->virtual != NULL) { uriPath=env->tmpPool->calloc(env, env->tmpPool, strlen(hostEnv->virtual) + 3); strcpy(uriPath, hostEnv->virtual); strcat(uriPath, "/"); } else { uriPath="/"; } rootCtx = env->getByName2(env, "uri", uriPath); if (rootCtx == NULL) { env->createBean2(env, uriMap->mbean->pool, "uri", uriPath); rootCtx=env->getByName2(env, "uri", uriPath); if (uriMap->mbean->debug > 0) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "uriMap.init() Create default context %s\n", uriPath); rootCtx->mbean->setAttribute(env, rootCtx->mbean, "context", "/"); } } uriEnv=env->getByName2(env, "uri", "/"); if (uriEnv == NULL) { env->createBean2(env, uriMap->mbean->pool, "uri", "/"); uriEnv=env->getByName2(env, "uri", "/"); if (uriMap->mbean->debug > 0) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "uriMap.init() Create default context / ( for default host )\n" ); uriEnv->mbean->setAttribute(env, uriEnv->mbean, "context", "/"); } /* Init all contexts */ /* For each context, init the local uri maps */ for (i = 0; i < uriMap->maps->size(env, uriMap->maps); i++) { jk_uriEnv_t *uriEnv = uriMap->maps->valueAt(env, uriMap->maps, i); char *uri; char *context; if (uriEnv == NULL ) { env->l->jkLog(env, env->l, JK_LOG_INFO, "uriMap.init() NPE\n"); } uri = uriEnv->uri; context = uriEnv->contextPath; if (uri != NULL && context != NULL && strcmp(uri, context) == 0) { char *vhost = uriEnv->virtual; jk_uriEnv_t *hostEnv=jk2_uriMap_hostMap(env, uriMap, vhost); if (uriMap->mbean->debug > 5) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "uriMap.init() loaded context %s %s uri %s %#lx %#lx %#lx\n", uriEnv->virtual, context, uri, hostEnv, hostEnv->webapps, uriMap->pool); uriEnv->uri_len = strlen(context); uriEnv->match_type = MATCH_TYPE_CONTEXT; hostEnv->webapps->put(env, hostEnv->webapps, context, uriEnv, NULL); jk2_map_default_create(env, & uriEnv->exactMatch, uriMap->pool); /* add default mappings for WEB-INF, META-INF, servlet/, .jsp */ } } if (uriMap->mbean->debug > 5) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "uriMap.init() processing mappings\n"); /* All other mappings are added in the right context leaf. XXX We should also sort prefix mappings and maybe use binary search - but it won't have too bigger benefits, the number of mappings per ctx is typically small */ for(i = 0; i < uriMap->maps->size(env, uriMap->maps); i++) { jk_uriEnv_t *uriEnv = uriMap->maps->valueAt(env, uriMap->maps, i); char *vhost= uriEnv->virtual; jk_uriEnv_t *hostEnv = jk2_uriMap_hostMap(env, uriMap, vhost); char *uri = uriEnv->uri; jk_uriEnv_t *ctxEnv; if (uri == NULL) continue; uriEnv->uriMap = uriMap; uriEnv->init(env, uriEnv); if (uriEnv->contextPath) { env->l->jkLog(env, env->l, JK_LOG_INFO, "uriMap.init() finding context %s\n", uriEnv->contextPath); ctxEnv = hostEnv->webapps->get(env, hostEnv->webapps, uriEnv->contextPath); } else { env->l->jkLog(env, env->l, JK_LOG_INFO, "uriMap.init() prefixing context uri %s\n", uri); ctxEnv=jk2_uriMap_prefixMap(env, uriMap, hostEnv->webapps, uri, strlen(uri)); } if (ctxEnv == NULL) { env->l->jkLog(env, env->l, JK_LOG_INFO, "uriMap.init() no context for %s\n", uri); return JK_ERR; } if (uriEnv->match_type == MATCH_TYPE_EXACT) { env->l->jkLog(env, env->l, JK_LOG_DEBUG, "uriMap adding exact %s\n", uri); ctxEnv->exactMatch->add( env, ctxEnv->exactMatch, uri, uriEnv ); } } return rc; } static void jk2_uriMap_destroy(jk_env_t *env, jk_uriMap_t *uriMap) { if (uriMap->mbean->debug > 0) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "uriMap.destroy()\n"); /* this can't be null ( or a NPE would have been generated */ uriMap->pool->close(env, uriMap->pool); } #define SAFE_URI_SIZE 8192 static jk_uriEnv_t *jk2_uriMap_mapUri(jk_env_t *env, jk_uriMap_t *uriMap, const char *vhost, const char *uri) { int best_match = -1; int longest_match = 0; char * clean_uri = NULL; char *url_rewrite = NULL; int uriLen; jk_uriEnv_t *hostEnv; jk_uriEnv_t *ctxEnv; jk_uriEnv_t *match; /* Ugly hack to avoid using non-thread safe code. Modify the uri in place for uri session encoding, then restore it to the original. That works since the processing happens in a single thred. A better solution is to allocate the jk_ws_service and it's pool and pass it as param */ char origChar = '\0'; /* XXX - need to make sure prefix match take precedence over extension match ( now it doesn't ) */ if (uriMap == NULL || uri==NULL) return NULL; if (uriMap->mbean->debug > 1) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "uriMap.mapUri() %s %s\n", vhost, uri); if (uri[0] != '/') { env->l->jkLog(env, env->l, JK_LOG_ERROR, "uriMap.mapUri() uri must start with /\n"); return NULL; } hostEnv = jk2_uriMap_hostMap(env, uriMap, vhost); if (uriMap->mbean->debug > 1) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "uriMap.mapUri() found host %s\n", hostEnv->virtual); url_rewrite = strstr(uri, JK_PATH_SESSION_IDENTIFIER); if (url_rewrite) { origChar = *url_rewrite; *url_rewrite = '\0'; if (uriMap->mbean->debug > 0) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "uriMap.mapUri() rewrote uri %s \n",uri); } uriLen = strlen(uri); /* Map the context */ ctxEnv = jk2_uriMap_prefixMap(env, uriMap, hostEnv->webapps, uri, uriLen); if( ctxEnv == NULL ) { env->l->jkLog(env, env->l, JK_LOG_INFO, "uriMap.mapUri() no context %s\n", uri); return NULL; } if (uriMap->mbean->debug > 1) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "uriMap.mapUri() found ctx %s\n", ctxEnv->uri); /* As per Servlet spec, do exact match first */ match = jk2_uriMap_findMap(env, uriMap, ctxEnv->exactMatch, uri, uriLen); if (match != NULL) { /* restore */ if (url_rewrite) *url_rewrite = origChar; if (uriMap->mbean->debug > 0) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "uriMap.mapUri() exact match %s %s\n", uri, match->workerName ); return match; } /* restore */ if (url_rewrite) *url_rewrite = origChar; if (uriMap->mbean->debug > 1) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "uriMap.mapUri() no match found\n"); return NULL; } int JK_METHOD jk2_uriMap_factory(jk_env_t *env, jk_pool_t *pool, jk_bean_t *result, const char *type, const char *name) { jk_uriMap_t *uriMap; uriMap = (jk_uriMap_t *)pool->calloc(env, pool, sizeof(jk_uriMap_t)); if (!uriMap) { env->l->jkLog(env, env->l, JK_LOG_ERROR, "uriMap.factory() OutOfMemoryError\n"); return JK_ERR; } uriMap->pool = pool; jk2_map_default_create(env, &uriMap->maps, pool); jk2_map_default_create(env, &uriMap->vhosts, pool); uriMap->init = jk2_uriMap_init; uriMap->destroy = jk2_uriMap_destroy; uriMap->addUriEnv = jk2_uriMap_addUriEnv; uriMap->checkUri = jk2_uriMap_checkUri; uriMap->mapUri = jk2_uriMap_mapUri; result->object = uriMap; result->setAttribute = jk2_uriMap_setProperty; uriMap->mbean = result; return JK_OK; }
/* ========================================================================= * * * * The Apache Software License, Version 1.1 * * * * Copyright (c) 1999-2002 The Apache Software Foundation. * * All rights reserved. * * * * ========================================================================= * * * * Redistribution and use in source and binary forms, with or without modi- * * fication, are permitted provided that the following conditions are met: * * * * 1. Redistributions of source code must retain the above copyright notice * * 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. The end-user documentation included with the redistribution, if any, * * must include the following acknowlegement: * * * * "This product includes software developed by the Apache Software * * Foundation <http://www.apache.org/>." * * * * Alternately, this acknowlegement may appear in the software itself, if * * and wherever such third-party acknowlegements normally appear. * * * * 4. The names "The Jakarta Project", "Jk", and "Apache Software * * Foundation" must not be used to endorse or promote products derived * * from this software without prior written permission. For written * * permission, please contact <[EMAIL PROTECTED]>. * * * * 5. Products derived from this software may not be called "Apache" nor may * * "Apache" appear in their names without prior written permission of the * * Apache Software Foundation. * * * * THIS SOFTWARE IS PROVIDED "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 APACHE SOFTWARE FOUNDATION 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 indivi- * * duals on behalf of the Apache Software Foundation. For more information * * on the Apache Software Foundation, please see <http://www.apache.org/>. * * * * ========================================================================= */ /** * Location properties. UriEnv can be: * * Exact Context -> /exact/uri=worker e.g. /examples/do[STAR]=ajp12 * Context Based -> /context/[STAR]=worker e.g. /examples/[STAR]=ajp12 * Context and suffix ->/context/[STAR].suffix=worker e.g. /examplesSTAR].jsp=ajp12 * */ #include "jk_pool.h" #include "jk_env.h" #include "jk_uriMap.h" #include "jk_registry.h" #include "apr_pools.h" #include "apr_strings.h" #include "pcreposix.h" static apr_status_t regex_cleanup(void *preg) { regfree((regex_t *) preg); return APR_SUCCESS; } static regex_t * jk2_pregcomp(jk_pool_t *p, const char *pattern, int cflags) { regex_t *preg = (regex_t *)apr_palloc(p->_private, sizeof(regex_t)); if (regcomp(preg, pattern, cflags)) { return NULL; } apr_pool_cleanup_register(p->_private, (void *) preg, regex_cleanup, regex_cleanup); return preg; } /** Parse the name: VHOST/PATH If VHOST is empty, we map to the default host. The PATH will be further split in CONTEXT/LOCALPATH during init ( after we have all uris, including the context paths ). */ static int jk2_uriEnv_parseName( jk_env_t *env, jk_uriEnv_t *uriEnv, char *name) { char *n; char *slash; if (*name == '!') { uriEnv->reverse = 1; ++name; } n = name; slash=strchr( name, '/' ); /* fprintf( stderr, "XXX parseURI %s\n", name ); */ if( slash==NULL ) { /* That's a virtual host definition ( no actual mapping, just global * settings like aliases, etc */ uriEnv->match_type= MATCH_TYPE_HOST; if( name[0]=='\0' ) { uriEnv->virtual=NULL; /* "" for the default host */ } else { uriEnv->virtual=name; } return JK_OK; } /* If it doesn't start with /, it must have a vhost */ if( *name != '/' ) { /* char *portIdx=strchr( n, ':' ); */ uriEnv->virtual=uriEnv->pool->calloc( env, uriEnv->pool, slash - name + 2 ); strncpy( uriEnv->virtual, name, slash-name ); } n=slash; uriEnv->uri=uriEnv->pool->pstrdup(env, uriEnv->pool, n); return JK_OK; } static void * JK_METHOD jk2_uriEnv_getAttribute(jk_env_t *env, jk_bean_t *bean, char *name ) { jk_uriEnv_t *uriEnv=(jk_uriEnv_t *)bean->object; if( strcmp( name, "host" )==0 ) { return (uriEnv->virtual==NULL) ? "*" : uriEnv->virtual; } else if( strcmp( name, "uri" )==0 ) { return uriEnv->uri; } else if( strcmp( name, "group" )==0 ) { return uriEnv->workerName; } return NULL; } static int JK_METHOD jk2_uriEnv_setAttribute(jk_env_t *env, jk_bean_t *mbean, char *nameParam, void *valueP) { jk_uriEnv_t *uriEnv=mbean->object; char *valueParam=valueP; char *name=uriEnv->pool->pstrdup(env,uriEnv->pool, nameParam); char *val=uriEnv->pool->pstrdup(env,uriEnv->pool, valueParam); uriEnv->properties->add( env ,uriEnv->properties, name, val ); if( strcmp("group", name) == 0 ) { uriEnv->workerName=val; return JK_OK; } else if( strcmp("context", name) == 0 ) { uriEnv->contextPath=val; uriEnv->ctxt_len=strlen( val ); if( strcmp( val, uriEnv->uri ) == 0 ) { uriEnv->match_type= MATCH_TYPE_CONTEXT; } return JK_OK; } else if( strcmp("servlet", name) == 0 ) { uriEnv->servlet=val; } else if( strcmp("timing", name) == 0 ) { uriEnv->timing=atoi( val ); } else if( strcmp("reverse", name) == 0 ) { uriEnv->reverse=atoi( val ); } else if( strcmp("alias", name) == 0 ) { if( uriEnv->match_type == MATCH_TYPE_HOST ) { if( uriEnv->aliases==NULL ) { jk2_map_default_create( env, &uriEnv->aliases, mbean->pool ); } uriEnv->aliases->put( env, uriEnv->aliases, val, uriEnv, NULL ); } /* XXX: Add URI alias ? */ } /* OLD - DEPRECATED */ if( strcmp("worker", name) == 0 ) { uriEnv->workerName=val; } else if( strcmp("path", name) == 0 ) { if( val==NULL ) uriEnv->uri=NULL; else uriEnv->uri=uriEnv->pool->pstrdup(env, uriEnv->pool, val); } if( strcmp("uri", name) == 0 ) { jk2_uriEnv_parseName( env, uriEnv, val); } if( strcmp("name", name) == 0 ) { jk2_uriEnv_parseName( env, uriEnv, val); } if( strcmp("vhost", name) == 0 ) { if( val==NULL ) uriEnv->virtual=NULL; else uriEnv->virtual=uriEnv->pool->pstrdup(env, uriEnv->pool, val); } return JK_OK; } static int jk2_uriEnv_init(jk_env_t *env, jk_uriEnv_t *uriEnv) { char *uri, *wname; uri=uriEnv->pool->pstrdup( env, uriEnv->pool, uriEnv->uri); /* Set the worker */ wname=uriEnv->workerName; if( uriEnv->workerEnv->timing == JK_TRUE ) { uriEnv->timing=JK_TRUE; } if( uriEnv->workerName == NULL ) { /* The default worker */ uriEnv->workerName=uriEnv->uriMap->workerEnv->defaultWorker->mbean->name;; uriEnv->worker=uriEnv->uriMap->workerEnv->defaultWorker; if( uriEnv->mbean->debug > 0 ) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "uriEnv.init() map %s %s\n", uriEnv->uri, uriEnv->uriMap->workerEnv->defaultWorker->mbean->name); } /* No further init - will be called by uriMap.init() */ if( uriEnv->workerName != NULL && uriEnv->worker==NULL ) { uriEnv->worker= env->getByName( env, wname ); if( uriEnv->worker==NULL ) { uriEnv->worker= env->getByName2( env, "lb", wname ); if( uriEnv->worker==NULL ) { env->l->jkLog(env, env->l, JK_LOG_ERROR, "uriEnv.init() map to invalid worker %s %s\n", uriEnv->uri, uriEnv->workerName); /* XXX that's allways a 'lb' worker, create it */ } } } if( uri==NULL ) return JK_ERR; if ('/' != uri[0]) { /* * JFC: please check... * Not sure what to do, but I try to prevent problems. * I have fixed jk_mount_context() in apaches/mod_jk2.c so we should * not arrive here when using Apache. */ env->l->jkLog(env, env->l, JK_LOG_ERROR, "uriEnv.init() context must start with '/' in %s\n", uri); return JK_ERR; } /* Something like: JkMount /login/j_security_check ajp13 */ uriEnv->uri_len = strlen( uriEnv->uri ); if( uriEnv->match_type != MATCH_TYPE_CONTEXT && uriEnv->match_type != MATCH_TYPE_HOST ) { regex_t *r = (regex_t *)jk2_pregcomp(uriEnv->pool, uriEnv->uri, REG_EXTENDED); if (!r) { env->l->jkLog(env, env->l, JK_LOG_ERROR, "uriEnv.init() Regular expression '%s' could not be compiled.\n", uriEnv->uri); return JK_ERR; } env->l->jkLog(env, env->l, JK_LOG_DEBUG, "uriEnv.init() Compiled Regular expression '%s'.\n", uriEnv->uri); uriEnv->regexp = r; uriEnv->match_type = MATCH_TYPE_EXACT; } if( uriEnv->mbean->debug > 0 ) { if( uriEnv->match_type == MATCH_TYPE_CONTEXT ) { env->l->jkLog(env, env->l, JK_LOG_DEBUG, "uriEnv.init() context mapping %s=%s \n", uriEnv->contextPath, uriEnv->workerName); } else if( uriEnv->match_type == MATCH_TYPE_HOST ) { env->l->jkLog(env, env->l, JK_LOG_DEBUG, "uriEnv.init() host mapping %s=%s \n", uriEnv->virtual, uriEnv->workerName); } else { env->l->jkLog(env, env->l, JK_LOG_DEBUG, "uriEnv.init() exact mapping %s=%s \n", uriEnv->uri, uriEnv->workerName); } } if( uriEnv->mbean->debug > 0 ) env->l->jkLog( env, env->l, JK_LOG_DEBUG, "uriEnv.init() %s host=%s uri=%s type=%d ctx=%s\n", uriEnv->mbean->name, uriEnv->virtual, uriEnv->uri, uriEnv->match_type, uriEnv->contextPath); return JK_OK; } static char *myAttInfo[]={ "host", "uri", "group", NULL }; int JK_METHOD jk2_uriEnv_factory(jk_env_t *env, jk_pool_t *pool, jk_bean_t *result, const char *type, const char *name) { jk_pool_t *uriPool; jk_uriEnv_t *uriEnv; uriPool=(jk_pool_t *)pool->create( env, pool, HUGE_POOL_SIZE); uriEnv=(jk_uriEnv_t *)pool->calloc(env, uriPool, sizeof(jk_uriEnv_t)); uriEnv->pool=uriPool; jk2_map_default_create( env, &uriEnv->properties, uriPool ); uriEnv->init=jk2_uriEnv_init; result->setAttribute=jk2_uriEnv_setAttribute; result->getAttribute=jk2_uriEnv_getAttribute; uriEnv->mbean=result; result->object=uriEnv; result->getAttributeInfo=myAttInfo; uriEnv->name=result->localName; jk2_uriEnv_parseName(env, uriEnv, result->localName); uriEnv->workerEnv=env->getByName(env, "workerEnv" ); uriEnv->workerEnv->uriMap->addUriEnv(env, uriEnv->workerEnv->uriMap, uriEnv); uriEnv->uriMap=uriEnv->workerEnv->uriMap; return JK_OK; }
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>