Keep on going, never give up.

Apache模块开发实例

Apache模块开发入门还是非常简单的,只需简单的几步骤就可以DIY出自己的helloworld,本文测试系统为Ubuntu 12.04,在该系统下只需安装好apache和apache2-threaded-dev这两个包就可以了。然后直接使用apxs2编译和安装模块。

一、安装apache及其开发包

1、安装apache过程请参考:

Ubuntu VPS安装Apache+PHP+MySQL指南

2、安装apache2-threaded-dev

sudo apt-get install apache2-threaded-dev

默认安装路径为:/usr/bin/apxs2。

二、打造helloworld模块

1、程序源代码如下

拷贝另存为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_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_hooks  /* 注册模块的钩子函数                      */ 
    };   

其中,request_rec是个复杂结构体,其表示一个http请求,从这个结构体中可以获得浏览器连接的各种信息。

参考:

/*request_rec 下变量
char *hostname;//域名 localhost
char *args;    //域名参数(?号以后的内容)a=123
char *filename;//文件路径 /var/www/test
const char *content_encoding;
...       
*/

2、编译和安装

编译:

apxs2 -c mod_helloworld.c

安装:

apxs2 -i mod_helloworld.la

或,一句话命令:

  • apxs2 -iac mod_helloworld.c

执行完成后,helloworld模块被安装到:/usr/lib/apache2/modules,这里可能会报告权限错误,请确保有管理员权限方可执行安装模块动作。

3、创建conf配置文件

在/etc/apache2/mods-available下面创建helloworld.conf文件(页可能是在/etc/apache2/apache2.conf,根据实际选择),内容如下:

    LoadModule helloworld_module /usr/lib/apache2/modules/mod_helloworld.so
    <Location /helloworld>
            SetHandler helloworld
    </Location>

然后,为helloworld.conf创建一个快捷方式并放到/etc/apache2/mods-enabled下面:

ln -s /etc/apache2/mods-available/helloworld.load /etc/apache2/mods-enabled/helloworld.load

所以,模块目录在:/usr/lib/apache2/modules

当前生效模块目录在:/etc/apache2/mods-available

4、重启apache

service apache2 restart

重启apache后,在浏览器中输入”localhost/hellworld”,浏览器显示:

The sample page from mod_helloworld.c

三、常见问题

1、常见错误

apxs:Error: Sorry, cannot determine bootstrap symbol name. apxs:Error: Please specify one with option `-n'.

加个-n参数,给模块起个名字

apxs2 -iacn mod_helloworld.cpp ./mod_helloworld.so

2、带库模块的编译

a、库编译仍然采用gcc或g++,结果为libfun.so(示例),比如:

  • 标准C:gcc -shared fun.cpp -o libfun.so
  • C++:g++ -shared fun.cpp -o libfun.so
  • 带MYSQL: g++ -shared student.cpp fun.cpp -I/usr/include/mysql/ -lmysqlclient -lm -o libfun.so
  • 合并C++:g++ -shared fun1.cpp fun2.cpp -o libfun.so

b、编译APACHE c模块文件方法如下:

apxs2 -ica -L./ -lfun test.c -Wl,-rpath=/root/

如果是C++文件,添加-S CC=g++参数。-WL,-rpath=/root/表示APACHE运行时需加载libfun.so的放置目录。

该设置可以通过ldd test.so查看,结果如下:

root@ubuntu:~# ldd test.so
    linux-gate.so.1 =>  (0x00a32000)
    libfun.so => /root/libfun.so (0x0018e000)

如果编译时需包含MYSQL,只需确认MYSQl.h的头文件位置,然后添加-I/usr/include/mysql/编译选项。示例如:

apxs2 -c -L./ -I/usr/include/mysql/ -lmysqlclient -lfun test.c -Wl,-rpath=/root/

参数说明:

  • -I/usr/include/mysql/表示到该目录下找mysql相关头文件
  • -lmysqlclient表示链接时,必须把libmysqlclient库也链接进来,否则编译通过,但是Apache会提示mysql相关函数未定义错误。

 3、apxs2编译c++文件

如果编译C++文件,也必须改名为.c文件,然后类似如下方法(示例为只编译不安装):

apxs2 -ac -S CC=g++ -I../ calcserver.c

如需更多参数可以一并附加到apxs2后面,比如 -I/usr/local/include -lmylib -L/usr/local/lib/mydir

4、几个常见变量

获取客户端IP

r->connection->remote_ip

获取COOKIE

r->headers_in

获取URL参数

r->args

相关评论(0):  

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

订阅博客

最新文章

本站采用创作共用版权协议, 要求署名、非商业用途和保持一致. 转载也必须遵循“署名-非商业用途-保持一致”的创作共用协议. 返回顶部
Copyright@2005-2016 Metsky.com, All rights Reserved.