You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by rb...@apache.org on 2001/08/02 06:25:20 UTC

cvs commit: httpd-2.0/server config.c core.c protocol.c

rbb         01/08/01 21:25:20

  Modified:    .        CHANGES
               include  http_config.h http_core.h http_protocol.h httpd.h
               modules/aaa mod_access.c
               modules/http http_protocol.c
               server   config.c core.c protocol.c
  Log:
  Add the ability to extend the methods that Apache understands
  and have those methods <limit>able in the httpd.conf. It uses
  the same bit mask/shifted offset as the original HTTP methods
  such as M_GET or M_POST, but expands the total bits from an int to
  an ap_int64_t to handle more bits for new request methods than
  an int provides.
  Submitted by:	Cody Sherr <cs...@covalent.net>
  
  Revision  Changes    Path
  1.270     +7 -0      httpd-2.0/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/CHANGES,v
  retrieving revision 1.269
  retrieving revision 1.270
  diff -u -r1.269 -r1.270
  --- CHANGES	2001/08/01 23:33:07	1.269
  +++ CHANGES	2001/08/02 04:25:19	1.270
  @@ -1,5 +1,12 @@
   Changes with Apache 2.0.23-dev
   
  +  *) Add the ability to extend the methods that Apache understands
  +     and have those methods <limit>able in the httpd.conf. It uses 
  +     the same bit mask/shifted offset as the original HTTP methods 
  +     such as M_GET or M_POST, but expands the total bits from an int to 
  +     an ap_int64_t to handle more bits for new request methods than 
  +     an int provides.  [Cody Sherr <cs...@covalent.net>]
  +
     *) Fix broken mod_mime behavior in merging its arguments.  Possible
        cause of unexplicable crashes introduced in 2.0.20.  [William Rowe]
   
  
  
  
  1.83      +1 -1      httpd-2.0/include/http_config.h
  
  Index: http_config.h
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/include/http_config.h,v
  retrieving revision 1.82
  retrieving revision 1.83
  diff -u -r1.82 -r1.83
  --- http_config.h	2001/05/28 15:32:50	1.82
  +++ http_config.h	2001/08/02 04:25:19	1.83
  @@ -260,7 +260,7 @@
       /** Which allow-override bits are set */
       int override;
       /** Which methods are <Limit>ed */
  -    int limited;
  +    apr_int64_t limited;
       apr_array_header_t *limited_xmethods;
       ap_method_list_t *xlimited;
   
  
  
  
  1.47      +1 -1      httpd-2.0/include/http_core.h
  
  Index: http_core.h
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/include/http_core.h,v
  retrieving revision 1.46
  retrieving revision 1.47
  diff -u -r1.46 -r1.47
  --- http_core.h	2001/07/30 18:51:57	1.46
  +++ http_core.h	2001/08/02 04:25:19	1.47
  @@ -277,7 +277,7 @@
   /** A structure to keep track of authorization requirements */
   struct require_line {
       /** Where the require line is in the config file. */
  -    int method_mask;
  +    apr_int64_t method_mask;
       /** The complete string from the command line */
       char *requirement;
   };
  
  
  
  1.61      +34 -0     httpd-2.0/include/http_protocol.h
  
  Index: http_protocol.h
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/include/http_protocol.h,v
  retrieving revision 1.60
  retrieving revision 1.61
  diff -u -r1.60 -r1.61
  --- http_protocol.h	2001/07/27 21:01:16	1.60
  +++ http_protocol.h	2001/08/02 04:25:19	1.61
  @@ -227,6 +227,40 @@
                                size_t length);
   #endif
   
  +/* The index of the first bit field that is used to index into a limit
  + * bitmask. M_INVALID + 1 to METHOD_NUMBER_LAST.
  + */
  +#define METHOD_NUMBER_FIRST M_INVALID + 1
  +
  +/* The max method number. Method numbers are used to shift bitmasks,
  + * so this cannot exceed 63, and all bits high is equal to -1, which is a
  + * special flag, so the last bit used has index 62.
  + */
  +#define METHOD_NUMBER_LAST  62
  +
  +/**
  + * Register a new request method, and return the offset that will be
  + * associated with that method.
  + *
  + * @param p        The pool to create registered method numbers from.
  + * @param methname The name of the new method to register.
  + * @return         Ab int value representing an offset into a bitmask.
  + */
  +AP_DECLARE(int) ap_method_register(apr_pool_t *p, char *methname);
  +
  +/**
  + * Initialize the method_registry and allocate memory for it.
  + *
  + * @param p Pool to allocate memory for the registry from.
  + */
  +AP_DECLARE(void) ap_method_registry_init(apr_pool_t *p);
  +
  +/*
  + * This is a convenience macro to ease with checking a mask
  + * against a method name.
  + */
  +#define AP_METHOD_CHECK_ALLOWED(mask, methname) ((mask) & (1 << ap_method_number_of((methname))))
  +
   /**
    * Create a new method list with the specified number of preallocated
    * slots for extension methods.
  
  
  
  1.157     +7 -4      httpd-2.0/include/httpd.h
  
  Index: httpd.h
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/include/httpd.h,v
  retrieving revision 1.156
  retrieving revision 1.157
  diff -u -r1.156 -r1.157
  --- httpd.h	2001/07/26 15:53:15	1.156
  +++ httpd.h	2001/08/02 04:25:19	1.157
  @@ -498,7 +498,10 @@
   #define M_UNLOCK    14
   #define M_INVALID   15
   
  -#define METHODS     16
  +/* METHODS needs to be equal to the number of bits
  + * we are using for limit masks.
  + */
  +#define METHODS     64
   
   typedef struct ap_method_list_t ap_method_list_t;
   /**
  @@ -508,8 +511,8 @@
    */
   struct ap_method_list_t {
       /* The bitmask used for known methods */
  -    int method_mask;
  -    /* The array used for extension methods */
  +    apr_int64_t method_mask;
  +    /* the array used for extension methods */
       apr_array_header_t *method_list;
   };
   
  @@ -679,7 +682,7 @@
        *  HTTP_METHOD_NOT_ALLOWED.  Unfortunately this means that a Script GET
        *  handler can't be installed by mod_actions.
        */
  -    int allowed;
  +    apr_int64_t allowed;
       /** Array of extension methods */
       apr_array_header_t *allowed_xmethods; 
       /** List of allowed methods */
  
  
  
  1.33      +3 -2      httpd-2.0/modules/aaa/mod_access.c
  
  Index: mod_access.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/aaa/mod_access.c,v
  retrieving revision 1.32
  retrieving revision 1.33
  diff -u -r1.32 -r1.33
  --- mod_access.c	2001/04/12 13:35:39	1.32
  +++ mod_access.c	2001/08/02 04:25:19	1.33
  @@ -91,7 +91,7 @@
   };
   
   typedef struct {
  -    int limited;
  +    apr_int64_t limited;
       union {
   	char *from;
           apr_ipsubnet_t *ip;
  @@ -237,8 +237,9 @@
   
   static int find_allowdeny(request_rec *r, apr_array_header_t *a, int method)
   {
  +
       allowdeny *ap = (allowdeny *) a->elts;
  -    int mmask = (1 << method);
  +    apr_int64_t mmask = (1 << method);
       int i;
       int gothost = 0;
       const char *remotehost = NULL;
  
  
  
  1.340     +73 -3     httpd-2.0/modules/http/http_protocol.c
  
  Index: http_protocol.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/http/http_protocol.c,v
  retrieving revision 1.339
  retrieving revision 1.340
  diff -u -r1.339 -r1.340
  --- http_protocol.c	2001/08/01 04:08:36	1.339
  +++ http_protocol.c	2001/08/02 04:25:20	1.340
  @@ -299,6 +299,64 @@
       return OK;
   }
   
  +/**
  + * Singleton registry of additional methods. This maps new method names
  + * such as "MYGET" to methnums, which are int offsets into bitmasks.
  + *
  + * This follows the same technique as standard M_GET, M_POST, etc. These
  + * are dynamically assigned when modules are loaded and <Limit GET MYGET>
  + * directives are processed.
  + */
  +static apr_hash_t *methods_registry=NULL;
  +static int cur_method_number = METHOD_NUMBER_FIRST;
  +
  +/* This internal function is used to clear the method registry
  + * and reset the cur_method_number counter.
  + */
  +static apr_status_t ap_method_registry_destroy(void *notused)
  +{
  +    methods_registry = NULL;
  +    cur_method_number = METHOD_NUMBER_FIRST;
  +    return APR_SUCCESS;
  +}
  +
  +AP_DECLARE(void) ap_method_registry_init(apr_pool_t *p)
  +{
  +    methods_registry = apr_hash_make(p);
  +    apr_pool_cleanup_register(p, NULL,
  +			      ap_method_registry_destroy,
  +			      apr_pool_cleanup_null);
  +}
  +
  +AP_DECLARE(int) ap_method_register(apr_pool_t *p, char *methname)
  +{
  +    int *newmethnum;
  +
  +    if (methods_registry == NULL) {
  +	ap_method_registry_init(p);
  +    }
  +
  +    if (methname == NULL) {
  +	return M_INVALID;
  +    }
  +
  +    if (cur_method_number > METHOD_NUMBER_LAST) {
  +	/* The method registry  has run out of dynamically
  +	 * assignable method numbers. Log this and return M_INVALID.
  +	 */
  +	ap_log_perror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, p,
  +		      "Maximum new request methods %d reached while registering method %s.",
  +		      METHOD_NUMBER_LAST, methname);
  +	return M_INVALID;
  +    }
  +
  +    newmethnum  = (int*)apr_palloc(p,sizeof(int));
  +    *newmethnum = cur_method_number++;
  +    apr_hash_set(methods_registry, methname, APR_HASH_KEY_STRING, newmethnum);
  +
  +    return *newmethnum;
  +}
  +
   /* Get the method number associated with the given string, assumed to
    * contain an HTTP method.  Returns M_INVALID if not recognized.
    *
  @@ -308,6 +366,8 @@
    */
   AP_DECLARE(int) ap_method_number_of(const char *method)
   {
  +    int *methnum = NULL;
  +
       switch (*method) {
           case 'H':
              if (strcmp(method, "HEAD") == 0)
  @@ -362,6 +422,16 @@
                  return M_UNLOCK;
              break;
       }
  +
  +    /* check if the method has been dynamically registered */
  +    if (methods_registry != NULL) {
  +	methnum = (int*)apr_hash_get(methods_registry,
  +				     method,
  +				     APR_HASH_KEY_STRING);
  +	if (methnum != NULL)
  +	    return *methnum;
  +    }
  +
       return M_INVALID;
   }
   
  @@ -904,7 +974,7 @@
   static char *make_allow(request_rec *r)
   {
       char *list;
  -    int mask;
  +    apr_int64_t mask;
   
       mask = r->allowed_methods->method_mask;
       list = apr_pstrcat(r->pool,
  @@ -2073,8 +2143,8 @@
       char **methods;
    
       /*
  -     * If it's one of our known methods, use the shortcut and use the
  -     * bitmask.
  +     * If it's a known methods, either builtin or registered
  +     * by a module, use the bitmask.
        */
       methnum = ap_method_number_of(method);
       l->method_mask |= ~(1 << methnum);
  
  
  
  1.131     +6 -18     httpd-2.0/server/config.c
  
  Index: config.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/server/config.c,v
  retrieving revision 1.130
  retrieving revision 1.131
  diff -u -r1.130 -r1.131
  --- config.c	2001/07/04 03:16:33	1.130
  +++ config.c	2001/08/02 04:25:20	1.131
  @@ -354,30 +354,18 @@
   
   AP_DECLARE(int) ap_method_is_limited(cmd_parms *cmd, const char *method) {
       int methnum;
  -    int i;
  -    char **xmethod;
   
       methnum = ap_method_number_of(method);
  +
       /*
  -     * The simple case: a method hard-coded into Apache.
  +     * A method number either hardcoded into apache or
  +     * added by a module and registered.
        */
       if (methnum != M_INVALID) {
  -	return (methnum & cmd->limited);
  -    }
  -    /*
  -     * Some extension method we don't know implicitly.
  -     */
  -    if ((cmd->limited_xmethods == NULL)
  -	|| (cmd->limited_xmethods->nelts == 0)) {
  -	return 0;
  -    }
  -    xmethod = (char **) cmd->limited_xmethods->elts;
  -    for (i = 0; i < cmd->limited_xmethods->nelts; ++i) {
  -	if (strcmp(method, xmethod[i]) == 0) {
  -	    return 1;
  -	}
  +	return  (cmd->limited & (1<<methnum));
       }
  -    return 0;
  +
  +    return 0; /* not found */
   }
   
   AP_DECLARE(void) ap_register_hooks(module *m, apr_pool_t *p)
  
  
  
  1.33      +10 -35    httpd-2.0/server/core.c
  
  Index: core.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/server/core.c,v
  retrieving revision 1.32
  retrieving revision 1.33
  diff -u -r1.32 -r1.33
  --- core.c	2001/08/01 19:15:22	1.32
  +++ core.c	2001/08/02 04:25:20	1.33
  @@ -1466,7 +1466,7 @@
   						  const char *arg) {
       const char *limited_methods = ap_getword(cmd->pool, &arg, '>');
       void *tog = cmd->cmd->cmd_data;
  -    int limited = 0;
  +    apr_int64_t limited = 0;
       const char *errmsg;
     
       const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);
  @@ -1476,46 +1476,21 @@
   
       while (limited_methods[0]) {
           char *method = ap_getword_conf(cmd->pool, &limited_methods);
  -        int  methnum = ap_method_number_of(method);
  +        int methnum;
   
  +        /* check for builtin or module registered method number */
  +        methnum = ap_method_number_of(method);
  +
           if (methnum == M_TRACE && !tog) {
               return "TRACE cannot be controlled by <Limit>";
           }
           else if (methnum == M_INVALID) {
  -	    char **xmethod;
  -	    register int i, j, k;
  -
  -	    /*
  -	     * Deal with <Limit> by adding the method to the list.
  -	     */
  -	    if (!tog) {
  -		if (cmd->limited_xmethods == NULL) {
  -		    cmd->limited_xmethods = apr_array_make(cmd->pool, 2,
  -							   sizeof(char *));
  -		}
  -		xmethod = (char **) apr_array_push(cmd->limited_xmethods);
  -		*xmethod = apr_pstrdup(cmd->pool, method);
  -	    }
  -	    /*
  -	     * <LimitExcept>, so remove any/all occurrences of the method
  -	     * in the extension array.
  -	     */
  -	    else if ((cmd->limited_xmethods != NULL)
  -		     && (cmd->limited_xmethods->nelts != 0)) {
  -		xmethod = (char **) cmd->limited_xmethods->elts;
  -		for (i = 0; i < cmd->limited_xmethods->nelts; i++) {
  -		    if (strcmp(xmethod[i], method) == 0) {
  -			for (j = i, k = i + 1;
  -			     k < cmd->limited_xmethods->nelts;
  -			     ++j, ++k) {
  -			    xmethod[j] = xmethod[k];
  -			}
  -			cmd->limited_xmethods->nelts--;
  -		    }
  -		}
  -	    }
  +            /* method has not been registered yet, but resorce restriction
  +             * is always checked before method handling, so register it.
  +             */
  +            methnum = ap_method_register(cmd->pool, method);
           }
  -	limited |= (1 << methnum);
  +        limited |= (1 << methnum);
       }
   
       /* Killing two features with one function,
  
  
  
  1.36      +20 -3     httpd-2.0/server/protocol.c
  
  Index: protocol.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/server/protocol.c,v
  retrieving revision 1.35
  retrieving revision 1.36
  diff -u -r1.35 -r1.36
  --- protocol.c	2001/07/30 04:38:02	1.35
  +++ protocol.c	2001/08/02 04:25:20	1.36
  @@ -1135,14 +1135,31 @@
   
   AP_DECLARE(int) ap_vrprintf(request_rec *r, const char *fmt, va_list va)
   {
  -    char buf[4096];
  +    char *buf;
  +    int   buf_size = 4096; /* start with a 4k buffer */
       apr_size_t written;
   
       if (r->connection->aborted)
           return -1;
   
  -    /* ### fix this mechanism to allow more than 4K of output */
  -    written = apr_vsnprintf(buf, sizeof(buf), fmt, va);
  +    buf = apr_palloc(r->pool, buf_size);
  +    while (1) {
  +	written = apr_vsnprintf(buf, buf_size, fmt, va);
  +
  +	/*
  +	 * Per the apr_vsnprintf comments, in no event does apr_snprintf return a negative number.
  +	 * Therefore, it's not possible to distinguish between an output which was truncated,
  +	 * and an output which exactly filled the buffer.
  +	 */
  +	if (written == buf_size) {
  +	    buf_size *= 2;
  +	    buf = apr_palloc(r->pool, buf_size); /* want realloc */
  +	}
  +	else {
  +	    break;
  +	}
  +    }
  +
       if (buffer_output(r, buf, written) != APR_SUCCESS)
           return -1;
   
  
  
  

Re: cvs commit: httpd-2.0/server config.c core.c protocol.c

Posted by Ryan Bloom <rb...@covalent.net>.
On Wednesday 01 August 2001 21:25, rbb@apache.org wrote:
> rbb         01/08/01 21:25:20
>
>   Modified:    .        CHANGES
>                include  http_config.h http_core.h http_protocol.h httpd.h
>                modules/aaa mod_access.c
>                modules/http http_protocol.c
>                server   config.c core.c protocol.c
>   Log:
>   Add the ability to extend the methods that Apache understands
>   and have those methods <limit>able in the httpd.conf. It uses
>   the same bit mask/shifted offset as the original HTTP methods
>   such as M_GET or M_POST, but expands the total bits from an int to
>   an ap_int64_t to handle more bits for new request methods than
>   an int provides.
>   Submitted by:	Cody Sherr <cs...@covalent.net>

Okay, now can we remove the ap_method_list_* functions?

Ryan
_____________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
Covalent Technologies			rbb@covalent.net
-----------------------------------------------------------------------------

Re: cvs commit: httpd-2.0/server config.c core.c protocol.c

Posted by Ryan Morgan <rm...@covalent.net>.
On Thu, Aug 02, 2001 at 04:25:20AM -0000, rbb@apache.org wrote:
> rbb         01/08/01 21:25:20
> 
>   Modified:    .        CHANGES
>                include  http_config.h http_core.h http_protocol.h httpd.h
>                modules/aaa mod_access.c
>                modules/http http_protocol.c
>                server   config.c core.c protocol.c
>   Log:
>   Add the ability to extend the methods that Apache understands
>   and have those methods <limit>able in the httpd.conf. It uses
>   the same bit mask/shifted offset as the original HTTP methods
>   such as M_GET or M_POST, but expands the total bits from an int to
>   an ap_int64_t to handle more bits for new request methods than
>   an int provides.
>   Submitted by:	Cody Sherr <cs...@covalent.net>
>   

<snip>

>    
>    static int find_allowdeny(request_rec *r, apr_array_header_t *a, int method)
>    {
>   +
>        allowdeny *ap = (allowdeny *) a->elts;
>   -    int mmask = (1 << method);
>   +    apr_int64_t mmask = (1 << method);
>        int i;
>        int gothost = 0;
>        const char *remotehost = NULL;
> 

There are a lot of places that do bit shifts like this, but they will not
work for method numbers > 32 since most compilers will treat the 1 as an
integer.  Casting the 1 to apr_int64_t fixes the problem.  I can put 
together a patch, or someone with commit access can just go in and fix it.

-Ryan

Re: cvs commit: httpd-2.0/server config.c core.c protocol.c

Posted by Ryan Bloom <rb...@covalent.net>.
On Wednesday 01 August 2001 21:25, rbb@apache.org wrote:
> rbb         01/08/01 21:25:20
>
>   Modified:    .        CHANGES
>                include  http_config.h http_core.h http_protocol.h httpd.h
>                modules/aaa mod_access.c
>                modules/http http_protocol.c
>                server   config.c core.c protocol.c
>   Log:
>   Add the ability to extend the methods that Apache understands
>   and have those methods <limit>able in the httpd.conf. It uses
>   the same bit mask/shifted offset as the original HTTP methods
>   such as M_GET or M_POST, but expands the total bits from an int to
>   an ap_int64_t to handle more bits for new request methods than
>   an int provides.
>   Submitted by:	Cody Sherr <cs...@covalent.net>

Okay, now can we remove the ap_method_list_* functions?

Ryan
_____________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
Covalent Technologies			rbb@covalent.net
-----------------------------------------------------------------------------