You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Alexei Kosut <ak...@nueva.pvt.k12.ca.us> on 1996/04/07 03:24:38 UTC

patch for Search, POST-Script, etc...

Following is a patch that, as I indicated earlier, implements in
Apache a CERN feature involving CGI scripts. It allows you to, using
the Search, POST-Script, PUT-Script and DELETE-Script directives to
implement default handlers for GET, POST, PUT and DELETE
methods, respectively. These only come into play if they appear, and
if the specified document is not a CGI script already, or something
else that gets to the request before this does. The Search directive
is only called into play if there are query args (i.e. ?), hence the
name 'Search'.

Note that, in a slight distinction from their CERN equivilents, the
commands take virtual paths (e.g. "PUT-Script /cgi-bin/putfile"), not
filesystem paths (e.g. "PUT-Script /usr/local/etc/httpd/cgi-bin/putfile").
Due to those nice Apache internal redirects, it's much easier to use
virtual paths.

Here's the patch, for review. I will commit it on Monday evening
unless someone objects. Enjoy:

Index: mod_cgi.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_cgi.c,v
retrieving revision 1.6
diff -c -r1.6 mod_cgi.c
*** mod_cgi.c	1996/03/31 01:07:01	1.6
--- mod_cgi.c	1996/04/07 01:17:46
***************
*** 74,79 ****
--- 74,128 ----
  #include "http_log.h"
  #include "util_script.h"

+ typedef struct {
+     char *get;		/* Added with Search */
+     char *post;		/* Added with POST-Script */
+     char *put;		/* Added with PUT-Script */
+     char *delete;	/* Added with DELETE-Script */
+ } cgi_dir_config;
+
+ module cgi_module;
+
+ void *create_cgi_dir_config (pool *p, char *dummy)
+ {
+     cgi_dir_config *new =
+       (cgi_dir_config *) palloc (p, sizeof(cgi_dir_config));
+
+     new->get = NULL;
+     new->post = NULL;
+     new->put = NULL;
+     new->delete = NULL;
+
+     return new;
+ }
+
+ void *merge_cgi_dir_configs (pool *p, void *basev, void *addv)
+ {
+     cgi_dir_config *base = (cgi_dir_config *)basev;
+     cgi_dir_config *add = (cgi_dir_config *)addv;
+     cgi_dir_config *new =
+       (cgi_dir_config *)palloc (p, sizeof(cgi_dir_config));
+
+     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;
+
+     return new;
+ }
+
+ command_rec cgi_cmds[] = {
+ { "Search", set_string_slot, (void*)XtOffsetOf(cgi_dir_config, get),
+     ACCESS_CONF|RSRC_CONF, TAKE1, "a CGI script to handle GET searches" },
+ { "POST-Script", set_string_slot, (void*)XtOffsetOf(cgi_dir_config, post),
+     ACCESS_CONF|RSRC_CONF, TAKE1, "a CGI script to handle POST requests" },
+ { "PUT-Script", set_string_slot, (void*)XtOffsetOf(cgi_dir_config, put),
+     ACCESS_CONF|RSRC_CONF, TAKE1, "a CGI script to handle PUT requests" },
+ { "DELETE-Script", set_string_slot, (void*)XtOffsetOf(cgi_dir_config, delete),
+     ACCESS_CONF|RSRC_CONF, TAKE1, "a CGI script to handle DELETE requests" },
+ { NULL},
+ };
+
  /* KLUDGE --- for back-combatibility, we don't have to check ExecCGI
   * in ScriptAliased directories, which means we need to know if this
   * request came through ScriptAlias or not... so the Alias module
***************
*** 374,393 ****
      return OK;			/* NOT r->status, even if it has changed. */
  }

  handler_rec cgi_handlers[] = {
  { CGI_MAGIC_TYPE, cgi_handler },
  { "cgi-script", cgi_handler },
  { NULL }
  };

  module cgi_module = {
     STANDARD_MODULE_STUFF,
     NULL,			/* initializer */
!    NULL,			/* dir config creater */
!    NULL,			/* dir merger --- default is to override */
     NULL,			/* server config */
     NULL,			/* merge server config */
!    NULL,			/* command table */
     cgi_handlers,		/* handlers */
     NULL,			/* filename translation */
     NULL,			/* check_user_id */
--- 423,470 ----
      return OK;			/* NOT r->status, even if it has changed. */
  }

+ int script_handler  (request_rec *r) {
+   cgi_dir_config *conf =
+     (cgi_dir_config *)get_module_config(r->per_dir_config, &cgi_module);
+   char *script = NULL;
+
+   /* Check for looping, which can happen if the CGI script isn't */
+   if (r->prev && r->prev->prev)
+     return DECLINED;
+
+   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 (script) {
+       internal_redirect(pstrcat(r->pool, script, escape_uri(r->pool, r->uri),
+ 				r->args ? "?" : NULL, r->args, NULL), r);
+       return OK;
+   }
+
+   return DECLINED;
+ }
+
  handler_rec cgi_handlers[] = {
  { CGI_MAGIC_TYPE, cgi_handler },
  { "cgi-script", cgi_handler },
+ { "*/*", script_handler },
  { NULL }
  };

  module cgi_module = {
     STANDARD_MODULE_STUFF,
     NULL,			/* initializer */
!    create_cgi_dir_config,	/* dir config creater */
!    merge_cgi_dir_configs,	/* dir merger --- default is to override */
     NULL,			/* server config */
     NULL,			/* merge server config */
!    cgi_cmds,			/* command table */
     cgi_handlers,		/* handlers */
     NULL,			/* filename translation */
     NULL,			/* check_user_id */


--
________________________________________________________________________
Alexei Kosut <ak...@nueva.pvt.k12.ca.us>
URL: http://www.nueva.pvt.k12.ca.us/~akosut/
Lefler on IRC, DALnet <http://www.dal.net/>