home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 15 / CDACTUAL15.iso / LINUX / LINUXISO.S97 / comprimid / apache / mod / mod_speling.c.txt < prev    next >
Encoding:
Text File  |  1997-07-19  |  7.7 KB  |  221 lines

  1.  
  2.  
  3.  
  4. /* ====================================================================
  5.  * Copyright (c) 1996 The Apache Group.  All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer. 
  13.  *
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in
  16.  *    the documentation and/or other materials provided with the
  17.  *    distribution.
  18.  *
  19.  * 3. All advertising materials mentioning features or use of this
  20.  *    software must display the following acknowledgment:
  21.  *    "This product includes software developed by the Apache Group
  22.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  23.  *
  24.  * 4. The names "Apache Server" and "Apache Group" must not be used to
  25.  *    endorse or promote products derived from this software without
  26.  *    prior written permission.
  27.  *
  28.  * 5. Redistributions of any form whatsoever must retain the following
  29.  *    acknowledgment:
  30.  *    "This product includes software developed by the Apache Group
  31.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  32.  *
  33.  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
  34.  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  35.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  36.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
  37.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  38.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  39.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  40.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  41.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  42.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  43.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  44.  * OF THE POSSIBILITY OF SUCH DAMAGE.
  45.  * ====================================================================
  46.  *
  47.  * This software consists of voluntary contributions made by many
  48.  * individuals on behalf of the Apache Group and was originally based
  49.  * on public domain software written at the National Center for
  50.  * Supercomputing Applications, University of Illinois, Urbana-Champaign.
  51.  * For more information on the Apache Group and the Apache HTTP server
  52.  * project, please see <http://www.apache.org/>.
  53.  *
  54.  */
  55.  
  56. #include "httpd.h"
  57. #include "http_config.h"
  58. #include "http_log.h"
  59.  
  60. /* mod_speling.c - by Alexei Kosut <akosut@organic.com> June, 1996
  61.  *
  62.  * This module is transparent, and simple. It attemps to correct
  63.  * mispellings of URLs that users might have entered, namely by checking
  64.  * capitalizations. If it finds a match, it sends a redirect.
  65.  *
  66.  * Activate it with "CheckSpelling On"
  67.  */
  68.  
  69. module speling_module;
  70.  
  71. /* We use the "unconventional" mod_userdir approach here. And heck,
  72.  * here it's just one int!
  73.  */
  74.  
  75. void *create_speling_config (pool *dummy, server_rec *s) { 
  76.     return (void *)0;
  77. }
  78.  
  79. char *set_speling (cmd_parms *cmd, void *dummy, int arg)
  80. {
  81.     void *server_conf = cmd->server->module_config;
  82.     
  83.     set_module_config (server_conf, &speling_module, (void *)arg);
  84.     return NULL;
  85. }
  86.  
  87. command_rec speling_cmds[] = {
  88. { "CheckSpelling", set_speling, NULL, RSRC_CONF, FLAG,
  89.     "whether or not to fix miscapitalized requests" },
  90. { NULL }
  91. };
  92.  
  93.  
  94. int check_speling (request_rec *r)
  95. {
  96.     void *server_conf = r->server->module_config;
  97.     char *good, *bad, *postgood, *url;
  98.     int filoc, dotloc, urlen, pglen;
  99. DIR *dirp;
  100.     struct DIR_TYPE *dir_entry;
  101.  
  102.     if (!(int)get_module_config(server_conf, &speling_module))
  103.       return DECLINED;
  104.  
  105.     /* We only want to worry about GETs */
  106.     if (r->method_number != M_GET) return DECLINED;
  107.  
  108.     /* We've already got a file of some kind or another */
  109.     if (r->proxyreq || (r->finfo.st_mode != 0)) return DECLINED;
  110.  
  111.     /* This is a sub request - don't mess with it */
  112.     if (r->main) return DECLINED;
  113.  
  114.     /* The request should end up looking like this:
  115.      * r->uri: /correct-url/mispelling/more
  116.      * r->filename: /correct-file/mispelling r->path_info: /more
  117.      *
  118.      * So we do this in steps. First break r->filename into two peices
  119.      */
  120.  
  121.     filoc = rind(r->filename, '/');
  122.     if (filoc == -1) return DECLINED;
  123.  
  124.     /* good = /correct-file */
  125.     good = pstrndup(r->pool, r->filename, filoc);
  126.     /* bad = mispelling */
  127.     bad = pstrdup(r->pool, r->filename+filoc+1);
  128.     /* postgood = mispelling/more */
  129.     postgood = pstrcat(r->pool, bad, r->path_info, NULL);
  130.  
  131.     urlen = strlen(r->uri);
  132.     pglen = strlen(postgood);
  133.  
  134.     /* Check to see if the URL peices add up */
  135.     if (strcmp(postgood, r->uri + (urlen-pglen)))
  136.       return DECLINED;
  137.  
  138.     /* url = /correct-url */
  139.     url = pstrndup(r->pool, r->uri, (urlen-pglen));
  140.  
  141.     /* Now open the directory and do ourselves a check... */
  142.     dirp = opendir (good);
  143.     if (dirp == NULL)    /* Oops, not a directory... */
  144.       return DECLINED;
  145.  
  146.     while ((dir_entry = readdir (dirp))) {
  147.       if (!strcasecmp(bad, dir_entry->d_name)) {
  148.     /* Wow... we found us a mispelling. Construct a fixed url */
  149.     char *nuri = pstrcat(r->pool, url, dir_entry->d_name, r->path_info,
  150.                  NULL);
  151.     char *ref = table_get(r->headers_in, "Referer");
  152.     
  153.     table_set(r->headers_out, "Location", construct_url(r->pool,
  154.          nuri, r->server));
  155.     log_error(pstrcat(r->pool, "Fixed spelling: ", r->uri, " to ", nuri,
  156.               ref ? " from " : NULL, ref, NULL), r->server);
  157.     closedir(dirp);
  158.     return REDIRECT;
  159.       }
  160.     }
  161.  
  162.     /* Okay... we didn't find anything. Now we take out the hard-core
  163.      * power tools. There are several cases here. Someone might have
  164.      * entered a wrong extension (.htm instead of .html or vice versa)
  165.      * or the document could be negotated. At any rate, now we just compare
  166.      * stuff before the first dot. If it matches, we figure we got us a
  167.      * match. This can result in wrong things if there are files of
  168.      * different content types but the same prefix (e.g. foo.gif and foo.html)
  169.      * This code will pick the first one it finds. Better than a Not Found,
  170.      * though.
  171.      */
  172.  
  173.     rewinddir(dirp);
  174.  
  175.     dotloc = ind(bad, '.');
  176.     if (dotloc == -1)
  177.       dotloc = strlen(bad);
  178.  
  179.     while ((dir_entry = readdir (dirp))) {
  180.       int entloc = ind(dir_entry->d_name, '.');
  181.       if (entloc == -1)
  182.     entloc = strlen(dir_entry->d_name);
  183.  
  184.       if ((dotloc == entloc) && !strncasecmp(bad, dir_entry->d_name, dotloc)) {
  185.     /* Wow... we found us a mispelling. Construct a fixed url */
  186.     char *nuri = pstrcat(r->pool, url, dir_entry->d_name, r->path_info,
  187.                  NULL);
  188.     char *ref = table_get(r->headers_in, "Referer");
  189.     
  190.     table_set(r->headers_out, "Location", construct_url(r->pool,
  191.          nuri, r->server));
  192.     log_error(pstrcat(r->pool, "Fixed spelling: ", r->uri, " to ", nuri,
  193.               ref ? " from " : NULL, ref, NULL), r->server);
  194.     closedir(dirp);
  195.     return REDIRECT;
  196.       }
  197.     }
  198.  
  199.     closedir(dirp);
  200.  
  201.     return OK;
  202. }
  203.  
  204. module speling_module = {
  205.    STANDARD_MODULE_STUFF,
  206.    NULL,            /* initializer */
  207.    NULL,            /* create per-dir config */
  208.    NULL,            /* merge per-dir config */
  209.    create_speling_config,        /* server config */
  210.    NULL,                   /* merge server config */
  211.    speling_cmds,               /* command table */
  212.    NULL,            /* handlers */
  213.    NULL,            /* filename translation */
  214.    NULL,            /* check_user_id */
  215.    NULL,            /* check auth */
  216.    NULL,            /* check access */
  217.    NULL,            /* type_checker */
  218.    check_speling,             /* fixups */
  219.    NULL                /* logger */
  220. };
  221.