httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gst...@apache.org
Subject cvs commit: httpd-2.0/include http_protocol.h httpd.h
Date Tue, 19 Mar 2002 10:11:33 GMT
gstein      02/03/19 02:11:33

  Modified:    modules/dav/main mod_dav.c
               modules/http http_protocol.c
               include  http_protocol.h httpd.h
  Log:
  The underlying change here was to add the new WebDAV/DeltaV methods
  now that it has an RFC. At the same time, I revamped a good chunk of
  the name <-> number mapping code in http_protocol.c
  
  * add M_FOO constants for the new RFC 3253 (DeltaV) methods. label
    where each of the builtin methods comes from.
  
  * moved METHOD_NUMBER_FIRST/LAST from http_protocol.h into
    http_protocol.c since they weren't used anywhere else and they
    weren't namespace-protected.
  
  * create register_one_method() and use it to insert all builtin
    methods (at _init() time) and extended methods into the registry.
  
  * add a lookup_builtin_method() to quickly map a method name to a
    builtin method number.
  
  * rebuild ap_method_number_of() to use the new lookup function.
  
  * revamp ap_method_name_of() to use the registry to locate the name
    for any method number. add a pool argument (no callers in the core
    code needed to be updated)
  
  * revamp make_allow() to deal with the new method numbers and all
    extended methods.
  
  * in mod_dav, use the new method numbers rather than registering the
    DeltaV methods.
  
  Revision  Changes    Path
  1.75      +13 -36    httpd-2.0/modules/dav/main/mod_dav.c
  
  Index: mod_dav.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/dav/main/mod_dav.c,v
  retrieving revision 1.74
  retrieving revision 1.75
  diff -u -r1.74 -r1.75
  --- mod_dav.c	18 Mar 2002 22:25:01 -0000	1.74
  +++ mod_dav.c	19 Mar 2002 10:11:32 -0000	1.75
  @@ -132,40 +132,18 @@
   
   /* DAV methods */
   enum {
  -    DAV_M_VERSION_CONTROL = 0,
  -    DAV_M_CHECKOUT,
  -    DAV_M_UNCHECKOUT,
  -    DAV_M_CHECKIN,
  -    DAV_M_UPDATE,
  -    DAV_M_LABEL,
  -    DAV_M_REPORT,
  -    DAV_M_MKWORKSPACE,
  -    DAV_M_MKACTIVITY,
  -    DAV_M_BASELINE_CONTROL,
  -    DAV_M_MERGE,
  -    DAV_M_BIND,
  +    DAV_M_BIND = 0,
       DAV_M_LAST
   };
  -
   static int dav_methods[DAV_M_LAST];
   
  +
   static int dav_init_handler(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp,
                                server_rec *s)
   {
       /* DBG0("dav_init_handler"); */
   
       /* Register DAV methods */
  -    dav_methods[DAV_M_VERSION_CONTROL] = ap_method_register(p, "VERSION-CONTROL");
  -    dav_methods[DAV_M_CHECKOUT] = ap_method_register(p, "CHECKOUT");
  -    dav_methods[DAV_M_UNCHECKOUT] = ap_method_register(p, "UNCHECKOUT");
  -    dav_methods[DAV_M_CHECKIN] = ap_method_register(p, "CHECKIN");
  -    dav_methods[DAV_M_UPDATE] = ap_method_register(p, "UPDATE");
  -    dav_methods[DAV_M_LABEL] = ap_method_register(p, "LABEL");
  -    dav_methods[DAV_M_REPORT] = ap_method_register(p, "REPORT");
  -    dav_methods[DAV_M_MKWORKSPACE] = ap_method_register(p, "MKWORKSPACE");
  -    dav_methods[DAV_M_MKACTIVITY] = ap_method_register(p, "MKACTIVITY");
  -    dav_methods[DAV_M_BASELINE_CONTROL] = ap_method_register(p, "BASELINE-CONTROL");
  -    dav_methods[DAV_M_MERGE] = ap_method_register(p, "MERGE");
       dav_methods[DAV_M_BIND] = ap_method_register(p, "BIND");
   
       ap_add_version_component(p, "DAV/2");
  @@ -3868,7 +3846,6 @@
       int result;
       int label_allowed;
       ap_xml_doc *doc;
  -    ap_text *t;
       dav_error *err;
   
       /* If no versioning provider, decline the request */
  @@ -4488,47 +4465,47 @@
           return dav_method_unlock(r);
       }
   
  -    if (r->method_number == dav_methods[DAV_M_VERSION_CONTROL]) {
  +    if (r->method_number == M_VERSION_CONTROL) {
           return dav_method_vsn_control(r);
       }
   
  -    if (r->method_number == dav_methods[DAV_M_CHECKOUT]) {
  +    if (r->method_number == M_CHECKOUT) {
           return dav_method_checkout(r);
       }
   
  -    if (r->method_number == dav_methods[DAV_M_UNCHECKOUT]) {
  +    if (r->method_number == M_UNCHECKOUT) {
           return dav_method_uncheckout(r);
       }
   
  -    if (r->method_number == dav_methods[DAV_M_CHECKIN]) {
  +    if (r->method_number == M_CHECKIN) {
           return dav_method_checkin(r);
       }
   
  -    if (r->method_number == dav_methods[DAV_M_UPDATE]) {
  +    if (r->method_number == M_UPDATE) {
           return dav_method_update(r);
       }
   
  -    if (r->method_number == dav_methods[DAV_M_LABEL]) {
  +    if (r->method_number == M_LABEL) {
           return dav_method_label(r);
       }
   
  -    if (r->method_number == dav_methods[DAV_M_REPORT]) {
  +    if (r->method_number == M_REPORT) {
           return dav_method_report(r);
       }
   
  -    if (r->method_number == dav_methods[DAV_M_MKWORKSPACE]) {
  +    if (r->method_number == M_MKWORKSPACE) {
           return dav_method_make_workspace(r);
       }
   
  -    if (r->method_number == dav_methods[DAV_M_MKACTIVITY]) {
  +    if (r->method_number == M_MKACTIVITY) {
           return dav_method_make_activity(r);
       }
   
  -    if (r->method_number == dav_methods[DAV_M_BASELINE_CONTROL]) {
  +    if (r->method_number == M_BASELINE_CONTROL) {
           return dav_method_baseline_control(r);
       }
   
  -    if (r->method_number == dav_methods[DAV_M_MERGE]) {
  +    if (r->method_number == M_MERGE) {
           return dav_method_merge(r);
       }
   
  
  
  
  1.396     +270 -138  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.395
  retrieving revision 1.396
  diff -u -r1.395 -r1.396
  --- http_protocol.c	16 Mar 2002 20:29:38 -0000	1.395
  +++ http_protocol.c	19 Mar 2002 10:11:32 -0000	1.396
  @@ -100,6 +100,18 @@
   #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
  +
  +
   AP_DECLARE(int) ap_set_keepalive(request_rec *r)
   {
       int ka_sent = 0;
  @@ -317,6 +329,16 @@
   static apr_hash_t *methods_registry = NULL;
   static int cur_method_number = METHOD_NUMBER_FIRST;
   
  +/* internal function to register one method/number pair */
  +static void register_one_method(apr_pool_t *p, const char *methname,
  +                                int methnum)
  +{
  +    int *pnum = apr_palloc(p, sizeof(*pnum));
  +
  +    *pnum = methnum;
  +    apr_hash_set(methods_registry, methname, APR_HASH_KEY_STRING, pnum);
  +}
  +
   /* This internal function is used to clear the method registry
    * and reset the cur_method_number counter.
    */
  @@ -333,6 +355,35 @@
       apr_pool_cleanup_register(p, NULL,
                                 ap_method_registry_destroy,
                                 apr_pool_cleanup_null);
  +
  +    /* put all the standard methods into the registry hash to ease the
  +       mapping operations between name and number */
  +    register_one_method(p, "GET", M_GET);
  +    register_one_method(p, "PUT", M_PUT);
  +    register_one_method(p, "POST", M_POST);
  +    register_one_method(p, "DELETE", M_DELETE);
  +    register_one_method(p, "CONNECT", M_CONNECT);
  +    register_one_method(p, "OPTIONS", M_OPTIONS);
  +    register_one_method(p, "TRACE", M_TRACE);
  +    register_one_method(p, "PATCH", M_PATCH);
  +    register_one_method(p, "PROPFIND", M_PROPFIND);
  +    register_one_method(p, "PROPPATCH", M_PROPPATCH);
  +    register_one_method(p, "MKCOL", M_MKCOL);
  +    register_one_method(p, "COPY", M_COPY);
  +    register_one_method(p, "MOVE", M_MOVE);
  +    register_one_method(p, "LOCK", M_LOCK);
  +    register_one_method(p, "UNLOCK", M_UNLOCK);
  +    register_one_method(p, "VERSION-CONTROL", M_VERSION_CONTROL);
  +    register_one_method(p, "CHECKOUT", M_CHECKOUT);
  +    register_one_method(p, "UNCHECKOUT", M_UNCHECKOUT);
  +    register_one_method(p, "CHECKIN", M_CHECKIN);
  +    register_one_method(p, "UPDATE", M_UPDATE);
  +    register_one_method(p, "LABEL", M_LABEL);
  +    register_one_method(p, "REPORT", M_REPORT);
  +    register_one_method(p, "MKWORKSPACE", M_MKWORKSPACE);
  +    register_one_method(p, "MKACTIVITY", M_MKACTIVITY);
  +    register_one_method(p, "BASELINE-CONTROL", M_BASELINE_CONTROL);
  +    register_one_method(p, "MERGE", M_MERGE);
   }
   
   AP_DECLARE(int) ap_method_register(apr_pool_t *p, const char *methname)
  @@ -366,11 +417,180 @@
           return M_INVALID;
       }
   
  -    methnum = (int *)apr_palloc(p, sizeof(int));
  -    *methnum = cur_method_number++;
  -    apr_hash_set(methods_registry, methname, APR_HASH_KEY_STRING, methnum);
  +    register_one_method(p, methname, cur_method_number);
  +    return cur_method_number++;
  +}
  +
  +#define UNKNOWN_METHOD (-1)
   
  -    return *methnum;
  +static int lookup_builtin_method(const char *method, apr_size_t len)
  +{
  +    /* Note: the following code was generated by the "shilka" tool from
  +       the "cocom" parsing/compilation toolkit. It is an optimized lookup
  +       based on analysis of the input keywords. Postprocessing was done
  +       on the shilka output, but the basic structure and analysis is
  +       from there. Should new HTTP methods be added, then manual insertion
  +       into this code is fine, or simply re-running the shilka tool on
  +       the appropriate input. */
  +
  +    /* Note: it is also quite reasonable to just use our method_registry,
  +       but I'm assuming (probably incorrectly) we want more speed here
  +       (based on the optimizations the previous code was doing). */
  +
  +    switch (len)
  +    {
  +    case 3:
  +        switch (method[0])
  +        {
  +        case 'P':
  +            return (method[1] == 'U'
  +                    && method[2] == 'T'
  +                    ? M_PUT : UNKNOWN_METHOD);
  +        case 'G':
  +            return (method[1] == 'E'
  +                    && method[2] == 'T'
  +                    ? M_GET : UNKNOWN_METHOD);
  +        default:
  +            return UNKNOWN_METHOD;
  +        }
  +
  +    case 4:
  +        switch (method[0])
  +        {
  +        case 'P':
  +            return (method[1] == 'O'
  +                    && method[2] == 'S'
  +                    && method[3] == 'T'
  +                    ? M_POST : UNKNOWN_METHOD);
  +        case 'M':
  +            return (method[1] == 'O'
  +                    && method[2] == 'V'
  +                    && method[3] == 'E'
  +                    ? M_MOVE : UNKNOWN_METHOD);
  +        case 'L':
  +            return (method[1] == 'O'
  +                    && method[2] == 'C'
  +                    && method[3] == 'K'
  +                    ? M_LOCK : UNKNOWN_METHOD);
  +        case 'C':
  +            return (method[1] == 'O'
  +                    && method[2] == 'P'
  +                    && method[3] == 'Y'
  +                    ? M_COPY : UNKNOWN_METHOD);
  +        default:
  +            return UNKNOWN_METHOD;
  +        }
  +
  +    case 5:
  +        switch (method[2])
  +        {
  +        case 'T':
  +            return (memcmp(method, "PATCH", 5) == 0
  +                    ? M_PATCH : UNKNOWN_METHOD);
  +        case 'R':
  +            return (memcmp(method, "MERGE", 5) == 0
  +                    ? M_MERGE : UNKNOWN_METHOD);
  +        case 'C':
  +            return (memcmp(method, "MKCOL", 5) == 0
  +                    ? M_MKCOL : UNKNOWN_METHOD);
  +        case 'B':
  +            return (memcmp(method, "LABEL", 5) == 0
  +                    ? M_LABEL : UNKNOWN_METHOD);
  +        case 'A':
  +            return (memcmp(method, "TRACE", 5) == 0
  +                    ? M_TRACE : UNKNOWN_METHOD);
  +        default:
  +            return UNKNOWN_METHOD;
  +        }
  +
  +    case 6:
  +        switch (method[0])
  +        {
  +        case 'U':
  +            switch (method[5])
  +            {
  +            case 'K':
  +                return (memcmp(method, "UNLOCK", 6) == 0
  +                        ? M_UNLOCK : UNKNOWN_METHOD);
  +            case 'E':
  +                return (memcmp(method, "UPDATE", 6) == 0
  +                        ? M_UPDATE : UNKNOWN_METHOD);
  +            default:
  +                return UNKNOWN_METHOD;
  +            }
  +        case 'R':
  +            return (memcmp(method, "REPORT", 6) == 0
  +                    ? M_REPORT : UNKNOWN_METHOD);
  +        case 'D':
  +            return (memcmp(method, "DELETE", 6) == 0
  +                    ? M_DELETE : UNKNOWN_METHOD);
  +        default:
  +            return UNKNOWN_METHOD;
  +        }
  +
  +    case 7:
  +        switch (method[1])
  +        {
  +        case 'P':
  +            return (memcmp(method, "OPTIONS", 7) == 0
  +                    ? M_OPTIONS : UNKNOWN_METHOD);
  +        case 'O':
  +            return (memcmp(method, "CONNECT", 7) == 0
  +                    ? M_CONNECT : UNKNOWN_METHOD);
  +        case 'H':
  +            return (memcmp(method, "CHECKIN", 7) == 0
  +                    ? M_CHECKIN : UNKNOWN_METHOD);
  +        default:
  +            return UNKNOWN_METHOD;
  +        }
  +
  +    case 8:
  +        switch (method[0])
  +        {
  +        case 'P':
  +            return (memcmp(method, "PROPFIND", 8) == 0
  +                    ? M_PROPFIND : UNKNOWN_METHOD);
  +        case 'C':
  +            return (memcmp(method, "CHECKOUT", 8) == 0
  +                    ? M_CHECKOUT : UNKNOWN_METHOD);
  +        default:
  +            return UNKNOWN_METHOD;
  +        }
  +
  +    case 9:
  +        return (memcmp(method, "PROPPATCH", 9) == 0
  +                ? M_PROPPATCH : UNKNOWN_METHOD);
  +
  +    case 10:
  +        switch (method[0])
  +        {
  +        case 'U':
  +            return (memcmp(method, "UNCHECKOUT", 10) == 0
  +                    ? M_UNCHECKOUT : UNKNOWN_METHOD);
  +        case 'M':
  +            return (memcmp(method, "MKACTIVITY", 10) == 0
  +                    ? M_MKACTIVITY : UNKNOWN_METHOD);
  +        default:
  +            return UNKNOWN_METHOD;
  +        }
  +
  +    case 11:
  +        return (memcmp(method, "MKWORKSPACE", 11) == 0
  +                ? M_MKWORKSPACE : UNKNOWN_METHOD);
  +
  +    case 15:
  +        return (memcmp(method, "VERSION-CONTROL", 15) == 0
  +                ? M_VERSION_CONTROL : UNKNOWN_METHOD);
  +
  +    case 16:
  +        return (memcmp(method, "BASELINE-CONTROL", 16) == 0
  +                ? M_BASELINE_CONTROL : UNKNOWN_METHOD);
  +
  +    default:
  +        return UNKNOWN_METHOD;
  +    }
  +
  +    /* NOTREACHED */
   }
   
   /* Get the method number associated with the given string, assumed to
  @@ -382,84 +602,16 @@
    */
   AP_DECLARE(int) ap_method_number_of(const char *method)
   {
  -    int *methnum = NULL;
  +    int len = strlen(method);
  +    int which = lookup_builtin_method(method, len);
   
  -    switch (*method) {
  -    case 'H':
  -        if (strcmp(method, "HEAD") == 0) {
  -            return M_GET;   /* see header_only in request_rec */
  -        }
  -        break;
  -    case 'G':
  -        if (strcmp(method, "GET") == 0) {
  -            return M_GET;
  -        }
  -        break;
  -    case 'P':
  -        if (strcmp(method, "POST") == 0) {
  -            return M_POST;
  -        }
  -        if (strcmp(method, "PUT") == 0) {
  -            return M_PUT;
  -        }
  -        if (strcmp(method, "PATCH") == 0) {
  -            return M_PATCH;
  -        }
  -        if (strcmp(method, "PROPFIND") == 0) {
  -            return M_PROPFIND;
  -        }
  -        if (strcmp(method, "PROPPATCH") == 0) {
  -            return M_PROPPATCH;
  -        }
  -        break;
  -    case 'D':
  -        if (strcmp(method, "DELETE") == 0) {
  -            return M_DELETE;
  -        }
  -        break;
  -    case 'C':
  -        if (strcmp(method, "CONNECT") == 0) {
  -            return M_CONNECT;
  -        }
  -        if (strcmp(method, "COPY") == 0) {
  -            return M_COPY;
  -        }
  -        break;
  -    case 'M':
  -        if (strcmp(method, "MKCOL") == 0) {
  -            return M_MKCOL;
  -        }
  -        if (strcmp(method, "MOVE") == 0) {
  -            return M_MOVE;
  -        }
  -        break;
  -    case 'O':
  -        if (strcmp(method, "OPTIONS") == 0) {
  -            return M_OPTIONS;
  -        }
  -        break;
  -    case 'T':
  -        if (strcmp(method, "TRACE") == 0) {
  -            return M_TRACE;
  -        }
  -        break;
  -    case 'L':
  -        if (strcmp(method, "LOCK") == 0) {
  -            return M_LOCK;
  -        }
  -        break;
  -    case 'U':
  -        if (strcmp(method, "UNLOCK") == 0) {
  -            return M_UNLOCK;
  -        }
  -        break;
  -    }
  +    if (which != UNKNOWN_METHOD)
  +        return which;
   
       /* check if the method has been dynamically registered */
       if (methods_registry != NULL) {
  -        methnum = (int*)apr_hash_get(methods_registry,
  -                                     method,
  -                                     APR_HASH_KEY_STRING);
  +        int *methnum = apr_hash_get(methods_registry, method, len);
  +
           if (methnum != NULL) {
               return *methnum;
           }
  @@ -469,49 +621,25 @@
   }
   
   /*
  - * Turn a known method number into a name.  Doesn't work for
  - * extension methods, obviously.
  + * Turn a known method number into a name.
    */
  -AP_DECLARE(const char *) ap_method_name_of(int methnum)
  +AP_DECLARE(const char *) ap_method_name_of(apr_pool_t *p, int methnum)
   {
  -    static const char *AP_HTTP_METHODS[METHODS] = { NULL };
  +    apr_hash_index_t *hi = apr_hash_first(p, methods_registry);
   
  -    /*
  -     * This is ugly, but the previous incantation made Windows C
  -     * varf.  I'm not even sure it was ANSI C.  However, ugly as it
  -     * is, this works, and we only have to do it once.
  -     */
  -    if (AP_HTTP_METHODS[0] == NULL) {
  -        AP_HTTP_METHODS[M_GET]       = "GET";
  -        AP_HTTP_METHODS[M_PUT]       = "PUT";
  -        AP_HTTP_METHODS[M_POST]      = "POST";
  -        AP_HTTP_METHODS[M_DELETE]    = "DELETE";
  -        AP_HTTP_METHODS[M_CONNECT]   = "CONNECT";
  -        AP_HTTP_METHODS[M_OPTIONS]   = "OPTIONS";
  -        AP_HTTP_METHODS[M_TRACE]     = "TRACE";
  -        AP_HTTP_METHODS[M_PATCH]     = "PATCH";
  -        AP_HTTP_METHODS[M_PROPFIND]  = "PROPFIND";
  -        AP_HTTP_METHODS[M_PROPPATCH] = "PROPPATCH";
  -        AP_HTTP_METHODS[M_MKCOL]     = "MKCOL";
  -        AP_HTTP_METHODS[M_COPY]      = "COPY";
  -        AP_HTTP_METHODS[M_MOVE]      = "MOVE";
  -        AP_HTTP_METHODS[M_LOCK]      = "LOCK";
  -        AP_HTTP_METHODS[M_UNLOCK]    = "UNLOCK";
  -        AP_HTTP_METHODS[M_INVALID]   = NULL;
  -        /*
  -         * Since we're using symbolic names, make sure we only do
  -         * this once by forcing a value into the first slot IFF it's
  -         * still NULL.
  -         */
  -        if (AP_HTTP_METHODS[0] == NULL) {
  -            AP_HTTP_METHODS[0] = "INVALID";
  -        }
  -    }
  +    /* scan through the hash table, looking for a value that matches
  +       the provided method number. */
  +    for (; hi; hi = apr_hash_next(hi)) {
  +        const void *key;
  +        void *val;
   
  -    if ((methnum == M_INVALID) || (methnum >= METHODS)) {
  -        return NULL;
  +        apr_hash_this(hi, &key, NULL, &val);
  +        if (*(int *)val == methnum)
  +            return key;
       }
  -    return AP_HTTP_METHODS[methnum];
  +
  +    /* it wasn't found in the hash */
  +    return NULL;
   }
   
   static long get_chunk_size(char *);
  @@ -955,25 +1083,32 @@
   {
       char *list;
       apr_int64_t mask;
  +    apr_array_header_t *allow = apr_array_make(r->pool, 10, sizeof(char *));
  +    apr_hash_index_t *hi = apr_hash_first(r->pool, methods_registry);
   
       mask = r->allowed_methods->method_mask;
  -    list = apr_pstrcat(r->pool,
  -                   (mask & (AP_METHOD_BIT << M_GET))       ? ", GET, HEAD" :
"",
  -                   (mask & (AP_METHOD_BIT << M_POST))      ? ", POST"      :
"",
  -                   (mask & (AP_METHOD_BIT << M_PUT))       ? ", PUT"       :
"",
  -                   (mask & (AP_METHOD_BIT << M_DELETE))    ? ", DELETE"    :
"",
  -                   (mask & (AP_METHOD_BIT << M_CONNECT))   ? ", CONNECT"   :
"",
  -                   (mask & (AP_METHOD_BIT << M_OPTIONS))   ? ", OPTIONS"   :
"",
  -                   (mask & (AP_METHOD_BIT << M_PATCH))     ? ", PATCH"     :
"",
  -                   (mask & (AP_METHOD_BIT << M_PROPFIND))  ? ", PROPFIND"  :
"",
  -                   (mask & (AP_METHOD_BIT << M_PROPPATCH)) ? ", PROPPATCH" :
"",
  -                   (mask & (AP_METHOD_BIT << M_MKCOL))     ? ", MKCOL"     :
"",
  -                   (mask & (AP_METHOD_BIT << M_COPY))      ? ", COPY"      :
"",
  -                   (mask & (AP_METHOD_BIT << M_MOVE))      ? ", MOVE"      :
"",
  -                   (mask & (AP_METHOD_BIT << M_LOCK))      ? ", LOCK"      :
"",
  -                   (mask & (AP_METHOD_BIT << M_UNLOCK))    ? ", UNLOCK"    :
"",
  -                   ", TRACE",
  -                   NULL);
  +
  +    for (; hi; hi = apr_hash_next(hi)) {
  +        const void *key;
  +        void *val;
  +
  +        apr_hash_this(hi, &key, NULL, &val);
  +        if ((mask & (AP_METHOD_BIT << *(int *)val)) != 0) {
  +            *(const char **)apr_array_push(allow) = key;
  +
  +            /* the M_GET method actually refers to two methods */
  +            if (*(int *)val == M_GET)
  +                *(const char **)apr_array_push(allow) = "HEAD";
  +        }
  +    }
  +
  +    /* TRACE is always allowed */
  +    *(const char **)apr_array_push(allow) = "TRACE";
  +
  +    list = apr_array_pstrcat(r->pool, allow, ',');
  +
  +    /* ### this is rather annoying. we should enforce registration of
  +       ### these methods */
       if ((mask & (AP_METHOD_BIT << M_INVALID))
           && (r->allowed_methods->method_list != NULL)
           && (r->allowed_methods->method_list->nelts != 0)) {
  @@ -987,11 +1122,8 @@
               list = apr_pstrcat(r->pool, list, ", ", xmethod[i], NULL);
           }
       }
  -    /*
  -     * Space past the leading ", ".  Wastes two bytes, but that's better
  -     * than futzing around to find the actual length.
  -     */
  -    return list + 2;
  +
  +    return list;
   }
   
   AP_DECLARE_NONSTD(int) ap_send_http_trace(request_rec *r)
  
  
  
  1.71      +3 -13     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.70
  retrieving revision 1.71
  diff -u -r1.70 -r1.71
  --- http_protocol.h	13 Mar 2002 20:47:42 -0000	1.70
  +++ http_protocol.h	19 Mar 2002 10:11:33 -0000	1.71
  @@ -232,16 +232,6 @@
                                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
  @@ -571,23 +561,23 @@
   AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n, 
                                             apr_size_t *read,
                                             request_rec *r, int fold);
  +
   /**
    * Get the method number associated with the given string, assumed to
    * contain an HTTP method.  Returns M_INVALID if not recognized.
    * @param method A string containing a valid HTTP method
    * @return The method number
  - * @deffunc int ap_method_number_of(const char *method)
    */
   AP_DECLARE(int) ap_method_number_of(const char *method);
   
   /**
    * Get the method name associated with the given internal method
    * number.  Returns NULL if not recognized.
  + * @param p A pool to use for temporary allocations.
    * @param methnum An integer value corresponding to an internal method number
    * @return The name corresponding to the method number
  - * @deffunc const char *ap_method_name_of(int methnum)
    */
  -AP_DECLARE(const char *) ap_method_name_of(int methnum);
  +AP_DECLARE(const char *) ap_method_name_of(apr_pool_t *p, int methnum);
   
   
     /* Hooks */
  
  
  
  1.181     +28 -17    httpd-2.0/include/httpd.h
  
  Index: httpd.h
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/include/httpd.h,v
  retrieving revision 1.180
  retrieving revision 1.181
  diff -u -r1.180 -r1.181
  --- httpd.h	13 Mar 2002 20:47:42 -0000	1.180
  +++ httpd.h	19 Mar 2002 10:11:33 -0000	1.181
  @@ -522,22 +522,33 @@
    * This list must be tracked by the list in http_protocol.c in routine
    * ap_method_name_of().
    */
  -#define M_GET        0
  -#define M_PUT        1
  -#define M_POST       2
  -#define M_DELETE     3
  -#define M_CONNECT    4
  -#define M_OPTIONS    5
  -#define M_TRACE      6
  -#define M_PATCH      7
  -#define M_PROPFIND   8
  -#define M_PROPPATCH  9
  -#define M_MKCOL     10
  -#define M_COPY      11
  -#define M_MOVE      12
  -#define M_LOCK      13
  -#define M_UNLOCK    14
  -#define M_INVALID   15
  +#define M_GET                   0       /* RFC 2616: HTTP */
  +#define M_PUT                   1       /*  :             */
  +#define M_POST                  2
  +#define M_DELETE                3
  +#define M_CONNECT               4
  +#define M_OPTIONS               5
  +#define M_TRACE                 6       /* RFC 2616: HTTP */
  +#define M_PATCH                 7       /* no rfc(!)  ### remove this one? */
  +#define M_PROPFIND              8       /* RFC 2518: WebDAV */
  +#define M_PROPPATCH             9       /*  :               */
  +#define M_MKCOL                 10
  +#define M_COPY                  11
  +#define M_MOVE                  12
  +#define M_LOCK                  13
  +#define M_UNLOCK                14      /* RFC 2518: WebDAV */
  +#define M_VERSION_CONTROL       15      /* RFC 3253: WebDAV Versioning */
  +#define M_CHECKOUT              16      /*  :                          */
  +#define M_UNCHECKOUT            17
  +#define M_CHECKIN               18
  +#define M_UPDATE                19
  +#define M_LABEL                 20
  +#define M_REPORT                21
  +#define M_MKWORKSPACE           22
  +#define M_MKACTIVITY            23
  +#define M_BASELINE_CONTROL      24
  +#define M_MERGE                 25
  +#define M_INVALID               26      /* RFC 3253: WebDAV Versioning */
   
   /**
    * METHODS needs to be equal to the number of bits
  @@ -548,7 +559,7 @@
   /**
    * The method mask bit to shift for anding with a bitmask.
    */
  -#define AP_METHOD_BIT (apr_int64_t)1
  +#define AP_METHOD_BIT ((apr_int64_t)1)
   /** @} */
   
   
  
  
  

Mime
View raw message