mod_actions.c revision b6055b7832a0e4d0818416252fff5925aaebae4b
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess/* ====================================================================
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * The Apache Software License, Version 1.1
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess *
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * Copyright (c) 2000 The Apache Software Foundation. All rights
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * reserved.
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess *
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * Redistribution and use in source and binary forms, with or without
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * modification, are permitted provided that the following conditions
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * are met:
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess *
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * 1. Redistributions of source code must retain the above copyright
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * notice, this list of conditions and the following disclaimer.
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess *
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * 2. Redistributions in binary form must reproduce the above copyright
27e52281f1522522b170cafc76b08b58aa70ccaand * notice, this list of conditions and the following disclaimer in
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * the documentation and/or other materials provided with the
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * distribution.
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess *
4b5981e276e93df97c34e4da05ca5cf8bbd937dand * 3. The end-user documentation included with the redistribution,
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * if any, must include the following acknowledgment:
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * "This product includes software developed by the
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * Apache Software Foundation (http://www.apache.org/)."
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * Alternately, this acknowledgment may appear in the software itself,
1c8f2418892d98febb00a06b9a4f45f8bcfd80a3nd * if and wherever such third-party acknowledgments normally appear.
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess *
fac8c35bfb158112226ab43ddf84d59daca5dc30nd * 4. The names "Apache" and "Apache Software Foundation" must
d474d8ef01ec5c2a09341cd148851ed383c3287crbowen * not be used to endorse or promote products derived from this
d474d8ef01ec5c2a09341cd148851ed383c3287crbowen * software without prior written permission. For written
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * permission, please contact apache@apache.org.
b03f9485e6dfcf9326e6122f91eaa1ced8939818jim *
b03f9485e6dfcf9326e6122f91eaa1ced8939818jim * 5. Products derived from this software may not be called "Apache",
b03f9485e6dfcf9326e6122f91eaa1ced8939818jim * nor may "Apache" appear in their name, without prior written
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * permission of the Apache Software Foundation.
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess *
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * SUCH DAMAGE.
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * ====================================================================
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess *
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * This software consists of voluntary contributions made by many
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * individuals on behalf of the Apache Software Foundation. For more
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * information on the Apache Software Foundation, please see
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * <http://www.apache.org/>.
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess *
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * Portions of this software are based upon public domain software
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * originally written at the National Center for Supercomputing Applications,
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * University of Illinois, Urbana-Champaign.
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess */
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess/*
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * mod_actions.c: executes scripts based on MIME type or HTTP method
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess *
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * by Alexei Kosut; based on mod_cgi.c, mod_mime.c and mod_includes.c,
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * adapted by rst from original NCSA code by Rob McCool
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess *
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * Usage instructions:
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess *
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * Action mime/type /cgi-bin/script
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess *
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * will activate /cgi-bin/script when a file of content type mime/type is
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * requested. It sends the URL and file path of the requested document using
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * the standard CGI PATH_INFO and PATH_TRANSLATED environment variables.
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess *
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * Script PUT /cgi-bin/script
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess *
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * will activate /cgi-bin/script when a request is received with the
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * HTTP method "PUT". The available method names are defined in httpd.h.
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * If the method is GET, the script will only be activated if the requested
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * URI includes query information (stuff after a ?-mark).
d1348237b33bc1755b9f1165eea52317465a7671nd */
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess#include "apr_strings.h"
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess#include "ap_config.h"
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess#include "httpd.h"
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess#include "http_config.h"
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess#include "http_request.h"
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess#include "http_core.h"
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess#include "http_protocol.h"
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess#include "http_main.h"
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess#include "http_log.h"
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess#include "util_script.h"
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess
e655a84bbb62bb1c66993fda5e74b04feda14dc6kesstypedef struct {
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess ap_table_t *action_types; /* Added with Action... */
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess const char *scripted[METHODS]; /* Added with Script... */
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess} action_dir_config;
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess
e655a84bbb62bb1c66993fda5e74b04feda14dc6kessmodule action_module;
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess
e655a84bbb62bb1c66993fda5e74b04feda14dc6kessstatic void *create_action_dir_config(ap_pool_t *p, char *dummy)
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess{
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess action_dir_config *new =
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess (action_dir_config *) ap_palloc(p, sizeof(action_dir_config));
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess new->action_types = ap_make_table(p, 4);
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess memset(new->scripted, 0, sizeof(new->scripted));
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess return new;
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess}
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess
e655a84bbb62bb1c66993fda5e74b04feda14dc6kessstatic void *merge_action_dir_configs(ap_pool_t *p, void *basev, void *addv)
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess{
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess action_dir_config *base = (action_dir_config *) basev;
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess action_dir_config *add = (action_dir_config *) addv;
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess action_dir_config *new = (action_dir_config *) ap_palloc(p,
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess sizeof(action_dir_config));
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess int i;
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess new->action_types = ap_overlay_tables(p, add->action_types,
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess base->action_types);
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess for (i = 0; i < METHODS; ++i) {
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess new->scripted[i] = add->scripted[i] ? add->scripted[i]
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess : base->scripted[i];
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess }
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess return new;
1c8f2418892d98febb00a06b9a4f45f8bcfd80a3nd}
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess
fac8c35bfb158112226ab43ddf84d59daca5dc30ndstatic const char *add_action(cmd_parms *cmd, void *m_v,
d474d8ef01ec5c2a09341cd148851ed383c3287crbowen const char *type, const char *script)
d474d8ef01ec5c2a09341cd148851ed383c3287crbowen{
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess action_dir_config *m = (action_dir_config *)m_v;
9c1260efa52c82c2a58e5b5f20cd6902563d95f5rbowen ap_table_setn(m->action_types, type, script);
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess return NULL;
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess}
static const char *set_script(cmd_parms *cmd, void *m_v,
const char *method, const char *script)
{
action_dir_config *m = (action_dir_config *)m_v;
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
m->scripted[methnum] = script;
return NULL;
}
static const command_rec action_cmds[] =
{
AP_INIT_TAKE2("Action", add_action, NULL, OR_FILEINFO,
"a media type followed by a script name"),
AP_INIT_TAKE2("Script", set_script, NULL, ACCESS_CONF | RSRC_CONF,
"a method followed by a script name"),
{NULL}
};
static int action_handler(request_rec *r)
{
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 :
ap_field_noparam(r->pool, r->content_type);
const char *script;
int i;
/* Set allowed stuff */
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) {
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)
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)))) {
script = t;
if (r->finfo.protection == 0) {
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
"File does not exist: %s", r->filename);
return HTTP_NOT_FOUND;
}
}
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);
return OK;
}
static const handler_rec action_handlers[] =
{
{"*/*", action_handler},
{NULL}
};
module action_module =
{
STANDARD20_MODULE_STUFF,
create_action_dir_config, /* dir config creater */
merge_action_dir_configs, /* dir merger --- default is to override */
NULL, /* server config */
NULL, /* merge server config */
action_cmds, /* command ap_table_t */
action_handlers, /* handlers */
NULL /* register hooks */
};