Apache模块开发helloworld无错版
環(huán)境:CentOS 5.4
第一步:安裝Apache的apxs
首先來(lái)介紹下apache的一個(gè)工具apxs。apxs是一個(gè)為Apache HTTP服務(wù)器編譯和安裝擴(kuò)展模塊的工具,用于編譯一個(gè)或多個(gè)源程序或目標(biāo)代碼文件為動(dòng)態(tài)共享對(duì)象,使之可以用由mod_so提供的LoadModule指令在運(yùn)行時(shí)加載到Apache服務(wù)器中。
?
apxs可參考官方文檔
http://lamp.linux.gov.cn/Apache/ApacheMenu/programs/apxs.html
?
輸入命令查看是否有httpd-devel這個(gè)包,如果沒(méi)有需要安裝
#rpm -qa|grep httpd?
# yum -y install httpd-devel
利用指令確認(rèn)其已經(jīng)安裝
# which apxs
 /use/sbin/apxs
也可以這樣查找全部
#find / | grep apxs
?
第二步:apxs -g -n helloworld
上面的命令可以幫助我們產(chǎn)生一個(gè)模塊名字為helloworld的模板。
 上面的命令會(huì)產(chǎn)生以下代碼 
?
C代碼
- #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,?//用于編譯后的模塊產(chǎn)生版本信息 ??
- ????NULL,??????????????????/*?創(chuàng)建目錄配置結(jié)構(gòu)*/??
- ????NULL,??????????????????/*?合并目錄配置結(jié)構(gòu)?*/??
- ????NULL,??????????????????/*?創(chuàng)建主機(jī)配置結(jié)構(gòu)?*/??
- ????NULL,??????????????????/*?合并主機(jī)配置結(jié)構(gòu)?*/??
- ????NULL,??????????????????/*?為模塊配置相關(guān)指令???????*/??
- ????helloworld_register_hooks??/*?注冊(cè)模塊的鉤子函數(shù)??????????????????????*/??
- };??
#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, //用于編譯后的模塊產(chǎn)生版本信息
 NULL, /* 創(chuàng)建目錄配置結(jié)構(gòu)*/
 NULL, /* 合并目錄配置結(jié)構(gòu) */
 NULL, /* 創(chuàng)建主機(jī)配置結(jié)構(gòu) */
 NULL, /* 合并主機(jī)配置結(jié)構(gòu) */
 NULL, /* 為模塊配置相關(guān)指令 */
 helloworld_register_hooks /* 注冊(cè)模塊的鉤子函數(shù) */
 };
我們來(lái)看下helloworld_module這個(gè)結(jié)構(gòu)體,它沒(méi)個(gè)成員的具體作用請(qǐng)看注釋。
 它最關(guān)鍵的參數(shù)為最后一個(gè),這個(gè)參數(shù)是一個(gè)注冊(cè)鉤子函數(shù)指針,也就是說(shuō)當(dāng)我們把模塊加入到apache里面去的時(shí)候,他會(huì)執(zhí)行這個(gè)注冊(cè)函數(shù)。在這個(gè)函數(shù)里面我們將會(huì)注冊(cè)我們所要添加的鉤子。
 本例子中我們用的是 
?
C代碼
- ap_hook_handler(helloworld_handler,?NULL,?NULL,?APR_HOOK_MIDDLE);??
ap_hook_handler(helloworld_handler, NULL, NULL, APR_HOOK_MIDDLE);
這個(gè)處理函數(shù),這個(gè)處理函數(shù)注冊(cè)了helloworld_handler這個(gè)函數(shù)。這個(gè)函數(shù)用于處理我們的請(qǐng)求。
 我們來(lái)講下執(zhí)行的順序,模塊加載-》執(zhí)行helloworld_register_hooks函數(shù)-》注冊(cè)helloworld_handler這個(gè)函數(shù)到鉤子上去。
 這樣一來(lái):當(dāng)一個(gè)http請(qǐng)求來(lái)的時(shí)候,我們就會(huì)自動(dòng)去執(zhí)行helloworld_handler這個(gè)函數(shù)。本例子是一個(gè)非常簡(jiǎn)單的內(nèi)容生成器。 
?
C代碼
- if?(strcmp(r->handler,?"helloworld"))?{//判斷是否是這個(gè)helloworld??handler ??
- ????????return?DECLINED;// ??
- ????} ??
- ????r->content_type?=?"text/html";?????? ??
- ????if?(!r->header_only) ??
- ????????ap_rputs("The?sample?page?from?mod_helloworld.c\n",?r);//內(nèi)容生成 ??
- ????return?OK;??
if (strcmp(r->handler, "helloworld")) {//判斷是否是這個(gè)helloworld handler
 return DECLINED;//
 }
 r->content_type = "text/html";
 if (!r->header_only)
 ap_rputs("The sample page from mod_helloworld.c\n", r);//內(nèi)容生成
 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后發(fā)現(xiàn)目錄下的確多了幾個(gè)文件,其中就有一個(gè)mod_helloworld.la的,于是再調(diào)用
#?apxs -i mod_helloworld.la
apache的Module目錄下就多了一個(gè)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 
當(dāng)然這里這里只是輸出一句話,我們也可以打印很多html信息,就類似于servlet一樣。
這樣一來(lái)一個(gè)簡(jiǎn)單的apache內(nèi)容生成器模塊已經(jīng)開(kāi)發(fā)好了,當(dāng)然應(yīng)用比較廣泛的是過(guò)濾器模塊的開(kāi)發(fā),最近項(xiàng)目主要也是用過(guò)濾器來(lái)實(shí)現(xiàn)的。
apache 可以開(kāi)發(fā)出一些功能非常強(qiáng)大的模塊來(lái),可以為我們定制更好的apache,比如容器中應(yīng)用的流量統(tǒng)計(jì),cpu統(tǒng)計(jì)等。
?
?
網(wǎng)上還有幾篇寫的可參考的:
http://www.cnblogs.com/ithurricane/archive/2009/01/01/1366312.html?
http://www.cnblogs.com/DeadKnight/archive/2010/04/08/1707444.html
http://hi.baidu.com/kylelee/blog/item/f13fef2c7366bceb8b1399c9.html
總結(jié)
以上是生活随笔為你收集整理的Apache模块开发helloworld无错版的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: 天空套多少钱啊?
- 下一篇: 谁能帮看看这张邮票上说的啥 啥意思?
