helloworld_mod模塊

1. 通過apxs生成

1.1 簡單版

使用apxs -n helloworld -g可生成helloworld模塊:

renz@apache1:~/helloworld$ ls
Makefile mod_helloworld.c modules.mk

生成mod_helloworld.c代碼如下:

/* 
**  mod_helloworld.c -- Apache sample helloworld module
**  [Autogenerated via ``apxs -n helloworld -g'']
**
**  To play with this sample module first compile it into a
**  DSO file and install it into Apache's modules directory 
**  by running:
**
**    $ apxs -c -i mod_helloworld.c
**
**  Then activate it in Apache's apache2.conf file for instance
**  for the URL /helloworld in as follows:
**
**    #   apache2.conf
**    LoadModule helloworld_module modules/mod_helloworld.so
**    <Location /helloworld>
**    SetHandler helloworld
**    </Location>
**
**  Then after restarting Apache via
**
**    $ apachectl restart
**
**  you immediately can request the URL /helloworld and watch for the
**  output of this module. This can be achieved for instance via:
**
**    $ lynx -mime_header http://localhost/helloworld 
**
**  The output should be similar to the following one:
**
**    HTTP/1.1 200 OK
**    Date: Tue, 31 Mar 1998 14:42:22 GMT
**    Server: Apache/1.3.4 (Unix)
**    Connection: close
**    Content-Type: text/html
**  
**    The sample page from mod_helloworld.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,
    NULL,                  /* create per-dir    config structures */
    NULL,                  /* merge  per-dir    config structures */
    NULL,                  /* create per-server config structures */
    NULL,                  /* merge  per-server config structures */
    NULL,                  /* table of config file commands       */
    helloworld_register_hooks  /* register hooks                      */
};

代碼注釋里有helloworld模塊實現(xiàn)的步驟,參考執(zhí)行:apxs -c -i mod_helloworld.c蝇闭,這一步執(zhí)行的就是編譯了吠裆。如果apache不是按照默認目錄安裝匾鸥,可能需要修改Makefile文件里的路徑桅滋。
加載模塊岔乔,找到apache2.conf配置文件拇砰,在里面添加如下配置即可:

LoadModule helloworld_module modules/mod_helloworld
<Location /helloworld>
SetHandler helloworld
</Location>

我這個環(huán)境稍有不同脱篙,在瀏覽器登錄的歡迎界面就說到:

 The configuration layout for an Apache2 web server installation on Ubuntu systems is as follows:

/etc/apache2/
|-- apache2.conf
|       `--  ports.conf
|-- mods-enabled
|       |-- *.load
|       `-- *.conf
|-- conf-enabled
|       `-- *.conf
|-- sites-enabled
|       `-- *.conf

它把apache的配置文件拆成了小配置文件,在apache2.conf文件里include悦施,mods-enabled文件夾像是用來管理模塊的并扇,但是你會發(fā)現(xiàn)里面全是mods-available鏈接過來的文件,so仿照mods-available文件夾里面的文件格式抡诞,將helloworld模塊的配置文件分成兩部分:
helloworld.conf:

<Location /helloworld>
SetHandler helloworld
</Location>

helloworld.load:

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

但是僅僅這樣還不行穷蛹,你還需要將模塊鏈接到mod_available文件夾下面,鏈接的方法也寫在apache服務(wù)器的歡迎頁面了:

They are activated by symlinking available configuration files from their respective *-available/ counterparts. These should be managed by using our helpers a2enmod, a2dismod,a2ensite, a2dissite,and a2enconf, a2disconf . See their respective man pages for detailed information.

使用sudo a2enmod helloworld完成鏈接昼汗。
重啟apache服務(wù)器apachectl restart肴熏,也可以按照提示使用service apache2 restart,再然后就可以見證奇跡了顷窒,在主機瀏覽器里輸入http://192.168.232.129/helloworld蛙吏,出現(xiàn)The sample page from mod_helloworld.c界面:

apache-hellowrold2.png

代碼里可見這個模塊只做了很少的事情,檢查r-handler是否是helloworld鞋吉,若不是出刷,返回DECLINED(代表處理器和請求不匹配,拒絕處理該請求)坯辩。

1.2 地獄版

獲取Apache最常用的三組信息:請求報頭馁龟、響應(yīng)抱頭和內(nèi)部環(huán)境變量。
修改mod_helloworld.c:

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

static int printitem(void *rec, const char *key, const char *value)
{
    request_rec *r = rec;
    ap_rprintf(r, "<tr><th scope=\"row\">%s</th><td>%s</td></tr>\n",
        ap_escape_html(r->pool, key),
        ap_escape_html(r->pool, value));

    return 1;
}

static void printtable(request_rec *r, apr_table_t *t, const char *caption, const char *keyhead, const char *valhead)
{
    ap_rprintf(r, "<table><caption>%s</caption><thead>"
        "<tr><th scope=\"col\">%s</th><th scope=\"col\">%s"
        "</th></tr></thead><tbody>", caption, keyhead, valhead);
    apr_table_do(printitem, r, t, NULL);
    ap_rputs("</tbody></table>\n", r);
}

