Apache模块开发
一、简介
Apache HTTP服务器是一个模块化的软件,使管理者可以选择核心中包含的模块以裁剪功能。可以在编译时选择被静态包含进httpd二进制映象的模块,也可以编译成独立于主httpd二进制映象的动态共享对象DSO,DSO模块可以在编译服务器之后编译,也可以用Apache扩展工具(apxs)编译并增加。
Apache模块开发主要采用挂钩子的方法来实现模块开发的,这和linux内核模块开发有点像,说白了就是加一个回调函数。
二、安装Apache的apxs
apxs是一个为Apache HTTP服务器编译和安装扩展模块的工具,用于编译一个或多个源程序或目标代码文件为动态共享对象,使之可以用由mod_so提供的LoadModule指令在运行时加载到Apache服务器中。
apxs参考文档:http://lamp.linux.gov.cn/Apache/ApacheMenu/programs/apxs.html
查看是否有httpd-devel这个包,如果没有需要安装
#rpm -qa | grep httpd #查看
#yum -y install httpd-devel #安装
三、开发实例
程序1:apache模块开发之内容生成器
执行以下命令,将生成helloworld的模板
apxs -g -n helloworld
生成的代码如下:
/*
** 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 httpd.conf file for instance
** for the URL /helloworld in as follows:
**
** # httpd.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 */
};
编译
apxs -c mod_helloworld.c
安装
apxs -i mod_helloworld.la
修改配置文件httpd.conf,以加载模块,主要添加如下内容
LoadModule helloworld_module modules/mod_helloworld.so
<Location /helloworld>
SetHandler helloworld
</Location>
重启服务器,进行测试
apachectl -k stop #停止
apachectl -k start #启动
在浏览器中输入url,即可看到效果

程序2:apache模块开发之输出过滤器
对于过滤器,有输入过滤器与输出过滤器两种,有下面的顺序:
请求--输入过滤器--内容生成器--输出过滤器--响应
所有的请求都会经过我们的过滤器,所以我们可以对这些进行操作,比如统计流量、数据压缩等。下面示例可把页面中所有的小写字母变成大写字母。
/**
* @file: mod_casefilter.c
* @brief: 把页面中所有的小写字母变成大写字母
*/
#include "httpd.h"
#include "http_config.h"
#include "apr_buckets.h"
#include "apr_general.h"
#include "apr_lib.h"
#include "util_filter.h"
#include "http_request.h" #include <ctype.h> static const char s_szCaseFilterName[]="CaseFilter";
module AP_MODULE_DECLARE_DATA case_filter_module; typedef struct
{
int bEnabled;
} CaseFilterConfig; static void *CaseFilterCreateServerConfig(apr_pool_t *p,server_rec *s)
{
CaseFilterConfig *pConfig=apr_pcalloc(p,sizeof *pConfig); pConfig->bEnabled=0; return pConfig;
} static void CaseFilterInsertFilter(request_rec *r)
{
CaseFilterConfig *pConfig=ap_get_module_config(r->server->module_config,
&case_filter_module); if (!pConfig->bEnabled)
return; ap_add_output_filter(s_szCaseFilterName,NULL,r,r->connection);
} static apr_status_t CaseFilterOutFilter(ap_filter_t *f,
apr_bucket_brigade *pbbIn)
{
request_rec *r = f->r;
conn_rec *c = r->connection;
apr_bucket *pbktIn;
apr_bucket_brigade *pbbOut; pbbOut=apr_brigade_create(r->pool, c->bucket_alloc);
for (pbktIn = APR_BRIGADE_FIRST(pbbIn);
pbktIn != APR_BRIGADE_SENTINEL(pbbIn);
pbktIn = APR_BUCKET_NEXT(pbktIn))
{
const char *data;
apr_size_t len;
char *buf;
apr_size_t n;
apr_bucket *pbktOut; if (APR_BUCKET_IS_EOS(pbktIn))
{
apr_bucket *pbktEOS=apr_bucket_eos_create(c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(pbbOut,pbktEOS);
continue;
} /* read */
apr_bucket_read(pbktIn,&data,&len,APR_BLOCK_READ); /* write */
buf = apr_bucket_alloc(len, c->bucket_alloc);
for (n=0 ; n < len ; ++n)
buf[n] = apr_toupper(data[n]); pbktOut = apr_bucket_heap_create(buf, len, apr_bucket_free,
c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(pbbOut,pbktOut);
}
apr_brigade_cleanup(pbbIn);
return ap_pass_brigade(f->next,pbbOut);
} static const char *CaseFilterEnable(cmd_parms *cmd, void *dummy, int arg)
{
CaseFilterConfig *pConfig=ap_get_module_config(cmd->server->module_config,
&case_filter_module);
pConfig->bEnabled=arg; return NULL;
} static const command_rec CaseFilterCmds[] =
{
AP_INIT_FLAG("CaseFilter", CaseFilterEnable, NULL, RSRC_CONF,
"Run a case filter on this host"),
{ NULL }
}; static void CaseFilterRegisterHooks(apr_pool_t *p)
{
ap_hook_insert_filter(CaseFilterInsertFilter,NULL,NULL,APR_HOOK_MIDDLE);
ap_register_output_filter(s_szCaseFilterName,CaseFilterOutFilter,NULL,
AP_FTYPE_RESOURCE);
} module AP_MODULE_DECLARE_DATA case_filter_module =
{
STANDARD20_MODULE_STUFF,
NULL,
NULL,
CaseFilterCreateServerConfig,
NULL,
CaseFilterCmds,
CaseFilterRegisterHooks
};
编译
apxs -c mod_filter.c
安装
apxs -i mod_filter.la
配置httpd.conf,添加如下内容:
LoadModule case_filter_module modules/mod_casefilter.so
CaseFilter on
测试

Apache模块开发的更多相关文章
- Apache模块开发指南-APR池
转:原文: http://blog.csdn.net/zmxiangde_88/article/details/8038150 ------------------------------------ ...
- C语言-apache mod(模块开发)-采用apxs开发实战(centos7.2 linux篇)
C语言-apache mod(模块开发)-采用apxs开发实战(centos7.2 linux篇) 名词解释:apxs apxs is a tool for building and installi ...
- C语言-apache mod(模块开发)-采用VS2017开发实战(windows篇)
C语言-apache mod(模块开发)-采用VS2017开发实战(windows篇) 名词解释:apxs apxs is a tool for building and installing ext ...
- 用Perl编写Apache模块续二 - SVN动态鉴权实现SVNAuth 禅道版
代码地址:https://code.csdn.net/x3dcn/svnauth 以禅道项目管理系统的数据库结构为标准,实现了可用的svn authz验证功能. 以用户名.密码.项目的acl开发程度o ...
- 用Perl编写Apache模块
前言 Apache被许多大流量网站所嫌弃,但很多企业级的场景则更为适用. Apache httpd 从 2.0 之后,已经不仅仅局限于一个 http 的服务器,更是一个完善而强大.灵活而健壮且容易扩展 ...
- php在apache中一共有三种工作方式:CGI模式、FastCGI模式、Apache 模块DLL
php在apache中一共有三种工作方式:CGI模式.FastCGI .FastCGI是什么? FastCGI是语言无关的.可伸缩架构的CGI开放扩展,其主要行 为是将CGI解释器进程保持在内存中并因 ...
- 【转】Nginx模块开发入门
转自: http://kb.cnblogs.com/page/98352/ 结论:对Nginx模块开发入门做了一个helloworld的示例,简单易懂.也有一定的深度.值得一看. Nginx模块开发入 ...
- Nginx模块开发入门
前言 Nginx是当前最流行的HTTP Server之一,根据W3Techs的统计,目前世界排名(根据Alexa)前100万的网站中,Nginx的占有率为6.8%.与Apache相比,Nginx在高并 ...
- [转] Nginx模块开发入门
前言 Nginx是当前最流行的HTTP Server之一,根据W3Techs的统计,目前世界排名(根据Alexa)前100万的网站中,Nginx的占有率为6.8%.与Apache相比,Nginx在高并 ...
随机推荐
- Python while 循环使用实例
while循环是在Python中的循环结构之一. while循环继续,直到表达式变为假.表达的是一个逻辑表达式,必须返回一个true或false值,本文章向码农介绍Python while 循环使用方 ...
- javascript 常用获取页面宽高信息 API
在页面的构建中 常常会需要获取页面的一些宽高信息,例如实现 惰性加载图片 需要获取页面的可见区域高度 和 已滚动区域的高度,以判断图片所在位置是否可见来决定加载图片的时间, 花点时间整理了一下,获取页 ...
- 异步与websocket
异步与WebSockets 知识点 理解同步与异步执行过程 理解异步代码的回调写法与yield写法 Tornado异步 异步Web客户端AsyncHTTPClient tornado.web.asyn ...
- 模拟Vue之数据驱动1
一.前言 Vue有一核心就是数据驱动(Data Driven),允许我们采用简洁的模板语法来声明式的将数据渲染进DOM,且数据与DOM是绑定在一起的,这样当我们改变Vue实例的数据时,对应的DOM元素 ...
- mybatis 常用jdbcType数据类型
来自 : http://blog.csdn.net/paincupid/article/details/50922981
- Ztree学习(-)简单例子
https://www.cnblogs.com/shinhwazt/p/5828031.html ztree包:https://pan.baidu.com/s/1vOgGm_elF-lF0VowoHw ...
- mysql查看进程
select * from information_schema.processlist 查询所有连接到数据库的进程信息.
- 下载gradle缓慢的解决方法
用AndroidStudio或者Qt编译apk,下载gradle缓慢时,可以用迅雷等下载工具在https://services.gradle.org/distributions/下载对应的版本. 中断 ...
- Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?
1.什么是匿名内部类? 内部类,存在于另一个类内部的类,而匿名内部类,顾名思义,就是没有名字的内部类. 2.为什么需要匿名内部类? 每个inner class都能够各自继承某一实现类(implemen ...
- MySQL 逻辑备份工具
简介: Mydumper.Myloader 是一个第三方的.开源的 MySQL 逻辑备份工具. 支持多线程,比起 mysqldump 要快很多,也能解决 innobackupex 备份工具对 MyIS ...