echo ""; echo ""; echo ""; echo ""; if(!is_admin){echo "";} » Apache模块开发中的内容过滤 仲子说

2008-05-13

Apache模块开发中的内容过滤

Posted in 转载, Apache, FreeBSD/Unix服务器 at 23:53 Author:仲远

标签:

???????Apache?????????????????????????????????????????????????Apache??????Module?????????????????????????????????????????????Linux_prog??????apache?tutor??????http://www.apachetutor.org/dev/smart-filter??????Apache????????????????

Apache2.x filter??(?????apache??????)
by linux_prog

Apache2????filter????????filter???????????????????????????
?Apache1??????????????filter??????????????
?????apache2??????????filter:
#include “httpd.h”
#include “http_config.h”
#include “apr_buckets.h”
#include “apr_general.h”
#include “apr_lib.h”
#include “util_filter.h”
#include “http_request.h”
#include

static const char s_szCaseFilterName[]=”CaseFilter”;
module AP_MODULE_DECLARE_DATA case_filter_module;

typedef struct
    {
    int bEnabled;
    } CaseFilterConfig;

static void *CaseFilterCreateServerConfig(apr_pool_t *p,server_rec *s)
    {
    CaseFilterConfig *pConfig=apr_pcalloc(p,sizeof *pConfig);

    pConfig->bEnabled=0;

    return pConfig;
    }

static void CaseFilterInsertFilter(request_rec *r)
    {
    CaseFilterConfig *pConfig=ap_get_module_config(r->server->module_config,
                                                   &case_filter_module);

    if(!pConfig->bEnabled)
        return;

    ap_add_output_filter(s_szCaseFilterName,NULL,r,r->connection);
    }

static apr_status_t CaseFilterOutFilter(ap_filter_t *f,
                                        apr_bucket_brigade *pbbIn)
    {
    request_rec *r = f->r;
    conn_rec *c = r->connection;
    apr_bucket *pbktIn;
    apr_bucket_brigade *pbbOut;

    pbbOut=apr_brigade_create(r->pool, c->bucket_alloc);
  
    for (pbktIn = APR_BRIGADE_FIRST(pbbIn);
         pbktIn != APR_BRIGADE_SENTINEL(pbbIn);
         pbktIn = APR_BUCKET_NEXT(pbktIn))
    {
        const char *data;
        apr_size_t len;
        char *buf;
        apr_size_t n;
        apr_bucket *pbktOut;

        if(APR_BUCKET_IS_EOS(pbktIn))
            {
            apr_bucket *pbktEOS=apr_bucket_eos_create(c->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(pbbOut,pbktEOS);
            continue;
            }

        /* read */
        apr_bucket_read(pbktIn,&data,&len,APR_BLOCK_READ);

        /* write */
        buf = apr_bucket_alloc(len, c->bucket_alloc);
        for(n=0 ; n < len ; ++n)
            buf[n] = apr_toupper(data[n]);

        pbktOut = apr_bucket_heap_create(buf, len, apr_bucket_free,
                                         c->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(pbbOut,pbktOut);
        }

    /* XXX: is there any advantage to passing a brigade for each bucket? */
    return ap_pass_brigade(f->next,pbbOut);
    }

static const char *CaseFilterEnable(cmd_parms *cmd, void *dummy, int arg)
    {
    CaseFilterConfig *pConfig=ap_get_module_config(cmd->server->module_config,
                                                   &case_filter_module);
    pConfig->bEnabled=arg;

    return NULL;
    }

static const command_rec CaseFilterCmds[] =
    {
    AP_INIT_FLAG(”CaseFilter”, CaseFilterEnable, NULL, RSRC_CONF,
                 “Run a case filter on this host”),
    { NULL }
    };

static void CaseFilterRegisterHooks(apr_pool_t *p)
    {
    // ??filter
    ap_hook_insert_filter(CaseFilterInsertFilter,NULL,NULL,APR_HOOK_MIDDLE);
    // ??filter
    ap_register_output_filter(s_szCaseFilterName,CaseFilterOutFilter,NULL,
                              AP_FTYPE_RESOURCE);
    }

module AP_MODULE_DECLARE_DATA case_filter_module =
{
    STANDARD20_MODULE_STUFF,
    NULL,
    NULL,
    CaseFilterCreateServerConfig, // ?????
    NULL,
    CaseFilterCmds,   // ????????????
    CaseFilterRegisterHooks //??output filter
};

?????
./bin/apxs -c ./mod_case_filter.c
./bin/apxs -a -i -n case_filter ./mod_case_filter.la

?httpd.conf????
CaseFilter on

????????apache???????????????????????????????????
???filter????????????
?????????????????????????????????????apache?????????

???filter??????????????
?1? ??filter???
   output filter / input filter
 (2) filter??
 
util_filter.h?????
typedef enum {
    /** These filters are used to alter the content that is passed through
     *  them. Examples are SSI or PHP. */
    AP_FTYPE_RESOURCE     = 10,
    /** These filters are used to alter the content as a whole, but after all
     *  AP_FTYPE_RESOURCE filters are executed.  These filters should not
     *  change the content-type.  An example is deflate.  */
    AP_FTYPE_CONTENT_SET  = 20,
    /** These filters are used to handle the protocol between server and
     *  client.  Examples are HTTP and POP. */
    AP_FTYPE_PROTOCOL     = 30,
    /** These filters implement transport encodings (e.g., chunking). */
    AP_FTYPE_TRANSCODE    = 40,
    /** These filters will alter the content, but in ways that are
     *  more strongly associated with the connection.  Examples are
     *  splitting an HTTP connection into multiple requests and
     *  buffering HTTP responses across multiple requests.
     *
     *  It is important to note that these types of filters are not
     *  allowed in a sub-request. A sub-request’s output can certainly
     *  be filtered by ::AP_FTYPE_RESOURCE filters, but all of the “final
     *  processing” is determined by the main request. */
    AP_FTYPE_CONNECTION  = 50,
    /** These filters don’t alter the content.  They are responsible for
     *  sending/receiving data to/from the client. */
    AP_FTYPE_NETWORK     = 60
} ap_filter_type;

????????AP_FTYPE_RESOURCE?filter,????????????PHP?
AP_FTYPE_CONTENT_SET filter???????????????mod_deflate??????
?????????filter????????

(3) filter????
  ??ap_filter_type?????????????????AP_FTYPE_RESOURCE????AP_FTYPE_CONTENT_SET?????
  ???????????filter:
  ap_register_output_filter(s_szCaseFilterName,CaseFilterOutFilter,NULL,
                              AP_FTYPE_RESOURCE-1);
  ??filter?????AP_FTYPE_RESOURCE filter?????
  ????filter????????filter??????AP_FTYPE_RESOURCE?????httpd.conf??
  LoadModule php5_module        modules/libphp5.so
  LoadModule case_filter_module modules/mod_case_filter.so
  ???????????filter.

(4) ??filter???????????
    apr_bucket_brigade *pbbOut; // ?????????????????????????
    apr_bucket *pbktIn;         // ??????????????
   
    apache????????????????
    ???
    // ??????
    for (pbktIn = APR_BRIGADE_FIRST(pbbIn);
         pbktIn != APR_BRIGADE_SENTINEL(pbbIn);
         pbktIn = APR_BUCKET_NEXT(pbktIn))
    {
       
    }
   
    // ?????bucket
    apr_bucket *newb = APR_BUCKET_NEXT(pbktIn);
   
    //???apr_bucket_brigade???apr_bucket???????
    APR_BUCKET_REMOVE(pbktIn);
   
    //???apr_bucket_brigade???apr_bucket??????
    apr_bucket_delete(pbktIn);
   
    ????apr_bucket?????split??????apr_bucket?????????
    ???
    int index;
    apr_bucket_split(pbktIn, index); //?pbktIn?index??????
   
  filter????????????????????????????apache module.
  ????????

本文可以自由转载,转载时请保留全文并注明出处:
转载自仲子说 [ http://www.wangzhongyuan.com/ ]
原文链接:

2 Comments »

  1. 慎用域名注册商提供的URL转发功能 仲子说 301, 302, Apache, Freebsd/Unix服务器, URL转发, 同一网站, 多个域名 重定向 said,

    2008年May14日 at 20:17

    […] 原文链接:http://www.wangzhongyuan.com/archives/369.html  […]

  2. 屏蔽Indy Library的方法 仲子说 Apache, Freebsd/Unix服务器, Spiders, 搜索引擎, 网络安全, 网络爬虫 蜘蛛 said,

    2008年December5日 at 15:35

    […] 119.114.144.169 - - [05/Dec/2008:15:22:50 +0800] "POST / HTTP/1.0" 200 38535 "http://www.wangzhongyuan.com/archives/369.html" "Mozilla/3.0 (compatible; Indy […]

Leave a Comment

*
To prove you're a person (not a spam script), type the security text shown in the picture. Click here to regenerate some new text.
Click to hear an audio file of the anti-spam word