Bug 18472 - mod_jk2 doesn't handle vhosts correctly when using the JkUriSet commands
Summary: mod_jk2 doesn't handle vhosts correctly when using the JkUriSet commands
Status: RESOLVED WONTFIX
Alias: None
Product: Tomcat Connectors
Classification: Unclassified
Component: Common (show other bugs)
Version: unspecified
Hardware: All All
: P3 major (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
: 18569 26172 (view as bug list)
Depends on:
Blocks:
 
Reported: 2003-03-28 14:55 UTC by David Cassidy
Modified: 2008-10-05 03:13 UTC (History)
3 users (show)



Attachments
diff -u3 to get the vhost JkSetUri stuff working for apache 1.3 (13.27 KB, patch)
2003-04-29 08:08 UTC, David Cassidy
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description David Cassidy 2003-03-28 14:55:09 UTC
When using the JkUriSet commands within a Location block the configuration gets
confused between vhosts.

Example:

<VirtualHost example1.com>
#define remote server
JkSet channel.socket:example1.port 8009
JkSet channel.socket:example1.host server3
JkSet ajp13:example1.channel channel.socket:example1

<Location /examples/>
  JkSetUri group ajp13:example1
</Location>

....
</VirtualHost>

<VirtualHost example2.com>
#define remote server
JkSet channel.socket:example2.port 8500
JkSet channel.socket:example2.host server4
JkSet ajp13:example2.channel channel.socket:example2

<Location /examples/>
  JkSetUri group ajp13:example2
</Location>

....
</VirtualHost>

Assuming that the hosts are specified in the order example1, example2 then all
requests for /examples/ will go to ajp13:example2 .

In mod_jk.c 
static void *jk2_create_dir_config(apr_pool_t *p, char *path)

calls for the given path 

jk_bean_t *jkb=workerEnv->globalEnv->createBean2( 
     workerEnv->globalEnv,
     workerEnv->pool, "uri",
     (path==NULL)? "":path );

createBean2 then checks to see if there is an existing config for the given
path. If it is then the existing config is updated and returned. This means
that the first /examples will be created correctly and when the 2nd config is
encountered createBean2 will return the config for the first /examples. This
will then be updated with the config of the second and so both /examples will 
use the same config.

I suggest (have implemented and tested) the following alteration to fix this
problem.

The create_dir_config sends a unique path name (by adding a numerical suffix)
this will ensure that createBean2 will generate a unique bean for apache to hand
back to jk2_uriSet.

So that jkstatus will make any degree of sense I have updated jk2_uriSet so that
 it re-sets the path back to the original path without the numeric suffix.

Here is the code for apache1.3 as a diff -c against the standard 4.1.21

Please let me know what you think 

David Cassidy

***
../../jakarta-tomcat-connectors-4.1.21-src-ORIG/jk/native2/server/apache13/mod_jk2.c
2003-02-25 16:30:56.000000000 +0000
--- native2/server/apache13/mod_jk2.c	2003-03-27 11:31:59.000000000 +0000
***************
*** 1,3 ****
--- 1,4 ----
+ //  4.1.18 version
  /* ========================================================================= *
   *                                                                           *
   *                 The Apache Software License,  Version 1.1                 *
***************
*** 105,110 ****
--- 106,142 ----
   * config. No good way to discover if it's the first time or not.
   */
  static jk_workerEnv_t *workerEnv;
+ /* This is used to ensure that jk2_create_dir_config creates unique 
+  * dir mappings. This prevents vhost configs as configured through
+  * httpd.conf from getting crossed.
+  */
+ static int dirCounter=0;
+ 
+ /* This gives a slightly better 500 error message than the standard :)
+  */
+ static int jk_error( request_rec *r, char *extras)
+ {
+     // this is a little hack to get around the fact that the lb worker 
+     // might have already sent a page back ....
+     if ( r->bytes_sent > 0 ) 
+ 	    return  OK;
+ 
+     ap_table_setn(r->notes, "error-notes", ap_pstrcat(r->pool,
+         "<p>The mod_jk2 connector was unable handle the request for ",
+         "<em><a href=\"", ap_escape_uri(r->pool, r->uri), "\">",
+         ap_escape_html(r->pool, r->uri), "</a></em></p>\n",
+         "<p>This may mean an application server could not be contacted to "
+         "service this request. ",extras," <P>Please try again later.", NULL));
+ 
+     fprintf(stderr, "Error .... send %d bytes ...\n", r->bytes_sent );
+     /* Allow "error-notes" string to be printed by ap_send_error_response() */
+     ap_table_setn(r->notes, "verbose-error-to", ap_pstrdup(r->pool, "*"));
+ 
+     r->status_line = ap_psprintf(r->pool, "%3.3u mod_jk2 error",
+                                  HTTP_INTERNAL_SERVER_ERROR);
+     return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ 
  
  /* ==================== Options setters ==================== */
  
***************
*** 127,133 ****
          ap_get_module_config(s->module_config, &jk2_module);
      jk_env_t *env=workerEnv->globalEnv;
      int rc;
!     
      rc=workerEnv->config->setPropertyString( env, workerEnv->config, (char
*)name, value );
      if( rc!=JK_OK ) {
          fprintf( stderr, "mod_jk2: Unrecognized option %s %s\n", name, value);
--- 159,165 ----
          ap_get_module_config(s->module_config, &jk2_module);
      jk_env_t *env=workerEnv->globalEnv;
      int rc;
! 
      rc=workerEnv->config->setPropertyString( env, workerEnv->config, (char
*)name, value );
      if( rc!=JK_OK ) {
          fprintf( stderr, "mod_jk2: Unrecognized option %s %s\n", name, value);
***************
*** 136,141 ****
--- 168,311 ----
      return NULL;
  }
  
+ 
+ /**
+  * Set a property associated with a URI, using native <Location> 
+  * directives.
+  *
+  * This is used if you want to use the native mapping and
+  * integrate better into apache.
+  *
+  * Same behavior can be achieved by using uri.properties and/or JkSet.
+  * 
+  * Example:
+  *   <VirtualHost foo.com>
+  *      <Location /examples>
+  *         JkUriSet worker ajp13
+  *      </Location>
+  *   </VirtualHost>
+  *
+  * This is the best way to define a webapplication in apache. It is
+  * scalable ( using apache native optimizations, you can have hundreds
+  * of hosts and thousands of webapplications ), 'natural' to any
+  * apache user.
+  *
+  * XXX This is a special configuration, for most users just use
+  * the properties files.
+  */
+ static const char *jk2_uriSet(cmd_parms *cmd, void *per_dir, 
+                               const char *name, const char *val)
+ {
+     jk_uriEnv_t *uriEnv=(jk_uriEnv_t *)per_dir;
+ 
+ 	char *tmp, *tmp2;
+ 	char *tmp_virtual=NULL, *tmp_full_url=NULL;
+     server_rec *s = cmd->server;
+ 
+     // all of the objects that get passed in now are unique. create_dir adds a
incrementing counter to the 
+     // uri that is used to create the object!
+     // Here we must now 'fix' the content of the object passed in. 
+     // Apache doesn't care what we do here as it has the reference to the
unique object that has been 
+     // created. What we need to do is ensure that the data given to mod_jk2 is
correct. Hopefully in the long run 
+     // we can ignore some of the mod_jk details...
+     
+     // if applicable we will set the hostname etc variables.
+     if ( s->server_hostname != NULL && (uriEnv->virtual==NULL  || !strchr(
uriEnv->virtual, ':') || uriEnv->port != s->port ))
+     {
+ 	tmp_virtual  = (char *) ap_pcalloc(cmd->pool, sizeof(char *) *
(strlen(s->server_hostname) + 8 )) ;
+ 	tmp_full_url = (char *) ap_pcalloc(cmd->pool, sizeof(char *) *
(strlen(s->server_hostname) + strlen(uriEnv->uri)+8 )) ;
+ 	sprintf(tmp_virtual,  "%s:%d", s->server_hostname, s->port);
+ 	sprintf(tmp_full_url, "%s:%d%s", s->server_hostname, s->port, uriEnv->uri );
+ 
+ 	uriEnv->mbean->setAttribute( workerEnv->globalEnv, uriEnv->mbean, "uri",
tmp_full_url);
+ 	uriEnv->mbean->setAttribute( workerEnv->globalEnv, uriEnv->mbean, "path",
cmd->path);
+ 	uriEnv->name=tmp_virtual;
+ 	uriEnv->virtual=tmp_virtual;
+     
+     } 
+     // now lets actually add the parameter set in the <Location> block 
+     uriEnv->mbean->setAttribute( workerEnv->globalEnv, uriEnv->mbean, (char
*)name, (void *)val );
+ 
+     return NULL;
+ }
+ 
+ 
+ static void *jk2_create_dir_config(pool *p, char *path)
+ {
+     /* We don't know the vhost yet - so path is not
+      * unique. We'll have to generate a unique name
+      */
+     char *tmp=NULL;
+     int a=0;
+ 
+     path==NULL?a=10:(a=strlen(path)+10);
+     tmp = (char *) ap_pcalloc(p, sizeof(char *) * (a )   ) ;
+     sprintf(tmp, "%s-%d", path==NULL?"":path, dirCounter++);
+ 
+     // the greatest annoyance here is that we can't create the uri correctly
with the hostname as well.
+     // as apache doesn't give us the hostname .
+     // we'll fix this in JkUriSet
+ 
+     jk_bean_t *jkb=workerEnv->globalEnv->createBean2( workerEnv->globalEnv,
+                                                       workerEnv->pool, "uri",
+                                                       tmp);
+     jk_uriEnv_t *newUri = jkb->object;
+     newUri->workerEnv=workerEnv;
+     newUri->mbean->setAttribute( workerEnv->globalEnv, newUri->mbean, "path",
tmp ); 
+     // I'm hoping that setting the id won't break anything. I havn't noticed
it breaking anything.
+     newUri->mbean->id=(dirCounter -1);
+     // this makes the display in the status display make more sense 
+     newUri->mbean->localName=path;
+ 
+     return newUri;
+ }
+ 
+ /*
+  * Need to re-do this to make more sense - like properly creating a new config
and returning the merged config...
+  * Looks like parent needs to be dominant.
+  */
+ static void *jk2_merge_dir_config(pool *p, void *childv, void *parentv)
+ {
+     jk_uriEnv_t *child =(jk_uriEnv_t *)childv;
+     jk_uriEnv_t *parent = (jk_uriEnv_t *)parentv; 
+     jk_uriEnv_t *winner=NULL;
+ 
+ 
+ /*        fprintf(stderr,"Merging child & parent. (dir)\n");
+ 	fprintf(stderr, "Merging for  vhost child(%s) vhost parent(%s) uri child(%s)
uri parent(%s) child worker (%s) parentworker(%s)\n",
+               (child->virtual==NULL)?"":child->virtual,
+ 	      (parent->virtual==NULL)?"":parent->virtual,
+ 	      (child->uri==NULL)?"":child->uri,
+               (parent->uri==NULL)?"":parent->uri,
+ 	      (child->workerName==NULL)?"":child->workerName,
+ 	      (parent->workerName==NULL)?"":parent->workerName
+ 	      ); */
+ 
+ 
+      if ( child == NULL || child->uri==NULL || child->workerName==NULL )
+ 	     winner=parent;
+      else if ( parent == NULL || parent->uri ==NULL || parent->workerName==NULL )
+ 	     winner=child;
+      // interresting bit... so far they are equal ...
+      else if ( strlen(parent->uri) > strlen(child->uri) )
+ 	     winner=parent;
+      else 
+ 	     winner=child;
+ 
+ /*     if ( winner == child )
+ 	fprintf(stderr, "Going with the child\n");	
+      else if ( winner == parent )
+ 	fprintf(stderr, "Going with the parent\n");	
+      else
+ 	fprintf(stderr, "Going with NULL\n");	 
+ */
+  
+      return (void *) winner;
+ 
+ }
+ 
+ 
+ 
  #ifdef HAS_APR
  apr_pool_t *jk_globalPool;
  #endif
***************
*** 224,257 ****
          */
          { "JkSet", jk2_set2, NULL, RSRC_CONF, TAKE2,
            "Set a jk property, same syntax and rules as in JkWorkersFile" },
!         NULL
      };
  
! /** Create default jk_config.
!     This is the first thing called by apache ( or should be )
   */
  static void *jk2_create_config(ap_pool *p, server_rec *s)
  {
      jk_uriEnv_t *newUri;
      jk_bean_t *jkb;
  
      if(  workerEnv==NULL ) {
          jk2_create_workerEnv(p, s );
      }
      if( s->is_virtual == 1 ) {
          /* Virtual host */
!         fprintf( stderr, "Create config for virtual host\n");
      } else {
          /* Default host */
-         fprintf( stderr, "Create config for main host\n");
-     }
- 
      jkb=workerEnv->globalEnv->createBean2( workerEnv->globalEnv,
                                             workerEnv->pool,
                                             "uri", "" );
      newUri = jkb->object;
      newUri->workerEnv=workerEnv;
!     return newUri;
  }
  
  
--- 394,440 ----
          */
          { "JkSet", jk2_set2, NULL, RSRC_CONF, TAKE2,
            "Set a jk property, same syntax and rules as in JkWorkersFile" },
! 	{ "JkUriSet", jk2_uriSet, NULL, ACCESS_CONF, TAKE2,
!           "Defines a jk property associated with a Location"},
! 	  NULL
      };
  
! /** This makes the config for the specified server_rec s
!     This will include vhost info.
   */
  static void *jk2_create_config(ap_pool *p, server_rec *s)
  {
      jk_uriEnv_t *newUri;
      jk_bean_t *jkb;
+     char *tmp;
  
      if(  workerEnv==NULL ) {
          jk2_create_workerEnv(p, s );
      }
      if( s->is_virtual == 1 ) {
          /* Virtual host */
! 
!     tmp = (char *) ap_pcalloc(p, sizeof(char *) * (strlen(s->server_hostname)
+ 8 )) ;
!     sprintf(tmp, "%s:%d/", s->server_hostname, s->port );
! 
!     // for the sake of consistency we must have the port in the uri.
!     // Really it isn't necessary to have one - but I would like in the future for 
!     // the server config to hold the workers for that server...
!     jkb=workerEnv->globalEnv->createBean2( workerEnv->globalEnv,
!                                            workerEnv->pool,
!                                            "uri",  tmp );
!     // DNC
      } else {
          /* Default host */
      jkb=workerEnv->globalEnv->createBean2( workerEnv->globalEnv,
                                             workerEnv->pool,
                                             "uri", "" );
+     }
+ 
      newUri = jkb->object;
      newUri->workerEnv=workerEnv;
! 
!     return (void *) newUri;
  }
  
  
***************
*** 266,273 ****
      jk_uriEnv_t *base = (jk_uriEnv_t *) basev;
      jk_uriEnv_t *overrides = (jk_uriEnv_t *)overridesv;
      
-     fprintf(stderr,  "Merging workerEnv \n" );
-     
      /* The 'mountcopy' option should be implemented in common.
       */
      return overrides;
--- 449,454 ----
***************
*** 278,285 ****
   */
  static int jk2_init(server_rec *s, ap_pool *pconf)
  {
!     jk_uriEnv_t *serverEnv=(jk_uriEnv_t *)
!         ap_get_module_config(s->module_config, &jk2_module);
      
      jk_env_t *env=workerEnv->globalEnv;
  
--- 459,465 ----
   */
  static int jk2_init(server_rec *s, ap_pool *pconf)
  {
!     jk_uriEnv_t *serverEnv=(jk_uriEnv_t *)
ap_get_module_config(s->module_config, &jk2_module);
      
      jk_env_t *env=workerEnv->globalEnv;
  
***************
*** 329,341 ****
      jk_uriEnv_t *uriEnv;
      jk_env_t *env;
  
-     uriEnv=ap_get_module_config( r->request_config, &jk2_module );
- 
      /* If this is a proxy request, we'll notify an error */
      if(r->proxyreq) {
!         return HTTP_INTERNAL_SERVER_ERROR;
      }
  
      /* not for me, try next handler */
      if(uriEnv==NULL || strcmp(r->handler,JK_HANDLER)!= 0 )
          return DECLINED;
--- 509,527 ----
      jk_uriEnv_t *uriEnv;
      jk_env_t *env;
  
      /* If this is a proxy request, we'll notify an error */
      if(r->proxyreq) {
! 	 return jk_error(r, "<!-- We don't proxy requests. -->");
      }
  
+     // changed from r->request_config to r->per_dir_config. This should give
us the one that was set in 
+     // either the translate phase (if it was a config added through
workers.properties) 
+     // or in the create_dir config.
+     uriEnv=ap_get_module_config( r->request_config, &jk2_module );  // get one
for the dir
+     if ( uriEnv == NULL ) {
+ 	 uriEnv=ap_get_module_config( r->per_dir_config, &jk2_module );  // get one
specific to this request if there isn't a dir one.
+     }
+     
      /* not for me, try next handler */
      if(uriEnv==NULL || strcmp(r->handler,JK_HANDLER)!= 0 )
          return DECLINED;
***************
*** 369,374 ****
--- 555,561 ----
                            "mod_jk.handler() finding worker for %s %#lx %#lx\n",
                            uriEnv->workerName, worker, uriEnv );
              uriEnv->worker=worker;
+ 
          }
      }
  
***************
*** 376,382 ****
          env->l->jkLog(env, env->l, JK_LOG_ERROR, 
                        "mod_jk.handle() No worker for %s\n", r->uri); 
          workerEnv->globalEnv->releaseEnv( workerEnv->globalEnv, env );
!         return 500;
      }
  
      {
--- 563,569 ----
          env->l->jkLog(env, env->l, JK_LOG_ERROR, 
                        "mod_jk.handle() No worker for %s\n", r->uri); 
          workerEnv->globalEnv->releaseEnv( workerEnv->globalEnv, env );
!         return jk_error(r, "<!-- No worker defined for this uri -->");
      }
  
      {
***************
*** 425,433 ****
      }
  
      env->l->jkLog(env, env->l, JK_LOG_ERROR,
!              "mod_jk.handler() Error connecting to tomcat %d\n", rc);
      workerEnv->globalEnv->releaseEnv( workerEnv->globalEnv, env );
!     return 500;
  }
  
  /** Use the internal mod_jk mappings to find if this is a request for
--- 612,621 ----
      }
  
      env->l->jkLog(env, env->l, JK_LOG_ERROR,
!              "mod_jk.handler() Error connecting to tomcat %d %s\n", rc,
worker==NULL?"":worker->channelName==NULL?"":worker->channelName);
      workerEnv->globalEnv->releaseEnv( workerEnv->globalEnv, env );
!     
!     return jk_error(r, "<!-- Is your tomcat server down ? -->");
  }
  
  /** Use the internal mod_jk mappings to find if this is a request for
***************
*** 438,454 ****
      jk_uriEnv_t *uriEnv;
      jk_env_t *env;
              
      if(r->proxyreq) {
          return DECLINED;
      }
      
      /* Check JkMount directives, if any */
  /*     if( workerEnv->uriMap->size == 0 ) */
  /*         return DECLINED; */
      
      /* get_env() */
      env = workerEnv->globalEnv->getEnv( workerEnv->globalEnv );
