coar 99/12/08 11:02:24
Modified: src CHANGES src/modules/standard mod_actions.c htdocs/manual/mod mod_actions.html Log: Add ability to handle arbitrary methods to Script directive. Revision Changes Path 1.1473 +6 -0 apache-1.3/src/CHANGES Index: CHANGES =================================================================== RCS file: /home/cvs/apache-1.3/src/CHANGES,v retrieving revision 1.1472 retrieving revision 1.1473 diff -u -r1.1472 -r1.1473 --- CHANGES 1999/12/06 22:33:57 1.1472 +++ CHANGES 1999/12/08 19:01:13 1.1473 @@ -1,5 +1,11 @@ Changes with Apache 1.3.10 + *) Enhance mod_actions' Script handling to be able to deal with + arbitrary methods and not just the well-known ones. This allows + experimental or organisation-private methods to be used without + waiting for Apache to catch up. + [Ken Coar] + *) Fix various compile time warnings in hashbang_emul code which prevent successful compilation on OS/390 [Ovies Brabson <[EMAIL PROTECTED]>, Paul Gilmartin <[EMAIL PROTECTED]>] 1.32 +83 -21 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.31 retrieving revision 1.32 diff -u -r1.31 -r1.32 --- mod_actions.c 1999/01/01 19:05:06 1.31 +++ mod_actions.c 1999/12/08 19:01:48 1.32 @@ -87,8 +87,18 @@ #include "util_script.h" typedef struct { + char *method; + char *script; +} xmethod_t; + +/* + * HTTP methods are case-sensitive, so we can't use a table structure to + * track extension method mappings -- table keys are case-INsensitive. + */ +typedef struct { table *action_types; /* Added with Action... */ char *scripted[METHODS]; /* Added with Script... */ + array_header *xmethods; /* Added with Script -- extension methods */ } action_dir_config; module action_module; @@ -96,11 +106,11 @@ static void *create_action_dir_config(pool *p, char *dummy) { action_dir_config *new = - (action_dir_config *) ap_palloc(p, sizeof(action_dir_config)); + (action_dir_config *) ap_palloc(p, sizeof(action_dir_config)); new->action_types = ap_make_table(p, 4); memset(new->scripted, 0, sizeof(new->scripted)); - + new->xmethods = ap_make_array(p, 4, sizeof(xmethod_t)); return new; } @@ -119,29 +129,56 @@ new->scripted[i] = add->scripted[i] ? add->scripted[i] : base->scripted[i]; } + new->xmethods = ap_append_arrays(p, add->xmethods, base->xmethods); return new; } -static const char *add_action(cmd_parms *cmd, action_dir_config * m, char *type, +static const char *add_action(cmd_parms *cmd, action_dir_config *m, char *type, char *script) { ap_table_setn(m->action_types, type, script); return NULL; } -static const char *set_script(cmd_parms *cmd, action_dir_config * m, +static const char *set_script(cmd_parms *cmd, action_dir_config *m, char *method, char *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 + if (methnum == M_TRACE) { + return "TRACE not allowed for Script"; + } + else if (methnum != M_INVALID) { m->scripted[methnum] = script; - + } + else { + /* + * We used to return "Unknown method type for Script" + * but now we actually handle unknown methods. + */ + xmethod_t *xm; + xmethod_t *list; + int i; + + /* + * Scan through the list; if the method already has a script + * defined, overwrite it. Otherwise, add it. + */ + list = (xmethod_t *) m->xmethods->elts; + for (i = 0; i < m->xmethods->nelts; ++i) { + xm = &list[i]; + if (strcmp(method, xm->method) == 0) { + xm->script = script; + break; + } + } + if (i <= m->xmethods->nelts) { + xm = ap_push_array(m->xmethods); + xm->method = method; + xm->script = script; + } + } return NULL; } @@ -164,41 +201,66 @@ /* Set allowed stuff */ for (i = 0; i < METHODS; ++i) { - if (conf->scripted[i]) - r->allowed |= (1 << i); + if (conf->scripted[i]) { + r->allowed |= (1 << i); + } } /* First, check for the method-handling scripts */ if (r->method_number == M_GET) { - if (r->args) + if (r->args) { script = conf->scripted[M_GET]; - else + } + else { script = NULL; + } } else { - script = conf->scripted[r->method_number]; + if (r->method_number != M_INVALID) { + script = conf->scripted[r->method_number]; + } + else { + int j; + xmethod_t *xm; + xmethod_t *list; + + script = NULL; + list = (xmethod_t *) conf->xmethods->elts; + for (j = 0; j < conf->xmethods->nelts; ++j) { + xm = &list[j]; + if (strcmp(r->method, xm->method) == 0) { + script = xm->script; + break; + } + } + } } /* Check for looping, which can happen if the CGI script isn't */ - if (script && r->prev && r->prev->prev) + if (script && r->prev && r->prev->prev) { return DECLINED; + } /* Second, check for actions (which override the method scripts) */ if ((t = ap_table_get(conf->action_types, - action ? action : ap_default_type(r)))) { + action ? action : ap_default_type(r)))) { script = t; if (r->finfo.st_mode == 0) { ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, - "File does not exist: %s", r->filename); + "File does not exist: %s", r->filename); return NOT_FOUND; } } - if (script == NULL) + if (script == NULL) { return DECLINED; + } - ap_internal_redirect_handler(ap_pstrcat(r->pool, script, ap_escape_uri(r->pool, - r->uri), r->args ? "?" : NULL, r->args, NULL), r); + ap_internal_redirect_handler(ap_pstrcat(r->pool, script, + ap_escape_uri(r->pool, + r->uri), + r->args ? "?" : NULL, + r->args, NULL), r); return OK; } 1.14 +11 -5 apache-1.3/htdocs/manual/mod/mod_actions.html Index: mod_actions.html =================================================================== RCS file: /home/cvs/apache-1.3/htdocs/manual/mod/mod_actions.html,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- mod_actions.html 1998/11/18 09:15:27 1.13 +++ mod_actions.html 1999/12/08 19:02:19 1.14 @@ -94,17 +94,23 @@ HREF="directive-dict.html#Compatibility" REL="Help" ><STRONG>Compatibility:</STRONG></A> Script is only available in Apache 1.1 -and later +and later; arbitrary method use is only available with 1.3.10 and later </P> <P> -This directive adds an action, which will activate <EM>cgi-script</EM> when -a file is requested using the method of <EM>method</EM>, which can be -one of <CODE>GET</CODE>, <CODE>POST</CODE>, <CODE>PUT</CODE> or -<CODE>DELETE</CODE>. It sends the +This directive adds an action, which will activate <i>cgi-script</i> when +a file is requested using the method of <i>method</i>. It sends the URL and file path of the requested document using the standard CGI PATH_INFO and PATH_TRANSLATED environment variables. </P> +<blockquote> +Prior to Apache 1.3.10, <i>method</i> can only be +one of <code>GET</code>, <code>POST</code>, <code>PUT</code>, or +<code>DELETE</code>. As of 1.3.10, any arbitrary method name +may be used. <b>Method names are case-sensitive</b>, so +<code>Script PUT</code> and <code>Script put</code> +have two entirely different effects. +</blockquote> <P> Note that the Script command defines default actions only. If a CGI script is called, or some other resource that is capable of handling