You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by mt...@apache.org on 2003/05/03 20:08:26 UTC

cvs commit: jakarta-tomcat-connectors/jk/native2/server/apache13 mod_jk2.c

mturk       2003/05/03 11:08:26

  Modified:    jk/native2/server/apache13 mod_jk2.c
  Log:
  Fix the bug 18472. Patch originates from David Cassidy,
  with small adjustments, to make work.
  
  Revision  Changes    Path
  1.27      +223 -27   jakarta-tomcat-connectors/jk/native2/server/apache13/mod_jk2.c
  
  Index: mod_jk2.c
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native2/server/apache13/mod_jk2.c,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- mod_jk2.c	4 Feb 2003 07:42:05 -0000	1.26
  +++ mod_jk2.c	3 May 2003 18:08:26 -0000	1.27
  @@ -56,10 +56,10 @@
    * ========================================================================= */
   
   /***************************************************************************
  - * Description: Apache 1.3 plugin for Jakarta/Tomcat                         *
  + * Description: Apache 1.3 plugin for Jakarta/Tomcat                       *
    * Author:      Gal Shachor <sh...@il.ibm.com>                           *
  - *                 Henri Gomez <hg...@slib.fr>                               *
  - * Version:     $Revision$                                           *
  + *              Henri Gomez <hg...@slib.fr>                               *
  + * Version:     $Revision$                                          *
    ***************************************************************************/
   
   /*
  @@ -105,6 +105,11 @@
    * 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;
   
   /* ==================== Options setters ==================== */
   
  @@ -136,6 +141,164 @@
       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_virtual=NULL;
  +    char *tmp_full_url=NULL;
  +    server_rec *s = cmd->server;
  +
  +    uriEnv->mbean->setAttribute( workerEnv->globalEnv, uriEnv->mbean, (char *)name, (void *)val );
  +
  +    /*
  +     * 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->is_virtual && 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 )) ; 
  +        /* do not pass the hostname:0/ scheme */
  +        if (s->port) {
  +            sprintf(tmp_virtual,  "%s:%d", s->server_hostname, s->port);
  +            sprintf(tmp_full_url, "%s:%d%s", s->server_hostname, s->port, uriEnv->uri );
  +        }
  +        else {
  +            strcpy(tmp_virtual, s->server_hostname);
  +            strcpy(tmp_full_url, s->server_hostname);
  +            strcat(tmp_full_url, 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;
  +    jk_uriEnv_t *newUri;
  +    jk_bean_t *jkb;
  +
  +    if (!path)
  +        return NULL;
  +
  +    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
  +    */
  +
  +    jkb=workerEnv->globalEnv->createBean2(workerEnv->globalEnv,
  +                                          workerEnv->pool, "uri", tmp);
  +    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
  @@ -150,7 +313,7 @@
       jk_bean_t *jkb;
   
   #ifdef HAS_APR
  -	apr_initialize();
  +    apr_initialize();
       apr_pool_create( &jk_globalPool, NULL );
   
       jk2_pool_apr_create( NULL, &globalPool, NULL, jk_globalPool );
  @@ -224,34 +387,46 @@
           */
           { "JkSet", jk2_set2, NULL, RSRC_CONF, TAKE2,
             "Set a jk property, same syntax and rules as in JkWorkersFile" },
  -        NULL
  +   { "JkUriSet", jk2_uriSet, NULL, ACCESS_CONF, TAKE2,
  +          "Defines a jk property associated with a Location"},
  +     NULL
       };
   
  -/** Create default jk_config.
  -    This is the first thing called by apache ( or should be )
  +/** 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 */
  -        fprintf( stderr, "Create config for virtual host\n");
  +
  +    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 );
       } 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;
  +
  +    return (void *) newUri;
   }
   
   
  @@ -266,8 +441,6 @@
       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;
  @@ -278,8 +451,7 @@
    */
   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_uriEnv_t *serverEnv=(jk_uriEnv_t *) ap_get_module_config(s->module_config, &jk2_module);
       
       jk_env_t *env=workerEnv->globalEnv;
   
  @@ -329,13 +501,19 @@
       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;
  +    return HTTP_INTERNAL_SERVER_ERROR; /* 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,6 +547,7 @@
                             "mod_jk.handler() finding worker for %s %#lx %#lx\n",
                             uriEnv->workerName, worker, uriEnv );
               uriEnv->worker=worker;
  +
           }
       }
   
  @@ -376,7 +555,7 @@
           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;
  +   return HTTP_INTERNAL_SERVER_ERROR; /* No worker defined for this uri */
       }
   
       {
  @@ -425,9 +604,9 @@
       }
   
       env->l->jkLog(env, env->l, JK_LOG_ERROR,
  -             "mod_jk.handler() Error connecting to tomcat %d\n", rc);
  +             "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 500;
  +    return HTTP_INTERNAL_SERVER_ERROR;  /* Is your tomcat server down ? */
   }
   
   /** Use the internal mod_jk mappings to find if this is a request for
  @@ -438,17 +617,33 @@
       jk_uriEnv_t *uriEnv;
       jk_env_t *env;
               
  +    jk_uriMap_t *uriMap;
  +    char *name=NULL;
  +    int n;
       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;
  +    /* Get an env instance */
  +    env = workerEnv->globalEnv->getEnv( workerEnv->globalEnv );
  +    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,17 +668,18 @@
   static const handler_rec jk2_handlers[] =
   {
       { JK_MAGIC_TYPE, jk2_handler },
  -    { JK_HANDLER, 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_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 */
  +/*    jk2_merge_config,            / * server config merger */
  +    NULL,
       jk2_cmds,                    /* command table */
       jk2_handlers,                /* [7] list of handlers */
       jk2_translate,               /* [2] filename-to-URI translation */
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org