-         
      uriEnv = workerEnv->uriMap->mapUri(env, workerEnv->uriMap,
                                         ap_get_server_name(r),
                                         ap_get_server_port(r),
--- 626,656 ----
      jk_uriEnv_t *uriEnv;
      jk_env_t *env;
              
+     jk_uriMap_t *uriMap;
+     char *name=NULL;
+     int i,n,io;
      if(r->proxyreq) {
          return DECLINED;
      }
      
+     uriEnv=ap_get_module_config( r->per_dir_config, &jk2_module );
+     if( uriEnv != NULL  &&  uriEnv->workerName!=NULL) {
+         // jk2_handler tries to get the request_config and then falls back to
the per_dir one. 
+ 	// so no point setting the request_config 
+ 	r->handler=JK_HANDLER;
+ 	return OK;
+     }
+ 
+     
+     uriMap= workerEnv->uriMap;
+     n = uriMap->vhosts->size(env, uriMap->vhosts);
+ 
      /* Check JkMount directives, if any */
  /*     if( workerEnv->uriMap->size == 0 ) */
  /*         return DECLINED; */
      
      /* get_env() */
      env = workerEnv->globalEnv->getEnv( workerEnv->globalEnv );
      uriEnv = workerEnv->uriMap->mapUri(env, workerEnv->uriMap,
                                         ap_get_server_name(r),
                                         ap_get_server_port(r),
***************
*** 473,489 ****
  static const handler_rec jk2_handlers[] =
  {
      { JK_MAGIC_TYPE, jk2_handler },
!     { JK_HANDLER, jk2_handler },    
      NULL
  };
  
  module MODULE_VAR_EXPORT jk2_module = {
      STANDARD_MODULE_STUFF,
      jk2_init,             /* module initializer */
!     NULL,                       /* per-directory config creator */
!     NULL,                       /* dir config merger */
      jk2_create_config,           /* server config creator */
!     jk2_merge_config,            /* server config merger */
      jk2_cmds,                    /* command table */
      jk2_handlers,                /* [7] list of handlers */
      jk2_translate,               /* [2] filename-to-URI translation */
--- 675,692 ----
  static const handler_rec jk2_handlers[] =
  {
      { JK_MAGIC_TYPE, jk2_handler },
!     { JK_HANDLER, jk2_handler },
      NULL
  };
  
  module MODULE_VAR_EXPORT jk2_module = {
      STANDARD_MODULE_STUFF,
      jk2_init,             /* module initializer */
!     jk2_create_dir_config,                       /* per-directory config
creator */
!     jk2_merge_dir_config,                       /* dir config merger */
      jk2_create_config,           /* server config creator */
! //    jk2_merge_config,            /* server config merger */
!     NULL,
      jk2_cmds,                    /* command table */
      jk2_handlers,                /* [7] list of handlers */
      jk2_translate,               /* [2] filename-to-URI translation */
Comment 1 David Cassidy 2003-04-02 10:21:22 UTC
here's an apache2 version 
diff -c against the tomcat 4.1.21 release of mod_jk2.c 
to fix the same problems as the apache13 version.
(This sets the virtual host in the /jkstatus page as well as the apache13 version)


***
../../jakarta-tomcat-connectors-4.1.21-src-ORIG/jk/native2/server/apache2/mod_jk2.c
2003-02-25 16:30:56.000000000 +0000
--- native2/server/apache2/mod_jk2.c	2003-03-31 10:25:49.000000000 +0100
***************
*** 77,82 ****
--- 77,88 ----
  static char  file_name[_MAX_PATH];
  #endif
  
+ /* This is used to ensure that jk2_create_dir_config creates unique
+  * dir mappings. This prevents vhost configs as configured through
+  * httpd.conf from getting crossed.
+  */
+ static int dirCounter=0;
+ 
  
  #define JK_HANDLER          ("jakarta-servlet2")
  #define JK_MAGIC_TYPE       ("application/x-jakarta-servlet2")
***************
*** 171,177 ****
      jk_uriEnv_t *uriEnv=(jk_uriEnv_t *)per_dir;
  
      uriEnv->mbean->setAttribute( workerEnv->globalEnv, uriEnv->mbean, (char
*)name, (void *)val );
!     
  /*     fprintf(stderr, "JkUriSet  %s %s dir=%s args=%s\n", */
  /*             uriEnv->workerName, cmd->path, */
  /*             cmd->directive->directive, */
--- 177,211 ----
      jk_uriEnv_t *uriEnv=(jk_uriEnv_t *)per_dir;
  
      uriEnv->mbean->setAttribute( workerEnv->globalEnv, uriEnv->mbean, (char
*)name, (void *)val );
! 
!     char *tmp, *tmp2;
!     char *tmp_virtual=NULL, *tmp_full_url=NULL;
!     server_rec *s = cmd->server;
! 
!     // all of the objects that get passed in now are unique. create_dir adds a
incrementing counter to the
!     // uri that is used to create the object!
!     // Here we must now 'fix' the content of the object passed in.
!     // Apache doesn't care what we do here as it has the reference to the
unique object that has been
!     // created. What we need to do is ensure that the data given to mod_jk2 is
correct. Hopefully in the long run
!     // we can ignore some of the mod_jk details...
! 
!     // if applicable we will set the hostname etc variables.
!     if ( s->server_hostname != NULL && (uriEnv->virtual==NULL  || !strchr(
uriEnv->virtual, ':') || uriEnv->port != s->port ))
!     {
!           tmp_virtual  = (char *) ap_pcalloc(cmd->pool, sizeof(char *) *
(strlen(s->server_hostname) + 8 )) ;
!           tmp_full_url = (char *) ap_pcalloc(cmd->pool, sizeof(char *) *
(strlen(s->server_hostname) + strlen(uriEnv->uri)+8 )) ;
!           sprintf(tmp_virtual,  "%s:%d", s->server_hostname, s->port);
!           sprintf(tmp_full_url, "%s:%d%s", s->server_hostname, s->port,
uriEnv->uri );
! 
!           uriEnv->mbean->setAttribute( workerEnv->globalEnv, uriEnv->mbean,
"uri", tmp_full_url);
!           uriEnv->mbean->setAttribute( workerEnv->globalEnv, uriEnv->mbean,
"path", cmd->path);
!           uriEnv->name=tmp_virtual;
!           uriEnv->virtual=tmp_virtual;
! 
!     }
!     // now lets actually add the parameter set in the <Location> block
!     uriEnv->mbean->setAttribute( workerEnv->globalEnv, uriEnv->mbean, (char
*)name, (void *)val );
! 
  /*     fprintf(stderr, "JkUriSet  %s %s dir=%s args=%s\n", */
  /*             uriEnv->workerName, cmd->path, */
  /*             cmd->directive->directive, */
***************
*** 201,212 ****
      /* We don't know the vhost yet - so path is not
       * unique. We'll have to generate a unique name
       */
      jk_bean_t *jkb=workerEnv->globalEnv->createBean2( workerEnv->globalEnv,
                                                        workerEnv->pool, "uri",
!                                                       (path==NULL)? "":path );
      jk_uriEnv_t *newUri = jkb->object;
      newUri->workerEnv=workerEnv;
!     newUri->mbean->setAttribute( workerEnv->globalEnv, newUri->mbean, "path",
path );
      return newUri;
  }
  
--- 235,258 ----
      /* We don't know the vhost yet - so path is not
       * unique. We'll have to generate a unique name
       */
+    char *tmp=NULL;
+    int a=0;
+ 
+    path==NULL?a=10:(a=strlen(path)+10);
+    tmp = (char *) ap_pcalloc(p, sizeof(char *) * (a )   ) ;
+    sprintf(tmp, "%s-%d", path==NULL?"":path, dirCounter++);
+ 
      jk_bean_t *jkb=workerEnv->globalEnv->createBean2( workerEnv->globalEnv,
                                                        workerEnv->pool, "uri",
!                                                       tmp );
      jk_uriEnv_t *newUri = jkb->object;
      newUri->workerEnv=workerEnv;
!     newUri->mbean->setAttribute( workerEnv->globalEnv, newUri->mbean, "path",
tmp );
!     // I'm hoping that setting the id won't break anything. I havn't noticed
it breaking anything.
!     newUri->mbean->id=(dirCounter -1);
!     // this makes the display in the status display make more sense
!     newUri->mbean->localName=path;
! 
      return newUri;
  }
  
***************
*** 215,260 ****
  {
      jk_uriEnv_t *child =(jk_uriEnv_t *)childv;
      jk_uriEnv_t *parent = (jk_uriEnv_t *)parentv; 
  
!     if( child->uri==NULL )
!         return parentv;
!     
!     if( child->merged != JK_TRUE ) {
!         /* Merge options from parent. 
!          */
!         if( parent->mbean->debug > 0 ) /* Inherit debugging */
!             child->mbean->debug = parent->mbean->debug;
! 
!         if( child->workerName==NULL ) {
!             child->workerName=parent->workerName;
!             child->worker=parent->worker;
!         }
!         if( child->virtual==NULL ) {
!             child->virtual=parent->virtual;
!             child->aliases=parent->aliases;
!         }
!         if( child->contextPath==NULL ) {
!             child->contextPath=parent->contextPath;
!             child->ctxt_len=parent->ctxt_len;
!         }
!         /* XXX Shuld we merge env vars ?
!          */
!         
!         /* When we merged to top - mark and stop duplicating the work
!          */
!         if( parent->uri == NULL ) 
!             child->merged=JK_TRUE;
!     
!         
!         if( child->mbean->debug > -1 ) {
!             fprintf(stderr, "mod_jk2:mergeDirConfig() Merged dir config %#lx
%s %s %s %s\n",
!                     child, child->uri, parent->uri, child->workerName,
parent->workerName);
!             fprintf(stderr, "mod_jk2:mergeDirConfig() Merged dir config %#lx
%s %s %s %s\n",
!                     child, child->uri, parent->uri, child->workerName,
parent->workerName);
!         }
!     }
  
-     return childv;
  }
  
  /** Basic initialization for jk2.
--- 261,288 ----
  {
      jk_uriEnv_t *child =(jk_uriEnv_t *)childv;
      jk_uriEnv_t *parent = (jk_uriEnv_t *)parentv; 
+     jk_uriEnv_t *winner=NULL;
  
!     if ( child == NULL || child->uri==NULL || child->workerName==NULL )
!            winner=parent;
!     else if ( parent == NULL || parent->uri ==NULL || parent->workerName==NULL )
!            winner=child;
!     // interresting bit... so far they are equal ...
!     else if ( strlen(parent->uri) > strlen(child->uri) )
!            winner=parent;
!     else
!            winner=child;
! 
!     /*if ( winner == child )
!          fprintf(stderr, "Going with the child\n");
!       else if ( winner == parent )
!         fprintf(stderr, "Going with the parent\n");
!       else
!         fprintf(stderr, "Going with NULL\n");
!     */
! 
!     return (void *) winner;
  
  }
  
  /** Basic initialization for jk2.

Comment 2 Ignacio J. Ortega 2003-04-02 18:44:35 UTC
*** Bug 18569 has been marked as a duplicate of this bug. ***
Comment 3 Mladen Turk 2003-04-25 09:28:39 UTC
Fixed thanx to David, Costin, and others.
Comment 4 David Cassidy 2003-04-29 08:08:03 UTC
Created attachment 6075 [details]
diff -u3 to get the vhost JkSetUri stuff working for apache 1.3
Comment 5 David Cassidy 2003-04-30 07:47:48 UTC
If we can have the apache 1.3 mod_jk2.c fixed with the attached,

I'd be most grateful we still use apache 1.3 and not 2 :(

Ta
Comment 6 Mladen Turk 2003-05-03 18:12:51 UTC
Commited the latest changes to CVS.
Hopefully it works ;).
Comment 7 Erik Abele 2004-01-19 19:25:24 UTC
*** Bug 26172 has been marked as a duplicate of this bug. ***
Comment 8 Erik Abele 2004-01-19 19:32:08 UTC
*** Bug 26172 has been marked as a duplicate of this bug. ***
Comment 9 Mike Batting 2004-01-19 20:41:20 UTC
I am running the latest build of Tomcat 5 with mod_jk2 version 2.0.2 against 
apache 2.0.48 and am having a related problem listed in bug 26172 (linked to 
this bug).

is there a packaged source or binary bundle that has addressed this issue... 
or do i need to include the source changes listed and rebuild the connector 
myself ?
Comment 10 David Cassidy 2004-01-20 10:14:28 UTC
Looking at the message from Mladen it looks like it made it into CVS
Can you check out the latest version from CVS and see if this works for you ?
Comment 11 Matt Welch 2004-03-28 02:47:07 UTC
Did something happen to this fix before the 2.0.4 release? I compiled from CVS a
few weeks ago and did not have this problem, but in the 2.0.4 release, the issue
is once again present.
Comment 12 Henri Gomez 2004-03-30 06:11:21 UTC
Thanks to all to make a test against the released jk2 2.0.4.

If the problem is still in, thanks to provide a patch if available.

Also thanks to clarify if the problem exist in Apache 1.3 AND Apache 2.0.

Regards
Comment 13 Henri Gomez 2004-04-01 07:23:29 UTC
There was some change in jk2 code commited yesterday.

Thanks to check with latest HEAD and close the bug if it's fixed
Comment 14 Tim Funk 2004-12-01 02:58:55 UTC
As of November 15, 2004, JK2 is no longer supported. All bugs related to JK2 
will be marked as WONTFIX. In its place, some of its features have been 
backported to jk1. Most of those features will be seen in 1.2.7, which is 
slated for release on November 30th, 2004.

Another alternative is the ajp addition to mod_proxy which will be part of 
apache 2.

For more information on the Tomat connectors docs at
http://jakarta.apache.org/tomcat/connectors-doc/