home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 8 / CDACTUAL8.iso / share / os2 / varios / apache / mod_cern.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-01  |  10.1 KB  |  331 lines

  1. /* ====================================================================
  2.  * Copyright (c) 1995 The Apache Group.  All rights reserved.
  3.  *
  4.  * Redistribution and use in source and binary forms, with or without
  5.  * modification, are permitted provided that the following conditions
  6.  * are met:
  7.  *
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer. 
  10.  *
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in
  13.  *    the documentation and/or other materials provided with the
  14.  *    distribution.
  15.  *
  16.  * 3. All advertising materials mentioning features or use of this
  17.  *    software must display the following acknowledgment:
  18.  *    "This product includes software developed by the Apache Group
  19.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  20.  *
  21.  * 4. The names "Apache Server" and "Apache Group" must not be used to
  22.  *    endorse or promote products derived from this software without
  23.  *    prior written permission.
  24.  *
  25.  * 5. Redistributions of any form whatsoever must retain the following
  26.  *    acknowledgment:
  27.  *    "This product includes software developed by the Apache Group
  28.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  29.  *
  30.  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
  31.  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  32.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  33.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
  34.  * IT'S CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  35.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  36.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  37.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  40.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  41.  * OF THE POSSIBILITY OF SUCH DAMAGE.
  42.  * ====================================================================
  43.  *
  44.  * This software consists of voluntary contributions made by many
  45.  * individuals on behalf of the Apache Group and was originally based
  46.  * on public domain software written at the National Center for
  47.  * Supercomputing Applications, University of Illinois, Urbana-Champaign.
  48.  * For more information on the Apache Group and the Apache HTTP server
  49.  * project, please see <http://www.apache.org/>.
  50.  *
  51.  */
  52.  
  53. /*
  54.  * mod_cern_meta.c
  55.  * version 0.0.5
  56.  * status beta
  57.  * 
  58.  * Andrew Wilson <Andrew.Wilson@cm.cf.ac.uk> 25.Jan.96
  59.  *
  60.  * Emulate the CERN HTTPD Meta file semantics.  Meta files are HTTP
  61.  * headers that can be output in addition to the normal range of
  62.  * headers for each file accessed.  They appear rather like the Apache
  63.  * .asis files, and are able to provide a crude way of influencing
  64.  * the Expires: header, as well as providing other curiosities.
  65.  * There are many ways to manage meta information, this one was
  66.  * chosen because there is already a large number of CERN users
  67.  * who can exploit this module.  It should be noted that there are probably
  68.  * more sensitive ways of managing the Expires: header specifically.
  69.  *
  70.  * The module obeys the following directives, which can only appear 
  71.  * in the server's .conf files and not in any .htaccess file.
  72.  *
  73.  *  MetaDir <directory name>
  74.  *      
  75.  *    specifies the name of the directory in which Apache can find
  76.  *    meta information files.  The directory is usually a 'hidden'
  77.  *    subdirectory of the directory that contains the file being
  78.  *    accessed.  eg:
  79.  *
  80.  *        # .meta files are in the *same* directory as the 
  81.  *        # file being accessed
  82.  *        MetaDir .
  83.  *
  84.  *    the default is to look in a '.web' subdirectory. This is the
  85.  *    same as for CERN 3.+ webservers and behaviour is the same as 
  86.  *    for the directive:
  87.  *
  88.  *        MetaDir .web
  89.  *
  90.  *  MetaSuffix <meta file suffix>
  91.  *
  92.  *    specifies the file name suffix for the file containing the
  93.  *    meta information.  eg:
  94.  *
  95.  *       # our meta files are suffixed with '.cern_meta'
  96.  *       MetaSuffix .cern_meta
  97.  *
  98.  *    the default is to look for files with the suffix '.meta'.  This
  99.  *    behaviour is the same as for the directive:
  100.  *
  101.  *       MetaSuffix .meta
  102.  *
  103.  * When accessing the file
  104.  *
  105.  *   DOCUMENT_ROOT/somedir/index.html
  106.  *
  107.  * this module will look for the file
  108.  *
  109.  *   DOCUMENT_ROOT/somedir/.web/index.html.meta
  110.  *
  111.  * and will use its contents to generate additional MIME header 
  112.  * information.
  113.  *
  114.  * For more information on the CERN Meta file semantics see:
  115.  *
  116.  *   http://www.w3.org/hypertext/WWW/Daemon/User/Config/General.html#MetaDir
  117.  *
  118.  * Change-log:
  119.  * 29.Jan.96 pfopen/pfclose instead of fopen/fclose
  120.  *           DECLINE when real file not found, we may be checking each
  121.  *           of the index.html/index.shtml/index.htm variants and don't
  122.  *           need to report missing ones as spurious errors. 
  123.  * 31.Jan.96 log_error reports about a malformed .meta file, rather
  124.  *           than a script error.
  125.  *
  126.  */
  127.  
  128. #include "httpd.h"
  129. #include "http_config.h"
  130. #include <sys/types.h>
  131. #include <sys/stat.h>
  132. #include "util_script.h"
  133. #include "http_log.h"
  134.  
  135. #define DEFAULT_METADIR        ".web"
  136. #define DEFAULT_METASUFFIX    ".meta"
  137.  
  138. module cern_meta_module;
  139.  
  140. typedef struct {
  141.     char *metadir;
  142.     char *metasuffix;
  143. } cern_meta_config;
  144.  
  145. void *create_cern_meta_config (pool *p, server_rec *dummy)
  146. {
  147.     cern_meta_config *new =
  148.       (cern_meta_config *) palloc (p, sizeof(cern_meta_config)); 
  149.  
  150.     new->metadir = DEFAULT_METADIR;
  151.     new->metasuffix = DEFAULT_METASUFFIX;
  152.     
  153.     return new;
  154. }   
  155.  
  156. char *set_metadir (cmd_parms *parms, void *dummy, char *arg)
  157. {       
  158.     cern_meta_config *cmc ;
  159.  
  160.     cmc = get_module_config (parms->server->module_config,
  161.                            &cern_meta_module); 
  162.     cmc->metadir = arg;
  163.     return NULL;
  164. }
  165.  
  166. char *set_metasuffix (cmd_parms *parms, void *dummy, char *arg)
  167. {       
  168.     cern_meta_config *cmc ;
  169.  
  170.     cmc = get_module_config (parms->server->module_config,
  171.                            &cern_meta_module); 
  172.     cmc->metasuffix = arg;
  173.     return NULL;
  174. }
  175.  
  176. command_rec cern_meta_cmds[] = {
  177. { "MetaDir", set_metadir, NULL, RSRC_CONF, TAKE1,
  178.     "the name of the directory containing meta files"},
  179. { "MetaSuffix", set_metasuffix, NULL, RSRC_CONF, TAKE1,
  180.     "the filename suffix for meta files"},
  181. { NULL }
  182. };  
  183.  
  184. int scan_meta_file(request_rec *r, FILE *f)
  185. {
  186.     char w[MAX_STRING_LEN];
  187.     char *l;
  188.     int p;
  189.  
  190.     while( fgets(w, MAX_STRING_LEN-1, f) != NULL ) {
  191.  
  192.     /* Delete terminal (CR?)LF */
  193.     
  194.     p = strlen(w);
  195.     if (p > 0 && w[p-1] == '\n')
  196.     {
  197.         if (p > 1 && w[p-2] == '\015') w[p-2] = '\0';
  198.         else w[p-1] = '\0';
  199.     }
  200.  
  201.         if(w[0] == '\0') {
  202.         return OK;
  203.     }
  204.                                    
  205.     /* if we see a bogus header don't ignore it. Shout and scream */
  206.     
  207.         if(!(l = strchr(w,':'))) {
  208.         log_reason ("malformed header in meta file", r->filename, r);
  209.         return SERVER_ERROR;
  210.         }
  211.  
  212.         *l++ = '\0';
  213.     while (*l && isspace (*l)) ++l;
  214.     
  215.         if(!strcasecmp(w,"Content-type")) {
  216.  
  217.         /* Nuke trailing whitespace */
  218.         
  219.         char *endp = l + strlen(l) - 1;
  220.         while (endp > l && isspace(*endp)) *endp-- = '\0';
  221.         
  222.         r->content_type = pstrdup (r->pool, l);
  223.     }
  224.         else if(!strcasecmp(w,"Status")) {
  225.             sscanf(l, "%d", &r->status);
  226.             r->status_line = pstrdup(r->pool, l);
  227.         }
  228.         else {
  229.         table_set (r->headers_out, w, l);
  230.         }
  231.     }
  232.     return OK;
  233. }
  234.  
  235. int add_cern_meta_data(request_rec *r)
  236. {
  237.     char *metafilename;
  238.     char *last_slash;
  239.     char *real_file;
  240.     char *scrap_book;
  241.     struct stat meta_stat;
  242.     FILE *f;   
  243.     cern_meta_config *cmc ;
  244.     int rv;
  245.  
  246.     cmc = get_module_config (r->server->module_config,
  247.                            &cern_meta_module); 
  248.  
  249.     /* if ./.web/$1.meta exists then output 'asis' */
  250.  
  251.     if (r->finfo.st_mode == 0) {
  252.     return DECLINED;
  253.     };
  254.  
  255.     /* does uri end in a trailing slash? */
  256.     if ( r->uri[strlen(r->uri) - 1] == '/' ) {
  257.     return DECLINED;
  258.     };
  259.  
  260.     /* what directory is this file in? */
  261.     scrap_book = pstrdup( r->pool, r->filename );
  262.     /* skip leading slash, recovered in later processing */
  263.     scrap_book++;
  264.     last_slash = strrchr( scrap_book, '/' );
  265.     if ( last_slash != NULL ) {
  266.     /* skip over last slash */
  267.     real_file = last_slash;
  268.     real_file++;
  269.     *last_slash = '\0';
  270.     } else {
  271.     /* no last slash, buh?! */
  272.         log_reason("internal error in mod_cern_meta", r->filename, r);
  273.     /* should really barf, but hey, let's be friends... */
  274.     return DECLINED;
  275.     };
  276.  
  277.     metafilename = pstrcat(r->pool, "/", scrap_book, "/", cmc->metadir, "/", real_file, cmc->metasuffix, NULL);
  278.  
  279.     /*
  280.      * stat can legitimately fail for a bewildering number of reasons,
  281.      * only one of which implies the file isn't there.  A hardened
  282.      * version of this module should test for all conditions, but later...
  283.      */
  284.     if (stat(metafilename, &meta_stat) == -1) {
  285.     /* stat failed, possibly file missing */
  286.     return DECLINED;
  287.     };
  288.  
  289.     /*
  290.      * this check is to be found in other Jan/96 Apache code, I've
  291.      * not been able to find any corroboration in the man pages but
  292.      * I've been wrong before so I'll put it in anyway.  Never
  293.      * admit to being clueless...
  294.      */
  295.     if ( meta_stat.st_mode == 0 ) {
  296.     /* stat failed, definately file missing */
  297.     return DECLINED;
  298.     };
  299.  
  300.     f = pfopen (r->pool, metafilename, "r");
  301.     
  302.     if (f == NULL) {
  303.         log_reason("meta file permissions deny server access", metafilename, r);
  304.         return FORBIDDEN;
  305.     };
  306.  
  307.     /* read the headers in */
  308.     rv = scan_meta_file(r, f);
  309.     pfclose( r->pool, f );
  310.  
  311.     return rv;
  312. }
  313.  
  314. module cern_meta_module = {
  315.    STANDARD_MODULE_STUFF,
  316.    NULL,            /* initializer */
  317.    NULL,            /* dir config creater */
  318.    NULL,            /* dir merger --- default is to override */
  319.    create_cern_meta_config,    /* server config */
  320.    NULL,            /* merge server configs */
  321.    cern_meta_cmds,        /* command table */
  322.    NULL,            /* handlers */
  323.    NULL,            /* filename translation */
  324.    NULL,            /* check_user_id */
  325.    NULL,            /* check auth */
  326.    NULL,            /* check access */
  327.    NULL,            /* type_checker */
  328.    add_cern_meta_data,        /* fixups */
  329.    NULL,            /* logger */
  330. };
  331.