Linux 下 Apache 模塊開發

轉載自 http://blog.csdn.net/21aspnet/article/details/6621621


環境:CentOS

第一步:安裝Apache的apxs

首先來介紹下apache的一個工具apxs。apxs是一個爲Apache HTTP服務器編譯和安裝擴展模塊的工具,用於編譯一個或多個源程序或目標代碼文件爲動態共享對象,使之可以用由mod_so提供的LoadModule指令在運行時加載到Apache服務器中。

 

輸入命令查看是否有httpd-devel這個包,如果沒有需要安裝

#rpm -qa|grep httpd 

# yum -y install httpd-devel

利用指令確認其已經安裝

# which apxs
/use/sbin/apxs

也可以這樣查找全部

#find / | grep apxs

 

第二步:apxs -g -n helloworld

上面的命令可以幫助我們產生一個模塊名字爲helloworld的模板。
上面的命令會產生以下代碼

 

C代碼

  1. #include "httpd.h"   
  2. #include "http_config.h"   
  3. #include "http_protocol.h"   
  4. #include "ap_config.h"   
  5.   
  6. /* The sample content handler */  
  7. static int helloworld_handler(request_rec *r)   
  8. {   
  9.     if (strcmp(r->handler, "helloworld")) {   
  10.         return DECLINED;   
  11.     }   
  12.     r->content_type = "text/html";         
  13.   
  14.     if (!r->header_only)   
  15.         ap_rputs("The sample page from mod_helloworld.c\n", r);   
  16.     return OK;   
  17. }   
  18.   
  19. static void helloworld_register_hooks(apr_pool_t *p)   
  20. {   
  21.     ap_hook_handler(helloworld_handler, NULL, NULL, APR_HOOK_MIDDLE);   
  22. }   
  23. /* Dispatch list for API hooks */  
  24. module AP_MODULE_DECLARE_DATA helloworld_module = {   
  25.     STANDARD20_MODULE_STUFF, //用於編譯後的模塊產生版本信息   
  26.     NULL,                  /* 創建目錄配置結構*/  
  27.     NULL,                  /* 合併目錄配置結構 */  
  28.     NULL,                  /* 創建主機配置結構 */  
  29.     NULL,                  /* 合併主機配置結構 */  
  30.     NULL,                  /* 爲模塊配置相關指令       */  
  31.     helloworld_register_hooks  /* 註冊模塊的鉤子函數                      */  
  32. };  

#include "httpd.h"
#include "http_config.h"
#include "http_protocol.h"
#include "ap_config.h"

/* The sample content handler */
static int helloworld_handler(request_rec *r)
{
if (strcmp(r->handler, "helloworld")) {
return DECLINED;
}
r->content_type = "text/html";

if (!r->header_only)
ap_rputs("The sample page from mod_helloworld.c\n", r);
return OK;
}

static void helloworld_register_hooks(apr_pool_t *p)
{
ap_hook_handler(helloworld_handler, NULL, NULL, APR_HOOK_MIDDLE);
}
/* Dispatch list for API hooks */
module AP_MODULE_DECLARE_DATA helloworld_module = {
STANDARD20_MODULE_STUFF, //用於編譯後的模塊產生版本信息
NULL, /* 創建目錄配置結構*/
NULL, /* 合併目錄配置結構 */
NULL, /* 創建主機配置結構 */
NULL, /* 合併主機配置結構 */
NULL, /* 爲模塊配置相關指令 */
helloworld_register_hooks /* 註冊模塊的鉤子函數 */
};

我們來看下helloworld_module這個結構體,它沒個成員的具體作用請看註釋。
它最關鍵的參數爲最後一個,這個參數是一個註冊鉤子函數指針,也就是說當我們把模塊加入到apache裏面去的時候,他會執行這個註冊函數。在這個函數裏面我們將會註冊我們所要添加的鉤子。
本例子中我們用的是

 

C代碼

  1. ap_hook_handler(helloworld_handler, NULL, NULL, APR_HOOK_MIDDLE);  

ap_hook_handler(helloworld_handler, NULL, NULL, APR_HOOK_MIDDLE);

這個處理函數,這個處理函數註冊了helloworld_handler這個函數。這個函數用於處理我們的請求。
我們來講下執行的順序,模塊加載-》執行helloworld_register_hooks函數-》註冊helloworld_handler這個函數到鉤子上去。
這樣一來:當一個http請求來的時候,我們就會自動去執行helloworld_handler這個函數。本例子是一個非常簡單的內容生成器。

 

C代碼

  1. if (strcmp(r->handler, "helloworld")) {//判斷是否是這個helloworld  handler   
  2.         return DECLINED;//   
  3.     }   
  4.     r->content_type = "text/html";         
  5.     if (!r->header_only)   
  6.         ap_rputs("The sample page from mod_helloworld.c\n", r);//內容生成   
  7.     return OK;  

if (strcmp(r->handler, "helloworld")) {//判斷是否是這個helloworld handler
return DECLINED;//
}
r->content_type = "text/html";
if (!r->header_only)
ap_rputs("The sample page from mod_helloworld.c\n", r);//內容生成
return OK;

 

第三步:編譯

# apxs -c mod_helloworld.c
/usr/lib/apr-1/build/libtool --silent --mode=compile gcc -prefer-pic -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables -fno-strict-aliasing  -DLINUX=2 -D_REENTRANT -D_GNU_SOURCE -D_LARGEFILE64_SOURCE -pthread -I/usr/include/httpd  -I/usr/include/apr-1   -I/usr/include/apr-1   -c -o mod_helloworld.lo mod_helloworld.c && touch mod_helloworld.slo
/usr/lib/apr-1/build/libtool --silent --mode=link gcc -o mod_helloworld.la  -rpath /usr/lib/httpd/modules -module -avoid-version    mod_helloworld.lo

ls後發現目錄下的確多了幾個文件,其中就有一個mod_helloworld.la的,於是再調用

# apxs -i mod_helloworld.la

apache的Module目錄下就多了一個mod_helloworld.so

 

再在httpd.conf中加入這一Module:

LoadModule helloworld_module /usr/lib/httpd/modules/mod_helloworld.so

<Location /helloworld>
        SetHandler helloworld
</Location>

重啓apache 然後輸入 http://loacalhost/helloworld 就可以看到
The sample page from mod_helloworld.c

當然這裏這裏只是輸出一句話,我們也可以打印很多html信息,就類似於servlet一樣。

這樣一來一個簡單的apache內容生成器模塊已經開發好了,當然應用比較廣泛的是過濾器模塊的開發,最近項目主要也是用過濾器來實現的。

apache 可以開發出一些功能非常強大的模塊來,可以爲我們定製更好的apache,比如容器中應用的流量統計,cpu統計等。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章