设为首页 收藏本站
查看: 750|回复: 0

[经验分享] Apache Module 开发后记

[复制链接]

尚未签到

发表于 2015-8-3 07:47:12 | 显示全部楼层 |阅读模式
Apache Module 开发后记




由 qyb 在 周二, 2007-02-13 12:14 提交


  续上一篇文章
  开发出 apache 2.0 的模块以后,又面对着要将其移植到 apache 其他版本的需求,经过这段时间一点点的修补,现在我的模块已经可以同时在 1.3/2.0/2.2 下编译。甚至在 2.0/Win32 环境下也编译出了 dll,供在个人PC上做开发的同事使用。
  我感觉如果项目不复杂的话,可以学习我这样把所有的内容放在一个文件里面的做法。
  最重要的就是利用 MODULE_MAGIC_COOKIE 的定义,把 1.3 和 2.0/2.2 的不同之处融合在一起。例子:



  
#if MODULE_MAGIC_COOKIE == 0x41503230UL || MODULE_MAGIC_COOKIE == 0x41503232UL
#include "util_filter.h"
#include "apr_strings.h"
module AP_MODULE_DECLARE_DATA foobar_module;
#define APLOG_FOOBAR APLOG_ERR,0
#else
module MODULE_VAR_EXPORT foobar_module;
#define apr_pool_t          pool
#define apr_table_t         table
#define apr_pcalloc         ap_pcalloc
#define apr_table_unset     ap_table_unset
#define apr_table_set       ap_table_set
#define apr_table_get       ap_table_get
#define apr_table_make      ap_make_table
#define apr_pstrdup         ap_pstrdup
#define apr_snprintf        ap_snprintf
#define apr_pstrndup        ap_pstrndup
#define APLOG_FOOBAR APLOG_ERR
#endif /* MODULE_MAGIC_COOKIE == 0x41503230UL */
  

  同样,模块初始化的部分也这样针对不同版本定义一下。
  这样主要的功能函数就可以使用同样的代码模块,并使用 apr_* 系列函数族了。
  之所以要对 APLOG_ERR 做定义,是因为在 1.3 和 2.x 版本中,ap_log_error 和 ap_log_rerror 所使用的参数数目不一致,2.x 的参数要多一个,因此针对 2.x自动增加一个参数——",0"
  2.0 和 2.2 有些地方也有小差别,我的代码里面就碰到了 apr_socket_create 的参数不一样。同样简单 #if 就可以处理了。
  在 1.3 里面 module initializer 如果 2.x 里面的 post_config 会运行两次,而且2.x 上的这个小技巧无法直接使用了。本来是不影响程序运行的,但还是想出了一个变态的办法来解决它。module initializer 两次执行之间的一个重要事件就是 apache 的 daemonize。那样怎么来判断当前进程是否在 daemon 状态下呢?我的方案是:



  
/* 小技巧,用于帮助 init_module 只执行一次检查 */
#define MAX_FDS 1024
int daemon_flag(int fds[MAX_FDS])
{
int fd;
int newfd;
int i;
int opt;
socklen_t optlen = sizeof(int);
int ret = 0;
memset(fds, 0, sizeof(int) * MAX_FDS);
newfd = fd = socket(AF_INET,SOCK_STREAM,0);
while (newfd < MAX_FDS && newfd > 0) {
fds[newfd] = 1;
newfd = dup(fd);
}
for (i = 0; i < MAX_FDS; i++) {
if (fds == 1) {
close(i);
} else {
if (0 == getsockopt(i, SOL_SOCKET, SO_REUSEADDR, &opt, &optlen)) {
fds = -1; //这样返回以后也知道哪些 fd 被监听
ret = 1;
}
}
}
return ret;
}
  

  因为我知道 apache 必然会对监听套接字设置 SO_REUSEADDR,所以可如此判断。
  由于 apache2 有了 apr 的支持,几乎不用修改任何代码模块就可以在 win32 下编译。而且只需要 MS 的免费工具就可以了,包括 MSVC C++ Toolkit 2003 和 Platform SDK。设置好 INCLUDE/LIB 路径后,只需要执行
cl /MD /D "WIN32" /c mod_foobar.c
link /DLL mod_foobar.obj libhttpd.lib libapr.lib
  这样就得到了可被 LoadModule 的 mod_foobar.dll
  win32 下我碰到的问题稍微麻烦一些。启动 apache 无法成功,报告什么 OPENSSL_Applink 错误。看了 openssl 的 FAQ,说什么要 include 一个 applink.c,但仍然无济于事。不过查看 applink.c 后发现,它似乎和 IO 库相关;最后我把以前使用的 stdio 替换成了 openssl 自己的 bio 函数族,该问题就消失了。
  openssl 的 win32 库从这里下载并安装

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-93440-1-1.html 上篇帖子: 用Apache构建WEB服务器 下篇帖子: java apache commons HttpClient发送get和post请求的学习整理(转)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表