使用C++編寫Apache的模塊 -- 命令表,保存配置信息

· 作者:laruence(http://www.laruence.com/)
· 本文地址: http://www.laruence.com/2008/04/09/112.html
· 轉載請註明出處           
    還是和論文相關,要編寫一個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: 看源代碼,是最快的學習方法。
發佈了31 篇原創文章 · 獲贊 9 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章