fielding    98/11/08 01:51:12

  Modified:    src      CHANGES
               src/include ap_mmn.h http_protocol.h httpd.h
               src/main http_core.c http_protocol.c
               src/modules/standard mod_actions.c
  Log:
  Enabled all of the WebDAV method names for use by third-party
  modules, Limit, and Script directives.  That includes PATCH,
  PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, and UNLOCK.
  Improved mod_actions.c so that it can use any of the methods
  defined in httpd.h.  Added ap_method_number_of(method) for
  getting the internal method number.
  
  I would have preferred to use a configurable table for new methods,
  but the current API is too dependent on methods being represented as
  a bitmask.  We need to rethink this in the next major server version.
  
  Revision  Changes    Path
  1.1140    +7 -0      apache-1.3/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/CHANGES,v
  retrieving revision 1.1139
  retrieving revision 1.1140
  diff -u -r1.1139 -r1.1140
  --- CHANGES   1998/11/07 14:31:21     1.1139
  +++ CHANGES   1998/11/08 09:51:07     1.1140
  @@ -1,5 +1,12 @@
   Changes with Apache 1.3.4
   
  +  *) Enabled all of the WebDAV method names for use by third-party
  +     modules, Limit, and Script directives.  That includes PATCH,
  +     PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, and UNLOCK.
  +     Improved mod_actions.c so that it can use any of the methods
  +     defined in httpd.h.  Added ap_method_number_of(method) for
  +     getting the internal method number.  [Roy Fielding]
  +
     *) PORT: Add a port to the TPF OS. [Joe Moenich <[EMAIL PROTECTED]> and
        others at IBM]
   
  
  
  
  1.10      +3 -1      apache-1.3/src/include/ap_mmn.h
  
  Index: ap_mmn.h
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/include/ap_mmn.h,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- ap_mmn.h  1998/10/03 18:46:01     1.9
  +++ ap_mmn.h  1998/11/08 09:51:09     1.10
  @@ -181,10 +181,12 @@
    *                        (for implementing better error reporting).
    * 19980906 (1.3.2-dev) - added ap_md5_binary()
    * 19980917 (1.3.2-dev) - bs2000: changed os_set_authfile() to 
os_set_account()
  + * 19981108 (1.3.4-dev) - added ap_method_number_of()
  + *                      - changed value of M_INVALID and added WebDAV methods
    */
   
   #ifndef MODULE_MAGIC_NUMBER_MAJOR
  -#define MODULE_MAGIC_NUMBER_MAJOR 19980917
  +#define MODULE_MAGIC_NUMBER_MAJOR 19981108
   #endif
   #define MODULE_MAGIC_NUMBER_MINOR 0                     /* 0...n */
   #define MODULE_MAGIC_NUMBER MODULE_MAGIC_NUMBER_MAJOR        /* backward 
