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

📄 util_filter.c

📁 Apache HTTP Server 是一个功能强大的灵活的与HTTP/1.1相兼容的web服务器.这里给出的是Apache HTTP服务器的源码。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright 2000-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. */#define APR_WANT_STRFUNC#include "apr_want.h"#include "apr_lib.h"#include "apr_hash.h"#include "apr_strings.h"#include "httpd.h"#include "http_log.h"#include "util_filter.h"/* NOTE: Apache's current design doesn't allow a pool to be passed thru,   so we depend on a global to hold the correct pool*/#define FILTER_POOL     apr_hook_global_pool#include "apr_hooks.h"   /* for apr_hook_global_pool *//*** This macro returns true/false if a given filter should be inserted BEFORE** another filter. This will happen when one of: 1) there isn't another** filter; 2) that filter has a higher filter type (class); 3) that filter** corresponds to a different request.*/#define INSERT_BEFORE(f, before_this) ((before_this) == NULL \                           || (before_this)->frec->ftype > (f)->frec->ftype \                           || (before_this)->r != (f)->r)/* Trie structure to hold the mapping from registered * filter names to filters */typedef struct filter_trie_node filter_trie_node;typedef struct {    int c;    filter_trie_node *child;} filter_trie_child_ptr;/* Each trie node has an array of pointers to its children. * The array is kept in sorted order so that add_any_filter() * can do a binary search */struct filter_trie_node {    ap_filter_rec_t *frec;    filter_trie_child_ptr *children;    int nchildren;    int size;};#define TRIE_INITIAL_SIZE 4/* Link a trie node to its parent */static void trie_node_link(apr_pool_t *p, filter_trie_node *parent,                           filter_trie_node *child, int c){    int i, j;    if (parent->nchildren == parent->size) {        filter_trie_child_ptr *new;        parent->size *= 2;        new = (filter_trie_child_ptr *)apr_palloc(p, parent->size *                                             sizeof(filter_trie_child_ptr));        memcpy(new, parent->children, parent->nchildren *               sizeof(filter_trie_child_ptr));        parent->children = new;    }    for (i = 0; i < parent->nchildren; i++) {        if (c == parent->children[i].c) {            return;        }        else if (c < parent->children[i].c) {            break;        }    }    for (j = parent->nchildren; j > i; j--) {        parent->children[j].c = parent->children[j - 1].c;        parent->children[j].child = parent->children[j - 1].child;    }    parent->children[i].c = c;    parent->children[i].child = child;    parent->nchildren++;}/* Allocate a new node for a trie. * If parent is non-NULL, link the new node under the parent node with * key 'c' (or, if an existing child node matches, return that one) */static filter_trie_node *trie_node_alloc(apr_pool_t *p,                                         filter_trie_node *parent, char c){    filter_trie_node *new_node;    if (parent) {        int i;        for (i = 0; i < parent->nchildren; i++) {            if (c == parent->children[i].c) {                return parent->children[i].child;            }            else if (c < parent->children[i].c) {                break;            }        }        new_node =            (filter_trie_node *)apr_palloc(p, sizeof(filter_trie_node));        trie_node_link(p, parent, new_node, c);    }    else { /* No parent node */        new_node = (filter_trie_node *)apr_palloc(p,                                                  sizeof(filter_trie_node));    }    new_node->frec = NULL;    new_node->nchildren = 0;    new_node->size = TRIE_INITIAL_SIZE;    new_node->children = (filter_trie_child_ptr *)apr_palloc(p,                             new_node->size * sizeof(filter_trie_child_ptr));    return new_node;}static filter_trie_node *registered_output_filters = NULL;static filter_trie_node *registered_input_filters = NULL;static apr_status_t filter_cleanup(void *ctx){    registered_output_filters = NULL;    registered_input_filters = NULL;    return APR_SUCCESS;}static ap_filter_rec_t *get_filter_handle(const char *name,                                          const filter_trie_node *filter_set){    if (filter_set) {        const char *n;        const filter_trie_node *node;        node = filter_set;        for (n = name; *n; n++) {            int start, end;            start = 0;            end = node->nchildren - 1;            while (end >= start) {                int middle = (end + start) / 2;                char ch = node->children[middle].c;                if (*n == ch) {                    node = node->children[middle].child;                    break;                }                else if (*n < ch) {                    end = middle - 1;                }                else {                    start = middle + 1;                }            }            if (end < start) {                node = NULL;                break;            }        }        if (node && node->frec) {            return node->frec;        }    }    return NULL;}AP_DECLARE(ap_filter_rec_t *)ap_get_output_filter_handle(const char *name){    return get_filter_handle(name, registered_output_filters);}AP_DECLARE(ap_filter_rec_t *)ap_get_input_filter_handle(const char *name){    return get_filter_handle(name, registered_input_filters);}static ap_filter_rec_t *register_filter(const char *name,                            ap_filter_func filter_func,                            ap_init_filter_func filter_init,                            ap_filter_type ftype,                            filter_trie_node **reg_filter_set){    ap_filter_rec_t *frec;    char *normalized_name;    const char *n;    filter_trie_node *node;    if (!*reg_filter_set) {        *reg_filter_set = trie_node_alloc(FILTER_POOL, NULL, 0);    }    normalized_name = apr_pstrdup(FILTER_POOL, name);    ap_str_tolower(normalized_name);    node = *reg_filter_set;    for (n = normalized_name; *n; n++) {        filter_trie_node *child = trie_node_alloc(FILTER_POOL, node, *n);        if (apr_isalpha(*n)) {            trie_node_link(FILTER_POOL, node, child, apr_toupper(*n));        }        node = child;    }    if (node->frec) {        frec = node->frec;    }    else {        frec = apr_palloc(FILTER_POOL, sizeof(*frec));        node->frec = frec;        frec->name = normalized_name;    }    frec->filter_func = filter_func;    frec->filter_init_func = filter_init;    frec->ftype = ftype;        apr_pool_cleanup_register(FILTER_POOL, NULL, filter_cleanup,                               apr_pool_cleanup_null);    return frec;}AP_DECLARE(ap_filter_rec_t *) ap_register_input_filter(const char *name,                                          ap_in_filter_func filter_func,                                          ap_init_filter_func filter_init,                                          ap_filter_type ftype){    ap_filter_func f;    f.in_func = filter_func;    return register_filter(name, f, filter_init, ftype,                           &registered_input_filters);}                                                                    AP_DECLARE(ap_filter_rec_t *) ap_register_output_filter(const char *name,                                           ap_out_filter_func filter_func,                                           ap_init_filter_func filter_init,                                           ap_filter_type ftype){    ap_filter_func f;    f.out_func = filter_func;    return register_filter(name, f, filter_init, ftype,                           &registered_output_filters);}static ap_filter_t *add_any_filter_handle(ap_filter_rec_t *frec, void *ctx,                                           request_rec *r, conn_rec *c,                                           ap_filter_t **r_filters,                                          ap_filter_t **p_filters,                                          ap_filter_t **c_filters){    apr_pool_t* p = r ? r->pool : c->pool;    ap_filter_t *f = apr_palloc(p, sizeof(*f));    ap_filter_t **outf;    if (frec->ftype < AP_FTYPE_PROTOCOL) {        if (r) {            outf = r_filters;        }        else {            ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,                      "a content filter was added without a request: %s", frec->name);            return NULL;        }    }    else if (frec->ftype < AP_FTYPE_CONNECTION) {        if (r) {            outf = p_filters;        }        else {            ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,                         "a protocol filter was added without a request: %s", frec->name);            return NULL;        }    }    else {        outf = c_filters;    }    f->frec = frec;    f->ctx = ctx;    f->r = r;    f->c = c;    f->next = NULL;

⌨️ 快捷键说明

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