/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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_cern_meta.c
 * version 0.1.0
 * status beta
 *
 * Andrew Wilson <Andrew.Wilson@cm.cf.ac.uk> 25.Jan.96
 *
 * *** IMPORTANT ***
 * This version of mod_cern_meta.c controls Meta File behaviour on a
 * per-directory basis.  Previous versions of the module defined behaviour
 * on a per-server basis.  The upshot is that you'll need to revisit your
 * configuration files in order to make use of the new module.
 * ***
 *
 * Emulate the CERN HTTPD Meta file semantics.  Meta files are HTTP
 * headers that can be output in addition to the normal range of
 * headers for each file accessed.  They appear rather like the Apache
 * .asis files, and are able to provide a crude way of influencing
 * the Expires: header, as well as providing other curiosities.
 * There are many ways to manage meta information, this one was
 * chosen because there is already a large number of CERN users
 * who can exploit this module.  It should be noted that there are probably
 * more sensitive ways of managing the Expires: header specifically.
 *
 * The module obeys the following directives, which can appear
 * in the server's .conf files and in .htaccess files.
 *
 *  MetaFiles <on|off>
 *
 *    turns on|off meta file processing for any directory.
 *    Default value is off
 *
 *        # turn on MetaFiles in this directory
 *        MetaFiles on
 *
 *  MetaDir <directory name>
 *
 *    specifies the name of the directory in which Apache can find
 *    meta information files.  The directory is usually a 'hidden'
 *    subdirectory of the directory that contains the file being
 *    accessed.  eg:
 *
 *        # .meta files are in the *same* directory as the
 *        # file being accessed
 *        MetaDir .
 *
 *    the default is to look in a '.web' subdirectory. This is the
 *    same as for CERN 3.+ webservers and behaviour is the same as
 *    for the directive:
 *
 *        MetaDir .web
 *
 *  MetaSuffix <meta file suffix>
 *
 *    specifies the file name suffix for the file containing the
 *    meta information.  eg:
 *
 *       # our meta files are suffixed with '.cern_meta'
 *       MetaSuffix .cern_meta
 *
 *    the default is to look for files with the suffix '.meta'.  This
 *    behaviour is the same as for the directive:
 *
 *       MetaSuffix .meta
 *
 * When accessing the file
 *
 *   DOCUMENT_ROOT/somedir/index.html
 *
 * this module will look for the file
 *
 *   DOCUMENT_ROOT/somedir/.web/index.html.meta
 *
 * and will use its contents to generate additional MIME header
 * information.
 *
 * For more information on the CERN Meta file semantics see:
 *
 *   http://www.w3.org/hypertext/WWW/Daemon/User/Config/General.html#MetaDir
 *
 * Change-log:
 * 29.Jan.96 pfopen/pfclose instead of fopen/fclose
 *           DECLINE when real file not found, we may be checking each
 *           of the index.html/index.shtml/index.htm variants and don't
 *           need to report missing ones as spurious errors.
 * 31.Jan.96 log_error reports about a malformed .meta file, rather
 *           than a script error.
 * 20.Jun.96 MetaFiles <on|off> default off, added, so that module
 *           can be configured per-directory.  Prior to this the module
 *           was running for each request anywhere on the server, naughty..
 * 29.Jun.96 All directives made per-directory.
 */

#include "apr.h"
#include "apr_strings.h"

#define APR_WANT_STRFUNC
#include "apr_want.h"

#if APR_HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#include "ap_config.h"
#include "httpd.h"
#include "http_config.h"
#include "util_script.h"
#include "http_log.h"
#include "http_request.h"
#include "http_protocol.h"
#include "apr_lib.h"

#define DIR_CMD_PERMS OR_INDEXES

#define DEFAULT_METADIR     ".web"
#define DEFAULT_METASUFFIX  ".meta"
#define DEFAULT_METAFILES   0

module AP_MODULE_DECLARE_DATA cern_meta_module;

typedef struct {
    const char *metadir;
    const char *metasuffix;
    int metafiles;
} cern_meta_dir_config;

static void *create_cern_meta_dir_config(apr_pool_t *p, char *dummy)
{
    cern_meta_dir_config *new =
    (cern_meta_dir_config *) apr_palloc(p, sizeof(cern_meta_dir_config));

    new->metadir = NULL;
    new->metasuffix = NULL;
    new->metafiles = DEFAULT_METAFILES;

    return new;
}

static void *merge_cern_meta_dir_configs(apr_pool_t *p, void *basev, void *addv)
{
    cern_meta_dir_config *base = (cern_meta_dir_config *) basev;
    cern_meta_dir_config *add = (cern_meta_dir_config *) addv;
    cern_meta_dir_config *new =
    (cern_meta_dir_config *) apr_palloc(p, sizeof(cern_meta_dir_config));

    new->metadir = add->metadir ? add->metadir : base->metadir;
    new->metasuffix = add->metasuffix ? add->metasuffix : base->metasuffix;
    new->metafiles = add->metafiles;

    return new;
}

static const char *set_metadir(cmd_parms *parms, void *in_dconf, const char *arg)
{
    cern_meta_dir_config *dconf = in_dconf;

    dconf->metadir = arg;
    return NULL;
}

static const char *set_metasuffix(cmd_parms *parms, void *in_dconf, const char *arg)
{
    cern_meta_dir_config *dconf = in_dconf;

    dconf->metasuffix = arg;
    return NULL;
}

static const char *set_metafiles(cmd_parms *parms, void *in_dconf, int arg)
{
    cern_meta_dir_config *dconf = in_dconf;

    dconf->metafiles = arg;
    return NULL;
}


static const command_rec cern_meta_cmds[] =
{
    AP_INIT_FLAG("MetaFiles", set_metafiles, NULL, DIR_CMD_PERMS,
                 "Limited to 'on' or 'off'"),
    AP_INIT_TAKE1("MetaDir", set_metadir, NULL, DIR_CMD_PERMS,
                  "the name of the directory containing meta files"),
    AP_INIT_TAKE1("MetaSuffix", set_metasuffix, NULL, DIR_CMD_PERMS,
                  "the filename suffix for meta files"),
    {NULL}
};

/* XXX: this is very similar to ap_scan_script_header_err_core...
 * are the differences deliberate, or just a result of bit rot?
 */
static int scan_meta_file(request_rec *r, apr_file_t *f)
{
    char w[MAX_STRING_LEN];
    char *l;
    int p;
    apr_table_t *tmp_headers;

    tmp_headers = apr_table_make(r->pool, 5);
    while (apr_file_gets(w, MAX_STRING_LEN - 1, f) == APR_SUCCESS) {

    /* Delete terminal (CR?)LF */
        p = strlen(w);
        if (p > 0 && w[p - 1] == '\n') {
            if (p > 1 && w[p - 2] == '\015')
                w[p - 2] = '\0';
            else
                w[p - 1] = '\0';
        }

        if (w[0] == '\0') {
            return OK;
        }

        /* if we see a bogus header don't ignore it. Shout and scream */

        if (!(l = strchr(w, ':'))) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01560)
                "malformed header in meta file: %s", r->filename);
            return HTTP_INTERNAL_SERVER_ERROR;
        }

        *l++ = '\0';
        while (apr_isspace(*l))
            ++l;

        if (!ap_cstr_casecmp(w, "Content-type")) {
            char *tmp;
            /* Nuke trailing whitespace */

            char *endp = l + strlen(l) - 1;
            while (endp > l && apr_isspace(*endp))
                *endp-- = '\0';

            tmp = apr_pstrdup(r->pool, l);
            ap_content_type_tolower(tmp);
            ap_set_content_type(r, tmp);
        }
        else if (!ap_cstr_casecmp(w, "Status")) {
            sscanf(l, "%d", &r->status);
            r->status_line = apr_pstrdup(r->pool, l);
        }
        else {
            apr_table_set(tmp_headers, w, l);
        }
    }
    apr_table_overlap(r->headers_out, tmp_headers, APR_OVERLAP_TABLES_SET);
    return OK;
}

static int add_cern_meta_data(request_rec *r)
{
    char *metafilename;
    char *leading_slash;
    char *last_slash;
    char *real_file;
    char *scrap_book;
    apr_file_t *f = NULL;
    apr_status_t retcode;
    cern_meta_dir_config *dconf;
    int rv;
    request_rec *rr;

    dconf = ap_get_module_config(r->per_dir_config, &cern_meta_module);

    if (!dconf->metafiles) {
        return DECLINED;
    }

    /* if ./.web/$1.meta exists then output 'asis' */

    if (r->finfo.filetype == APR_NOFILE) {
        return DECLINED;
    }

    /* is this a directory? */
    if (r->finfo.filetype == APR_DIR || r->uri[strlen(r->uri) - 1] == '/') {
        return DECLINED;
    }

    /* what directory is this file in? */
    scrap_book = apr_pstrdup(r->pool, r->filename);

    leading_slash = strchr(scrap_book, '/');
    last_slash = strrchr(scrap_book, '/');
    if ((last_slash != NULL) && (last_slash != leading_slash)) {
        /* skip over last slash */
        real_file = last_slash;
        real_file++;
        *last_slash = '\0';
    }
    else {
        /* no last slash, buh?! */
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01561)
            "internal error in mod_cern_meta: %s", r->filename);
        /* should really barf, but hey, let's be friends... */
        return DECLINED;
    }

    metafilename = apr_pstrcat(r->pool, scrap_book, "/",
               dconf->metadir ? dconf->metadir : DEFAULT_METADIR,
               "/", real_file,
         dconf->metasuffix ? dconf->metasuffix : DEFAULT_METASUFFIX,
               NULL);

    /* It sucks to require this subrequest to complete, because this
     * means people must leave their meta files accessible to the world.
     * A better solution might be a "safe open" feature of pfopen to avoid
     * pipes, symlinks, and crap like that.
     *
     * In fact, this doesn't suck.  Because <Location > blocks are never run
     * against sub_req_lookup_file, the meta can be somewhat protected by
     * either masking it with a <Location > directive or alias, or stowing
     * the file outside of the web document tree, while providing the
     * appropriate directory blocks to allow access to it as a file.
     */
    rr = ap_sub_req_lookup_file(metafilename, r, NULL);
    if (rr->status != HTTP_OK) {
        ap_destroy_sub_req(rr);
        return DECLINED;
    }
    ap_destroy_sub_req(rr);

    retcode = apr_file_open(&f, metafilename, APR_READ, APR_OS_DEFAULT, r->pool);
    if (retcode != APR_SUCCESS) {
        if (APR_STATUS_IS_ENOENT(retcode)) {
            return DECLINED;
        }
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01562)
            "meta file permissions deny server access: %s", metafilename);
        return HTTP_FORBIDDEN;
    }

    /* read the headers in */
    rv = scan_meta_file(r, f);
    apr_file_close(f);

    return rv;
}

static void register_hooks(apr_pool_t *p)
{
    ap_hook_fixups(add_cern_meta_data,NULL,NULL,APR_HOOK_MIDDLE);
}

AP_DECLARE_MODULE(cern_meta) =
{
    STANDARD20_MODULE_STUFF,
    create_cern_meta_dir_config, /* dir config creater */
    merge_cern_meta_dir_configs, /* dir merger --- default is to override */
    NULL,                        /* server config */
    NULL,                        /* merge server configs */
    cern_meta_cmds,              /* command apr_table_t */
    register_hooks               /* register hooks */
};