compat */
  
  
  
  1.46      +5 -0      apache-1.3/src/include/http_protocol.h
  
  Index: http_protocol.h
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/include/http_protocol.h,v
  retrieving revision 1.45
  retrieving revision 1.46
  diff -u -r1.45 -r1.46
  --- http_protocol.h   1998/08/09 14:33:10     1.45
  +++ http_protocol.h   1998/11/08 09:51:09     1.46
  @@ -209,6 +209,11 @@
   
   CORE_EXPORT(void) ap_parse_uri(request_rec *r, const char *uri);
   
  +/* Get the method number associated with the given string, assumed to
  + * contain an HTTP method.  Returns M_INVALID if not recognized.
  + */
  +API_EXPORT(int) ap_method_number_of(const char *method);
  +
   #ifdef __cplusplus
   }
   #endif
  
  
  
  1.251     +21 -9     apache-1.3/src/include/httpd.h
  
  Index: httpd.h
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/include/httpd.h,v
  retrieving revision 1.250
  retrieving revision 1.251
  diff -u -r1.250 -r1.251
  --- httpd.h   1998/11/05 20:07:51     1.250
  +++ httpd.h   1998/11/08 09:51:09     1.251
  @@ -531,16 +531,28 @@
                                       ((x) == HTTP_SERVICE_UNAVAILABLE) || \
                                    ((x) == HTTP_NOT_IMPLEMENTED))
   
  +/* Methods recognized (but not necessarily handled) by the server.
  + * These constants are used in bit shifting masks of size int, so it is
  + * unsafe to have more methods than bits in an int.  HEAD == M_GET.
  + */
  +#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 METHODS 8
  -#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_INVALID 7
  +#define METHODS     15
  +#define M_INVALID   31
   
   #define CGI_MAGIC_TYPE "application/x-httpd-cgi"
   #define INCLUDES_MAGIC_TYPE "text/x-server-parsed-html"
  
  
  
  1.239     +12 -22    apache-1.3/src/main/http_core.c
  
  Index: http_core.c
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/main/http_core.c,v
  retrieving revision 1.238
  retrieving revision 1.239
  diff -u -r1.238 -r1.239
  --- http_core.c       1998/10/30 03:08:55     1.238
  +++ http_core.c       1998/11/08 09:51:10     1.239
  @@ -1068,28 +1068,18 @@
       
       while (limited_methods[0]) {
           char *method = ap_getword_conf(cmd->pool, &limited_methods);
  -     if (!strcmp(method, "GET")) {
  -         limited |= (1 << M_GET);
  -     }
  -     else if (!strcmp(method, "PUT")) {
  -         limited |= (1 << M_PUT);
  -     }
  -     else if (!strcmp(method, "POST")) {
  -         limited |= (1 << M_POST);
  -     }
  -     else if (!strcmp(method, "DELETE")) {
  -         limited |= (1 << M_DELETE);
  -     }
  -        else if (!strcmp(method, "CONNECT")) {
  -         limited |= (1 << M_CONNECT);
  -     }
  -     else if (!strcmp(method, "OPTIONS")) {
  -         limited |= (1 << M_OPTIONS);
  -     }
  -     else {
  -         return ap_pstrcat(cmd->pool, "unknown method \"",
  -                           method, "\" in <Limit>", NULL);
  -     }
  +        int  methnum = ap_method_number_of(method);
  +
  +        if (methnum == M_TRACE) {
  +            return "TRACE cannot be controlled by <Limit>";
  +        }
  +        else if (methnum == M_INVALID) {
  +            return ap_pstrcat(cmd->pool, "unknown method \"",
  +                              method, "\" in <Limit>", NULL);
  +        }
  +        else {
  +            limited |= (1 << methnum);
  +        }
       }
   
       cmd->limited = limited;
  
  
  
  1.248     +85 -25    apache-1.3/src/main/http_protocol.c
  
  Index: http_protocol.c
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/main/http_protocol.c,v
  retrieving revision 1.247
  retrieving revision 1.248
  diff -u -r1.247 -r1.248
  --- http_protocol.c   1998/10/30 22:41:24     1.247
  +++ http_protocol.c   1998/11/08 09:51:11     1.248
  @@ -517,6 +517,72 @@
                 ap_gm_timestr_822(r->pool, mod_time));
   }
   
  +/* Get the method number associated with the given string, assumed to
  + * contain an HTTP method.  Returns M_INVALID if not recognized.
  + *
  + * This is the first step toward placing method names in a configurable
  + * list.  Hopefully it (and other routines) can eventually be moved to
  + * something like a mod_http_methods.c, complete with config stuff.
  + */
  +API_EXPORT(int) ap_method_number_of(const char *method)
  +{
  +    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;
  +    }
  +    return M_INVALID;
  +}
  +
   /* Get a line of protocol input, including any continuation lines
    * caused by MIME folding (or broken clients) if fold != 0, and place it
    * in the buffer s, of size n bytes, without the ending newline.
  @@ -678,26 +744,11 @@
       uri = ap_getword_white(r->pool, &ll);
   
       /* Provide quick information about the request method as soon as known */
  -    if (!strcmp(r->method, "HEAD")) {
  +
  +    r->method_number = ap_method_number_of(r->method);
  +    if (r->method_number == M_GET && r->method[0] == 'H') {
           r->header_only = 1;
  -        r->method_number = M_GET;
       }
  -    else if (!strcmp(r->method, "GET"))
  -        r->method_number = M_GET;
  -    else if (!strcmp(r->method, "POST"))
  -        r->method_number = M_POST;
  -    else if (!strcmp(r->method, "PUT"))
  -        r->method_number = M_PUT;
  -    else if (!strcmp(r->method, "DELETE"))
  -        r->method_number = M_DELETE;
  -    else if (!strcmp(r->method, "CONNECT"))
  -        r->method_number = M_CONNECT;
  -    else if (!strcmp(r->method, "OPTIONS"))
  -        r->method_number = M_OPTIONS;
  -    else if (!strcmp(r->method, "TRACE"))
  -        r->method_number = M_TRACE;
  -    else
  -        r->method_number = M_INVALID;   /* Will eventually croak. */
   
       ap_parse_uri(r, uri);
   
  @@ -1237,13 +1288,22 @@
   static char *make_allow(request_rec *r)
   {
       return 2 + ap_pstrcat(r->pool,
  -                       (r->allowed & (1 << M_GET)) ? ", GET, HEAD" : "",
  -                       (r->allowed & (1 << M_POST)) ? ", POST" : "",
  -                       (r->allowed & (1 << M_PUT)) ? ", PUT" : "",
  -                       (r->allowed & (1 << M_DELETE)) ? ", DELETE" : "",
  -                       (r->allowed & (1 << M_OPTIONS)) ? ", OPTIONS" : "",
  -                       ", TRACE",
  -                       NULL);
  +                   (r->allowed & (1 << M_GET))       ? ", GET, HEAD" : "",
  +                   (r->allowed & (1 << M_POST))      ? ", POST"      : "",
  +                   (r->allowed & (1 << M_PUT))       ? ", PUT"       : "",
  +                   (r->allowed & (1 << M_DELETE))    ? ", DELETE"    : "",
  +                   (r->allowed & (1 << M_CONNECT))   ? ", CONNECT"   : "",
  +                   (r->allowed & (1 << M_OPTIONS))   ? ", OPTIONS"   : "",
  +                   (r->allowed & (1 << M_PATCH))     ? ", PATCH"     : "",
  +                   (r->allowed & (1 << M_PROPFIND))  ? ", PROPFIND"  : "",
  +                   (r->allowed & (1 << M_PROPPATCH)) ? ", PROPPATCH" : "",
  +                   (r->allowed & (1 << M_MKCOL))     ? ", MKCOL"     : "",
  +                   (r->allowed & (1 << M_COPY))      ? ", COPY"      : "",
  +                   (r->allowed & (1 << M_MOVE))      ? ", MOVE"      : "",
  +                   (r->allowed & (1 << M_LOCK))      ? ", LOCK"      : "",
  +                   (r->allowed & (1 << M_UNLOCK))    ? ", UNLOCK"    : "",
  +                   ", TRACE",
  +                   NULL);
   }
   
   API_EXPORT(int) ap_send_http_trace(request_rec *r)
  
  
  
  1.29      +44 -47    apache-1.3/src/modules/standard/mod_actions.c
  
  Index: mod_actions.c
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/modules/standard/mod_actions.c,v
  retrieving revision 1.28
  retrieving revision 1.29
  diff -u -r1.28 -r1.29
  --- mod_actions.c     1998/08/06 17:30:53     1.28
  +++ mod_actions.c     1998/11/08 09:51:12     1.29
  @@ -56,7 +56,7 @@
    */
   
   /*
  - * mod_actions.c: executes scripts based on MIME type
  + * mod_actions.c: executes scripts based on MIME type or HTTP method
    *
    * by Alexei Kosut; based on mod_cgi.c, mod_mime.c and mod_includes.c,
    * adapted by rst from original NCSA code by Rob McCool
  @@ -69,6 +69,12 @@
    * requested. It sends the URL and file path of the requested document using 
    * the standard CGI PATH_INFO and PATH_TRANSLATED environment variables.
    *
  + * Script PUT /cgi-bin/script
  + *
  + * will activate /cgi-bin/script when a request is received with the
  + * HTTP method "PUT".  The available method names are defined in httpd.h.
  + * If the method is GET, the script will only be activated if the requested
  + * URI includes query information (stuff after a ?-mark).
    */
   
   #include "httpd.h"
  @@ -81,11 +87,8 @@
   #include "util_script.h"
   
   typedef struct {
  -    table *action_types;     /* Added with Action... */
  -    char *get;                       /* Added with Script GET */
  -    char *post;                      /* Added with Script POST */
  -    char *put;                       /* Added with Script PUT */
  -    char *delete;            /* Added with Script DELETE */
  +    table *action_types;       /* Added with Action... */
  +    char *scripted[METHODS];   /* Added with Script... */
   } action_dir_config;
   
   module action_module;
  @@ -96,10 +99,7 @@
       (action_dir_config *) ap_palloc(p, sizeof(action_dir_config));
   
       new->action_types = ap_make_table(p, 4);
  -    new->get = NULL;
  -    new->post = NULL;
  -    new->put = NULL;
  -    new->delete = NULL;
  +    memset(new->scripted, 0, sizeof(new->scripted));
   
       return new;
   }
  @@ -108,17 +108,17 @@
   {
       action_dir_config *base = (action_dir_config *) basev;
       action_dir_config *add = (action_dir_config *) addv;
  -    action_dir_config *new =
  -    (action_dir_config *) ap_palloc(p, sizeof(action_dir_config));
  +    action_dir_config *new = (action_dir_config *) ap_palloc(p,
  +                                  sizeof(action_dir_config));
  +    int i;
   
       new->action_types = ap_overlay_tables(p, add->action_types,
                                       base->action_types);
   
  -    new->get = add->get ? add->get : base->get;
  -    new->post = add->post ? add->post : base->post;
  -    new->put = add->put ? add->put : base->put;
  -    new->delete = add->delete ? add->delete : base->delete;
  -
  +    for (i = 0; i < METHODS; ++i) {
  +        new->scripted[i] = add->scripted[i] ? add->scripted[i]
  +                                            : base->scripted[i];
  +    }
       return new;
   }
   
  @@ -129,19 +129,18 @@
       return NULL;
   }
   
  -static const char *set_script(cmd_parms *cmd, action_dir_config * m, char 
*method,
  -                           char *script)
  +static const char *set_script(cmd_parms *cmd, action_dir_config * m,
  +                              char *method, char *script)
   {
  -    if (!strcmp(method, "GET"))
  -     m->get = script;
  -    else if (!strcmp(method, "POST"))
  -     m->post = script;
  -    else if (!strcmp(method, "PUT"))
  -     m->put = script;
  -    else if (!strcmp(method, "DELETE"))
  -     m->delete = script;
  +    int methnum;
  +
  +    methnum = ap_method_number_of(method);
  +    if (methnum == M_TRACE)
  +        return "TRACE not allowed for Script";
  +    else if (methnum == M_INVALID)
  +        return "Unknown method type for Script";
       else
  -     return "Unknown method type for Script";
  +        m->scripted[methnum] = script;
   
       return NULL;
   }
  @@ -157,30 +156,28 @@
   
   static int action_handler(request_rec *r)
   {
  -    action_dir_config *conf =
  -    (action_dir_config *) ap_get_module_config(r->per_dir_config, 
&action_module);
  +    action_dir_config *conf = (action_dir_config *)
  +        ap_get_module_config(r->per_dir_config, &action_module);
       const char *t, *action = r->handler ? r->handler : r->content_type;
  -    const char *script = NULL;
  +    const char *script;
  +    int i;
   
       /* Set allowed stuff */
  -    if (conf->get)
  -     r->allowed |= (1 << M_GET);
  -    if (conf->post)
  -     r->allowed |= (1 << M_POST);
  -    if (conf->put)
  -     r->allowed |= (1 << M_PUT);
  -    if (conf->delete)
  -     r->allowed |= (1 << M_DELETE);
  +    for (i = 0; i < METHODS; ++i) {
  +        if (conf->scripted[i])
  +            r->allowed |= (1 << i);
  +    }
   
       /* First, check for the method-handling scripts */
  -    if ((r->method_number == M_GET) && r->args && conf->get)
  -     script = conf->get;
  -    else if ((r->method_number == M_POST) && conf->post)
  -     script = conf->post;
  -    else if ((r->method_number == M_PUT) && conf->put)
  -     script = conf->put;
  -    else if ((r->method_number == M_DELETE) && conf->delete)
  -     script = conf->delete;
  +    if (r->method_number == M_GET) {
  +        if (r->args)
  +            script = conf->scripted[M_GET];
  +        else
  +            script = NULL;
  +    }
  +    else {
  +        script = conf->scripted[r->method_number];
  +    }
   
       /* Check for looping, which can happen if the CGI script isn't */
       if (script && r->prev && r->prev->prev)
  
  
  

Reply via email to