/* The sample content handler */
static int helloworld_handler(request_rec *r)
{
    if (!r->handler || strcmp(r->handler, "helloworld") != 0 ) {
        return DECLINED;
    }
    if (r->method_number != M_GET) {
        return HTTP_METHOD_NOT_ALLOWED;
    }
    ap_set_content_type(r, "text/html;charset=ascii");
    ap_rputs("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\n"
        "<html><head><title>Apache Helloworld Module</title></head>"
        "<body><h1>Hello World</h1>"
        "<p>This is the Helloworld Module</p>", r);
    /*打印表格*/
    printtable(r, r->headers_in, "Request Headers", "Header", "Value");
    printtable(r, r->headers_out, "Response Headers", "Header", "Value");
    printtable(r, r->subprocess_env, "Environment", "Variable", "Value");

    ap_rputs("</body></html>", 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,                  /* create per-dir    config structures */
    NULL,                  /* merge  per-dir    config structures */
    NULL,                  /* create per-server config structures */
    NULL,                  /* merge  per-server config structures */
    NULL,                  /* table of config file commands       */
    helloworld_register_hooks  /* register hooks                      */
};

重啟后如下圖:


apache-helloworld3.png

1.3 其他

printitem回調(diào)函數(shù)

apr_table_do(func, rec, table, NULL) ;對表進行迭代
ap_escape_html

面向過濾器的I/O

三個步驟:

  • 創(chuàng)建一個Bucket brigade
  • 加載數(shù)據(jù)到Brigade
  • 把Brigade傳遞到堆棧(r->output_filters)的第一個輸出過濾器中漆魔。

2 手動編輯

安裝apxs:

apt-get install apache2-dev

DECLINED:

#define DECLINED -1     /**< Module declines to handle */

request_rec:

/** A structure that represents the current request */
struct request_rec {
    /** The handler string that we use to call a handler function */
    const char *handler;    /* What we *really* dispatch on */
    /** Request method (eg. GET, HEAD, POST, etc.) */
    const char *method;
    /** M_GET, M_POST, etc. */
    int method_number;
    /** The filename on disk corresponding to this response */
    char *filename;
}

ap_rputs:

/**
 * Output a string for the current request
 * @param str The string to output
 * @param r The current request
 * @return The number of bytes sent
 * @deffunc int ap_rputs(const char *str, request_rec *r)
 */
AP_DECLARE(int) ap_rputs(const char *str, request_rec *r);

ap_set_content_length:

/**
 * Set the content length for this request
 * @param r The current request
 * @param length The new content length
 * @deffunc void ap_set_content_length(request_rec *r, apr_off_t length)
 */
AP_DECLARE(void) ap_set_content_length(request_rec *r, apr_off_t length);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末坷檩,一起剝皮案震驚了整個濱河市却音,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌矢炼,老刑警劉巖系瓢,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異句灌,居然都是意外死亡夷陋,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門胰锌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來骗绕,“玉大人,你說我怎么就攤上這事资昧〕晖粒” “怎么了?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵格带,是天一觀的道長撤缴。 經(jīng)常有香客問我,道長叽唱,這世上最難降的妖魔是什么屈呕? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮棺亭,結(jié)果婚禮上虎眨,老公的妹妹穿的比我還像新娘。我一直安慰自己侦铜,他們只是感情好,可當我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布钟鸵。 她就那樣靜靜地躺著钉稍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪棺耍。 梳的紋絲不亂的頭發(fā)上贡未,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天,我揣著相機與錄音蒙袍,去河邊找鬼俊卤。 笑死,一個胖子當著我的面吹牛害幅,可吹牛的內(nèi)容都是我干的消恍。 我是一名探鬼主播,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼以现,長吁一口氣:“原來是場噩夢啊……” “哼狠怨!你這毒婦竟也來了约啊?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤佣赖,失蹤者是張志新(化名)和其女友劉穎恰矩,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體憎蛤,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡外傅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了俩檬。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片萎胰。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖豆胸,靈堂內(nèi)的尸體忽然破棺而出奥洼,到底是詐尸還是另有隱情,我是刑警寧澤晚胡,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布灵奖,位于F島的核電站,受9級特大地震影響估盘,放射性物質(zhì)發(fā)生泄漏瓷患。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一遣妥、第九天 我趴在偏房一處隱蔽的房頂上張望擅编。 院中可真熱鬧,春花似錦箫踩、人聲如沸爱态。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锦担。三九已至,卻和暖如春慨削,著一層夾襖步出監(jiān)牢的瞬間洞渔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工缚态, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留磁椒,地道東北人。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓玫芦,卻偏偏與公主長得像浆熔,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子桥帆,可洞房花燭夜當晚...
    茶點故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容