costin 01/12/06 15:04:33 Modified: jk/native2/common jk_uriMap.c Log: Updates, start updating to use jk_webapp. Note that jk_webapp should drasticaly improve the scalability - on a site with many webapps the performance of a global uriMap becomes problematic. jk_webapp will allow a simple partitioning ( of course, using 'native' directives will allways be faster ) Added a (maybe hacky ) fix to the thread-safety problem ( I don't think too many people will be able to see it - it happens only if you use a lot of url rewriting ). The fix should work fine as long as the uri is not processed by multiple threads at the same time ( in which case almost anything can fail ) Revision Changes Path 1.7 +88 -69 jakarta-tomcat-connectors/jk/native2/common/jk_uriMap.c Index: jk_uriMap.c =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native2/common/jk_uriMap.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- jk_uriMap.c 2001/12/05 20:48:20 1.6 +++ jk_uriMap.c 2001/12/06 23:04:33 1.7 @@ -67,14 +67,14 @@ * servlet container. * * Author: Gal Shachor <[EMAIL PROTECTED]> - * Version: $Revision: 1.6 $ + * Version: $Revision: 1.7 $ */ #include "jk_pool.h" #include "jk_env.h" #include "jk_uriMap.h" -int JK_METHOD jk_uriMap_factory( jk_env_t *env, void **result, +int JK_METHOD jk_uriMap_factory( jk_env_t *env, jk_pool_t *pool, void **result, const char *type, const char *name); static int jk_uriMap_init(jk_uriMap_t *_this, @@ -128,8 +128,8 @@ if((('.' == *after_suffix) || ('/' == *after_suffix) || (' ' == *after_suffix)) && - (0 == strncmp(_this->maps[i]->context, uri, - _this->maps[i]->ctxt_len))) { + (0 == strncmp(_this->maps[i]->prefix, uri, + _this->maps[i]->prefix_len))) { /* * Security violation !!! * this is a fraud. @@ -153,11 +153,11 @@ static int uriMap_realloc(jk_uriMap_t *_this) { if (_this->size == _this->capacity) { - jk_uriEnv_t **uwr; + jk_uriEnv_t **uwr=NULL; int capacity = _this->capacity + UW_INC_SIZE; uwr = (jk_uriEnv_t **) - _this->p.alloc(&_this->p, sizeof(jk_uriEnv_t *) * capacity); + _this->pool->alloc(_this->pool, sizeof(jk_uriEnv_t *) * capacity); if (! uwr) return JK_FALSE; @@ -173,12 +173,15 @@ return JK_TRUE; } -static jk_uriEnv_t *jk_uriMap_createUriEnv(jk_uriMap_t *_this ) { - jk_uriEnv_t *uriEnv=(jk_uriEnv_t *)_this->p.alloc(&_this->p, - sizeof(jk_uriEnv_t)); - memset(uriEnv, 0, sizeof(jk_uriEnv_t)); - +static jk_uriEnv_t *jk_uriMap_createUriEnv(jk_uriMap_t *_this, + const char *vhost, const char *uri ) +{ + jk_uriEnv_t *uriEnv=(jk_uriEnv_t *)_this->pool->calloc(_this->pool, + sizeof(jk_uriEnv_t)); uriEnv->workerEnv=_this->workerEnv; + /* XXX search the real webapp + */ + uriEnv->webapp=_this->workerEnv->rootWebapp; return uriEnv; } @@ -202,11 +205,13 @@ return NULL; } - uwr = jk_uriMap_createUriEnv(_this); + uwr = jk_uriMap_createUriEnv(_this,vhost,puri); + + uri = _this->pool->pstrdup(_this->pool, puri); + uwr->uri = _this->pool->pstrdup(_this->pool, uri); - uri = _this->p.pstrdup(&_this->p, puri); - worker = _this->p.pstrdup(&_this->p, pworker); - uwr->workerName = worker; + worker = _this->pool->pstrdup(_this->pool, pworker); + uwr->webapp->workerName = worker; if (uri==NULL || worker==NULL || @@ -238,8 +243,8 @@ // set the mapping type if (!asterisk) { /* Something like: JkMount /login/j_security_check ajp13 */ - uwr->uri = uri; - uwr->context = uri; + uwr->prefix = uri; + uwr->prefix_len =strlen( uwr->prefix ); uwr->suffix = NULL; uwr->match_type = MATCH_TYPE_EXACT; l->jkLog(l, JK_LOG_DEBUG, @@ -248,8 +253,6 @@ return uwr; } - uwr->uri = _this->p.pstrdup(&_this->p, uri); - if (!uwr->uri) { l->jkLog(l, JK_LOG_ERROR,"Allocation error\n"); return NULL; @@ -264,29 +267,32 @@ asterisk--; if ('/' == asterisk[0]) { if ('.' == asterisk[2]) { - /* suffix rule */ + /* suffix rule: /foo/bar/STAR.extension */ asterisk[1] = '\0'; asterisk[2] = '\0'; - uwr->context = uri; + uwr->prefix = uri; + uwr->prefix_len =strlen( uwr->prefix ); uwr->suffix = asterisk + 3; uwr->match_type = MATCH_TYPE_SUFFIX; l->jkLog(l, JK_LOG_DEBUG, "uriMap.addMapping() suffix mapping %s.%s=%s was added\n", uri, asterisk + 3, worker); } else if ('\0' != asterisk[2]) { - /* general suffix rule */ + /* general suffix rule /foo/bar/STARextraData */ asterisk[1] = '\0'; - uwr->context = uri; uwr->suffix = asterisk + 2; + uwr->prefix = uri; + uwr->prefix_len =strlen( uwr->prefix ); uwr->match_type = MATCH_TYPE_GENERAL_SUFFIX; l->jkLog(l, JK_LOG_DEBUG, "uriMap.addMapping() general suffix mapping %s.%s=%s\n", uri, asterisk + 2, worker); } else { - /* context based */ + /* context based /foo/bar/STAR */ asterisk[1] = '\0'; - uwr->context = uri; uwr->suffix = NULL; + uwr->prefix = uri; + uwr->prefix_len =strlen( uwr->prefix ); uwr->match_type = MATCH_TYPE_CONTEXT; l->jkLog(l, JK_LOG_DEBUG, "uriMap.addMapping() context mapping %s=%s\n", @@ -294,17 +300,16 @@ } } else { /* Something like : JkMount /servlets/exampl* ajp13 */ - uwr->uri = uri; - uwr->context = uri; + /* Is this valid ??? */ + uwr->prefix = uri; + uwr->prefix_len =strlen( uwr->prefix ); uwr->suffix = NULL; uwr->match_type = MATCH_TYPE_EXACT; l->jkLog(l, JK_LOG_DEBUG, - "uriMap.addMapping() prefix mapping %s=%s\n", + "uriMap.addMapping() XXX prefix mapping %s=%s\n", uri, worker); } - uwr->ctxt_len = strlen(uwr->context); - return uwr; } @@ -344,10 +349,10 @@ /* Set uriEnv->worker ( can't be done earlier since we might not have the workers set up */ for(i = 0 ; i < _this->size ; i++) { - char *wname=_this->maps[i]->workerName; + char *wname=_this->maps[i]->webapp->workerName; /* assert( wname != NULL ); */ - _this->maps[i]->worker= workerEnv->getWorkerForName( workerEnv, wname ); - if( _this->maps[i]->worker==NULL ) { + _this->maps[i]->webapp->worker= workerEnv->getWorkerForName( workerEnv, wname ); + if( _this->maps[i]->webapp->worker==NULL ) { l->jkLog(l, JK_LOG_ERROR, "Map to invalid worker %s %s\n", _this->maps[i]->uri, wname); } @@ -365,8 +370,7 @@ /* this can't be null ( or a NPE would have been generated */ - _this->p.close(&_this->p); - _this->tp.close(&_this->tp); + _this->pool->close(_this->pool); } @@ -407,6 +411,8 @@ return suffix; } +#define SAFE_URI_SIZE 8192 + static jk_uriEnv_t *jk_uriMap_mapUri(jk_uriMap_t *_this, const char *vhost, const char *uri ) @@ -415,9 +421,18 @@ int best_match = -1; int longest_match = 0; char * clean_uri = NULL; - char *url_rewrite; + char *url_rewrite=NULL; const char *suffix; + int uriLen; jk_logger_t *l=_this->workerEnv->l; + + /* 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 ) */ @@ -439,53 +454,56 @@ url_rewrite = strstr(uri, JK_PATH_SESSION_IDENTIFIER); if(url_rewrite) { - /* XXXXXXXXXX NOT THREAD SAFE ! ???? XXXXXX */ - _this->tp.reset(&_this->tp); - clean_uri = _this->tp.pstrdup(&_this->tp,uri); - url_rewrite = strstr(clean_uri, JK_PATH_SESSION_IDENTIFIER); + origChar=*url_rewrite; *url_rewrite = '\0'; if( _this->debug > 0 ) - l->jkLog(l, JK_LOG_DEBUG, "uriMap.mapUri() rewrote uri %s %s\n", - uri, clean_uri ); - uri = clean_uri; + l->jkLog(l, JK_LOG_DEBUG, "uriMap.mapUri() rewrote uri %s \n",uri ); } + uriLen=strlen( uri ); + /* Only once, no need to compute it for each extension match */ suffix=findExtension( uri ); for(i = 0 ; i < _this->size ; i++) { jk_uriEnv_t *uwr = _this->maps[i]; - if(uwr->ctxt_len < longest_match) { + if(uwr->prefix_len < longest_match) { + /* This will also eliminate extension matches if + a prefix match was already found */ continue; /* can not be a best match anyway */ } - if(0 != strncmp(uwr->context, uri, uwr->ctxt_len)) + if(0 != strncmp(uwr->prefix, uri, uwr->prefix_len)) continue; + + /* The prefix matches */ - if(MATCH_TYPE_EXACT == uwr->match_type) { - if(strlen(uri) == uwr->ctxt_len) { - l->jkLog(l, JK_LOG_DEBUG, - "uriMap.mapUri() exact match %s:%s \n", - uwr->worker->name, uwr->context ); - return uwr; - } + if(MATCH_TYPE_EXACT == uwr->match_type && + uriLen == uwr->prefix_len) { + l->jkLog(l, JK_LOG_DEBUG, + "uriMap.mapUri() exact match %s:%s \n", + uwr->webapp->worker->name, uwr->prefix ); + /* restore */ + if( url_rewrite ) *url_rewrite=origChar; + return uwr; } else if(MATCH_TYPE_CONTEXT == uwr->match_type) { - if(uwr->ctxt_len > longest_match) { + if(uwr->prefix_len > longest_match) { + /* This takes care of 'shorter' matches */ l->jkLog(l, JK_LOG_DEBUG, "uriMap.mapUri() tentative prefix match %s", - uwr->context ); - longest_match = uwr->ctxt_len; + uwr->prefix ); + longest_match = uwr->prefix_len; best_match = i; } } else if(MATCH_TYPE_GENERAL_SUFFIX == uwr->match_type) { - int suffix_start=last_index_of(uri,uwr->suffix[0]); - if (suffix_start>=0 && 0==strcmp(uri+suffix_start,uwr->suffix)) { - if(uwr->ctxt_len >= longest_match) { + if(uwr->prefix_len >= longest_match) { + int suffix_start=last_index_of(uri,uwr->suffix[0]); + if (suffix_start>=0 && 0==strcmp(uri+suffix_start,uwr->suffix)) { l->jkLog(l, JK_LOG_DEBUG, - "uriMap.mapUri() general suffix match %s\n", - uwr->suffix ); - longest_match = uwr->ctxt_len; + "uriMap.mapUri() general suffix match %s\n", + uwr->suffix ); + longest_match = uwr->prefix_len; best_match = i; } } @@ -497,11 +515,11 @@ #else if(0 == strcmp(suffix, uwr->suffix)) { #endif - if(uwr->ctxt_len >= longest_match) { + if(uwr->prefix_len >= longest_match) { l->jkLog(l,JK_LOG_DEBUG, "uriMap.mapUri() suffix match %s\n", uwr->suffix ); - longest_match = uwr->ctxt_len; + longest_match = uwr->prefix_len; best_match = i; } /* indentation trick */ @@ -514,10 +532,14 @@ } } + /* restore */ + if( url_rewrite ) + *url_rewrite=origChar; + if(-1 != best_match) { if( _this->debug > 0 ) l->jkLog(l, JK_LOG_DEBUG, "uriMap.mapUri() matched %s %s\n", - uri, _this->maps[best_match]->worker->name ); + uri, _this->maps[best_match]->webapp->worker->name ); return _this->maps[best_match]; } @@ -527,7 +549,7 @@ return NULL; } -int JK_METHOD jk_uriMap_factory( jk_env_t *env, void **result, +int JK_METHOD jk_uriMap_factory( jk_env_t *env, jk_pool_t *pool, void **result, const char *type, const char *name) { jk_uriMap_t *_this; @@ -538,10 +560,7 @@ _this->size = 0; _this->capacity = 0; - jk_open_pool(&_this->p,_this->buf, - sizeof(jk_pool_atom_t) * SMALL_POOL_SIZE); - jk_open_pool(&_this->tp,_this->tbuf, - sizeof(jk_pool_atom_t) * SMALL_POOL_SIZE); + _this->pool=pool; if( ! _this) { l->jkLog(l, JK_LOG_ERROR, "Allocation error\n");
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>