/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as
 * applicable.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * 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
 *
 * Usage instructions:
 *
 * Action mime/type /cgi-bin/script
 *
 * will activate /cgi-bin/script when a file of content type mime/type is
 * 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 "apr_strings.h"
#define APR_WANT_STRFUNC
#include "apr_want.h"
#include "ap_config.h"
#include "httpd.h"
#include "http_config.h"
#include "http_request.h"
#include "http_core.h"
#include "http_protocol.h"
#include "http_main.h"
#include "http_log.h"
#include "util_script.h"

typedef struct {
    apr_table_t *action_types;       /* Added with Action... */
    const char *scripted[METHODS];   /* Added with Script... */
    int configured;  /* True if Action or Script has been
                      * called at least once
                      */
} action_dir_config;

module AP_MODULE_DECLARE_DATA actions_module;

static void *create_action_dir_config(apr_pool_t *p, char *dummy)
{
    action_dir_config *new =
    (action_dir_config *) apr_pcalloc(p, sizeof(action_dir_config));

    new->action_types = apr_table_make(p, 4);

    return new;
}

static void *merge_action_dir_configs(apr_pool_t *p, void *basev, void *addv)
{
    action_dir_config *base = (action_dir_config *) basev;
    action_dir_config *add = (action_dir_config *) addv;
    action_dir_config *new = (action_dir_config *) apr_palloc(p,
                                  sizeof(action_dir_config));
    int i;

    new->action_types = apr_table_overlay(p, add->action_types,
                                       base->action_types);

    for (i = 0; i < METHODS; ++i) {
        new->scripted[i] = add->scripted[i] ? add->scripted[i]
                                            : base->scripted[i];
    }

    new->configured = (base->configured || add->configured);
    return new;
}

static const char *add_action(cmd_parms *cmd, void *m_v,
                              const char *type, const char *script,
                              const char *option)
{
    action_dir_config *m = (action_dir_config *)m_v;

    if (option && strcasecmp(option, "virtual")) {
        return apr_pstrcat(cmd->pool,
                           "unrecognized option '", option, "'", NULL);
    }

    apr_table_setn(m->action_types, type,
                   apr_pstrcat(cmd->pool, option ? "1" : "0", script, NULL));
    m->configured = 1;

    return NULL;
}

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;

    /* ap_method_register recognizes already registered methods,
     * so don't bother to check its previous existence explicitely.
     */
    int methnum = ap_method_register(cmd->pool, method);

    if (methnum == M_TRACE) {
        return "TRACE not allowed for Script";
    }
    else if (methnum == M_INVALID) {
        return apr_pstrcat(cmd->pool, "Could not register method '", method,
                           "' for Script", NULL);
    }

    m->scripted[methnum] = script;
    m->configured = 1;

    return NULL;
}

static const command_rec action_cmds[] =
{
    AP_INIT_TAKE23("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, &actions_module);
    const char *t, *action;
    const char *script;
    int i;

    if (!conf->configured) {
        return DECLINED;
    }

    /* Note that this handler handles _all_ types, so handler is unchecked */

    /* Set allowed stuff */
    for (i = 0; i < METHODS; ++i) {
        if (conf->scripted[i])
            r->allowed |= (AP_METHOD_BIT << 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) */
    action = r->handler ? r->handler :
        ap_field_noparam(r->pool, r->content_type);
    action = action ? action : ap_default_type(r);

    if ((t = apr_table_get(conf->action_types, action))) {
        if (*t++ == '0' && r->finfo.filetype == 0) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                          "File does not exist: %s", r->filename);
            return HTTP_NOT_FOUND;
        }

        script = t;
        /* propagate the handler name to the script
         * (will be REDIRECT_HANDLER there)
         */
        apr_table_setn(r->subprocess_env, "HANDLER", action);
    }

    if (script == NULL)
        return DECLINED;

    ap_internal_redirect_handler(apr_pstrcat(r->pool, script,
                                             ap_escape_uri(r->pool, r->uri),
                                             r->args ? "?" : NULL,
                                             r->args, NULL), r);
    return OK;
}

static void register_hooks(apr_pool_t *p)
{
    ap_hook_handler(action_handler,NULL,NULL,APR_HOOK_LAST);
}

module AP_MODULE_DECLARE_DATA actions_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 apr_table_t */
    register_hooks              /* register hooks */
};
