用C++开发Apache模块

本来是要自己写的,但是一直没有太多的时间,这里摘自laruence的一段文章,有机会补充一下。
    //作者: laruence<xinchen.hui at alibab-inc.com>
    //http://blog.csdn.net/laruence/
    //转载请注明出处
    还是和论文相关,要编写一个Apache的模块,挂在post read_request阶段,在第一时间,判断一个链接是否是而已连接请求,并在第一时间拒绝恶意连接请求。
      首先遇到的第一个问题,就是需要从http.conf中读取配置信息,提供俩个配置指令,MaxNumber, TimeRange.指定在一段时间内的连接次数上限。
       编写的时候,遇到的第一个问题就是,moudule申明,不能通过编译,编译器提示重复定义。查了N遍手边的apache源码分析,也没有找到原因,如:
     
......
module door_module;

......


module MODULE_VAR_EXPORT door_module 
= {
        STANDARD_MODULE_STUFF,
        NULL,
        NULL,
        NULL,
        create_door_config,
        NULL,
        door_cmds,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        door_authorization,
}
;

 最后,删除掉第一个module申明, 通过编译。
      遇到的第二个问题,就是命令表中的命令处理函数在http_config.h中的定义如下:
      
const char * (*cmd_func)();
      但是,《Aapache源码分析》和网上的资料中,命令处理都是带有参数的,如下:
  
static const char  * maxRequest(cmd_parms *cmd, void * dconf, const char * arg);
     真是,奇怪的很,我使用的是Apache 1.3的dev包,不知道是不是因为版本太低的缘故? 最后,修改了http_config.h, 通过编译,并且工作正常。真的很奇怪,留待以后解决。
     这俩个问题这么糊涂的解决以后,接下来的工作就很简单了。
     首先在server config阶段,初始化我们的全局配置结构。
      
typedef struct {
     
int MaxNumber;
         
int TimeLimit;
}
mod_door_config;

static void * create_door_config(pool *p, server_rec * s){
        mod_door_config 
* cf = static_cast<mod_door_config *>(ap_palloc(p, sizeof(mod_door_config)));
        cf
->MaxNumber = 100;
        cf
->TimeLimit = 60;
        
return cf;
}

     通过ap_palloc为全局配置结构分配资源,并初始化配置结构。然后定义命令表。
 
static const command_rec door_cmds[] = {
        
{"MaxRequest", maxRequest, NULL, RSRC_CONF|ACCESS_CONF, TAKE1, "Can't get MaxRequest"},
        
{"TimeRange", timeRange,  NULL, RSRC_CONF|ACCESS_CONF, TAKE1, "Cant' get Time Range"},
        
{NULL}
}
;
   接着定义命令处理函数:
static const char  * maxRequest(cmd_parms *cmd, void * dconf, const char * arg){
        server_rec 
* s = cmd->server;
        mod_door_config 
*cf = static_cast<mod_door_config *>(ap_get_module_config(s->module_config, &door_module));
        cf
->MaxNumber = atoi(arg);
        
//cerr<<cf->MaxNumber<<endl;
        return NULL;
}

static const char   * timeRange(cmd_parms *cmd, void * dconf, const char * arg){
        server_rec 
* s = cmd->server;
        mod_door_config 
*cf = static_cast<mod_door_config *>(ap_get_module_config(s->module_config, &door_module));
        cf
->TimeLimit = atoi(arg);
        
//cerr<<cf->TimeLimit<<endl;
        return NULL;
}

最后在验证阶段,来获取配置信息:
  
static int door_authorization(request_rec * r){
        cerr 
<< r->connection->remote_ip<<endl;
        mod_door_config 
* cf = static_cast<mod_door_config *>(ap_get_module_config(r->server->module_config, &door_module));
        
//ap_rprintf(r ,"your IP : %s  ", r->connection->remote_ip);
        
//ap_rprintf(r ,"MaxNumber : %d  ", cf->MaxNumber);
        
//ap_rprintf(r ,"TimeRange : %s  ", cf->TimeLimit);
        
//cerr<<cf->MaxNumber<<endl;
        return OK;
}

 经过编译,测试,一切works well。
 
 先写这么多,等我慢慢研究这些遗留问题,留待以后补充。
 ps: 看源代码,是最快的学习方法。

Monthly Archives

Pages

Powered by Movable Type 7.7.2

About this Entry

This page contains a single entry by Cnangel published on June 29, 2008 8:26 PM.

面试与被面试 was the previous entry in this blog.

深入 PHP 内核——Zend API和一些配置的宏 is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.