⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_speling.c

📁 Apache官方在今天放出产品系列2.2的最新版本2.2.11的源码包 最流行的HTTP服务器软件之一
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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. */#include "apr.h"#include "apr_file_io.h"#include "apr_strings.h"#include "apr_lib.h"#define APR_WANT_STRFUNC#include "apr_want.h"#define WANT_BASENAME_MATCH#include "httpd.h"#include "http_core.h"#include "http_config.h"#include "http_request.h"#include "http_log.h"/* mod_speling.c - by Alexei Kosut <akosut@organic.com> June, 1996 * * This module is transparent, and simple. It attempts to correct * misspellings of URLs that users might have entered, namely by checking * capitalizations. If it finds a match, it sends a redirect. * * Sep-1999 Hugo Haas <hugo@w3.org> * o Added a CheckCaseOnly option to check only miscapitalized words. * * 08-Aug-1997 <Martin.Kraemer@Mch.SNI.De> * o Upgraded module interface to apache_1.3a2-dev API (more NULL's in *   speling_module). * o Integrated tcsh's "spelling correction" routine which allows one *   misspelling (character insertion/omission/typo/transposition). *   Rewrote it to ignore case as well. This ought to catch the majority *   of misspelled requests. * o Commented out the second pass where files' suffixes are stripped. *   Given the better hit rate of the first pass, this rather ugly *   (request index.html, receive index.db ?!?!) solution can be *   omitted. * o wrote a "kind of" html page for mod_speling * * Activate it with "CheckSpelling On" */module AP_MODULE_DECLARE_DATA speling_module;typedef struct {    int enabled;    int case_only;} spconfig;/* * Create a configuration specific to this module for a server or directory * location, and fill it with the default settings. * * The API says that in the absence of a merge function, the record for the * closest ancestor is used exclusively.  That's what we want, so we don't * bother to have such a function. */static void *mkconfig(apr_pool_t *p){    spconfig *cfg = apr_pcalloc(p, sizeof(spconfig));    cfg->enabled = 0;    cfg->case_only = 0;    return cfg;}/* * Respond to a callback to create configuration record for a server or * vhost environment. */static void *create_mconfig_for_server(apr_pool_t *p, server_rec *s){    return mkconfig(p);}/* * Respond to a callback to create a config record for a specific directory. */static void *create_mconfig_for_directory(apr_pool_t *p, char *dir){    return mkconfig(p);}/* * Define the directives specific to this module.  This structure is referenced * later by the 'module' structure. */static const command_rec speling_cmds[] ={    AP_INIT_FLAG("CheckSpelling", ap_set_flag_slot,                  (void*)APR_OFFSETOF(spconfig, enabled), OR_OPTIONS,                 "whether or not to fix miscapitalized/misspelled requests"),    AP_INIT_FLAG("CheckCaseOnly", ap_set_flag_slot,                  (void*)APR_OFFSETOF(spconfig, case_only), OR_OPTIONS,                  "whether or not to fix only miscapitalized requests"),    { NULL }};typedef enum {    SP_IDENTICAL = 0,    SP_MISCAPITALIZED = 1,    SP_TRANSPOSITION = 2,    SP_MISSINGCHAR = 3,    SP_EXTRACHAR = 4,    SP_SIMPLETYPO = 5,    SP_VERYDIFFERENT = 6} sp_reason;static const char *sp_reason_str[] ={    "identical",    "miscapitalized",    "transposed characters",    "character missing",    "extra character",    "mistyped character",    "common basename",};typedef struct {    const char *name;    sp_reason quality;} misspelled_file;/* * spdist() is taken from Kernighan & Pike, *  _The_UNIX_Programming_Environment_ * and adapted somewhat to correspond better to psychological reality. * (Note the changes to the return values) * * According to Pollock and Zamora, CACM April 1984 (V. 27, No. 4), * page 363, the correct order for this is: * OMISSION = TRANSPOSITION > INSERTION > SUBSTITUTION * thus, it was exactly backwards in the old version. -- PWP * * This routine was taken out of tcsh's spelling correction code * (tcsh-6.07.04) and re-converted to apache data types ("char" type * instead of tcsh's NLS'ed "Char"). Plus it now ignores the case * during comparisons, so is a "approximate strcasecmp()". * NOTE that is still allows only _one_ real "typo", * it does NOT try to correct multiple errors. */static sp_reason spdist(const char *s, const char *t){    for (; apr_tolower(*s) == apr_tolower(*t); t++, s++) {        if (*t == '\0') {            return SP_MISCAPITALIZED;   /* exact match (sans case) */        }    }    if (*s) {        if (*t) {            if (s[1] && t[1] && apr_tolower(*s) == apr_tolower(t[1])                && apr_tolower(*t) == apr_tolower(s[1])                && strcasecmp(s + 2, t + 2) == 0) {                return SP_TRANSPOSITION;        /* transposition */            }            if (strcasecmp(s + 1, t + 1) == 0) {                return SP_SIMPLETYPO;   /* 1 char mismatch */            }        }        if (strcasecmp(s + 1, t) == 0) {            return SP_EXTRACHAR;        /* extra character */        }    }    if (*t && strcasecmp(s, t + 1) == 0) {        return SP_MISSINGCHAR;  /* missing character */    }    return SP_VERYDIFFERENT;    /* distance too large to fix. */}static int sort_by_quality(const void *left, const void *rite){    return (int) (((misspelled_file *) left)->quality)        - (int) (((misspelled_file *) rite)->quality);}static int check_speling(request_rec *r){    spconfig *cfg;    char *good, *bad, *postgood, *url;    apr_finfo_t dirent;    int filoc, dotloc, urlen, pglen;    apr_array_header_t *candidates = NULL;    apr_dir_t          *dir;    cfg = ap_get_module_config(r->per_dir_config, &speling_module);    if (!cfg->enabled) {        return DECLINED;    }    /* We only want to worry about GETs */    if (r->method_number != M_GET) {        return DECLINED;    }    /* We've already got a file of some kind or another */    if (r->finfo.filetype != 0) {        return DECLINED;    }    /* Not a file request */    if (r->proxyreq || !r->filename) {        return DECLINED;    }    /* This is a sub request - don't mess with it */    if (r->main) {        return DECLINED;    }    /*     * The request should end up looking like this:     * r->uri: /correct-url/mispelling/more     * r->filename: /correct-file/mispelling r->path_info: /more     *     * So we do this in steps. First break r->filename into two pieces     */    filoc = ap_rind(r->filename, '/');    /*     * Don't do anything if the request doesn't contain a slash, or     * requests "/"     */    if (filoc == -1 || strcmp(r->uri, "/") == 0) {        return DECLINED;    }    /* good = /correct-file */    good = apr_pstrndup(r->pool, r->filename, filoc);    /* bad = mispelling */    bad = apr_pstrdup(r->pool, r->filename + filoc + 1);    /* postgood = mispelling/more */    postgood = apr_pstrcat(r->pool, bad, r->path_info, NULL);    urlen = strlen(r->uri);    pglen = strlen(postgood);    /* Check to see if the URL pieces add up */    if (strcmp(postgood, r->uri + (urlen - pglen))) {        return DECLINED;    }    /* url = /correct-url */    url = apr_pstrndup(r->pool, r->uri, (urlen - pglen));    /* Now open the directory and do ourselves a check... */    if (apr_dir_open(&dir, good, r->pool) != APR_SUCCESS) {        /* Oops, not a directory... */        return DECLINED;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -