Apache模块嵌入技术的初步研究总结.docx
- 文档编号:7017116
- 上传时间:2023-01-16
- 格式:DOCX
- 页数:16
- 大小:22.57KB
Apache模块嵌入技术的初步研究总结.docx
《Apache模块嵌入技术的初步研究总结.docx》由会员分享,可在线阅读,更多相关《Apache模块嵌入技术的初步研究总结.docx(16页珍藏版)》请在冰豆网上搜索。
Apache模块嵌入技术的初步研究总结
Apache模块的初步研究总结
作者:
FREEDOM
日期:
2010/05/26
Apache作为Web服务器,除了可以写CGI程序完成各种Web应用外,Apache也提供了一套API来扩充服务器的功能。
Apache本身就是一个由多个模块(module)拼装而成的程序,它的API就是用来写Apache定义的模块的。
通过对Apache模块API的研究,总结如下:
一、Apache模块API的特点
●都是C的API:
Apache模块API是用标准C语言提供的。
●模块由一系列回调函数组成:
所谓的模块,就是实现一系列模块所需要的回调函数和提供符合预定义数据结构的值。
回调函数包括模块初始化(init)、配置信息处理(create_config、merge_config)、文件名转换处理(URI->filename)、内容处理程序(contenthandler)、专有日志输出(logger)等,回调函数可以根据需要全部或部分实现。
内容处理程序可以输出相应结果。
●一个模块可以包含一或多个内容处理程序回调函数:
若干个内容处理程序回调函数可以通过一个数据结构(handler_rec)指明。
如何激活相应的函数可以通过Apache的配置文件(conf/httpd.conf)指明。
内容处理程序可以在访问某个路径时或访问具有某种扩展名的文件时被激活。
●支持多种生命期的内存池(memorypool):
合理的使用可以防止内存泄露,使用内存池申请的动态空间可以在内容处理程序调用后或Apache正常退出时自动释放。
二、优点
Apache模块是和Apache绑定的,是Apache的一部分,无需每次HTTP请求时都需要加载。
三、缺点
●API可能会更新,由此会造成模块做相应的修改。
●每次改动模块要重新编译连接Apache(可以通过动态连接方式编译,还没做相应的试验)。
●对模块的健壮性要求高,因为模块是服务器的一部分。
●多了一套规范,推广难度比CGI大。
四、参考文档
http:
//httpd.apache.org/docs/misc/API.html
五、未来研究设想
目前的研究还是很初步的。
如果可能,未来还可以对以下领域做进一步的研究:
1.通过Apache配置文件配置模块的一些参数,如数据库参数;配置命令各种参数传递方式的使用;配置命令放在VirtaulHost内和VirtualHost外的区别和影响。
2.模块各阶段回调函数的深入研究,充分利用各种回调函数
3.子请求(subrequest)的研究
4.Apache源代码提供的各种操作函数
六、如何书写Apache模块
(本部分代码都可以在模块例子中找到)
1.定义Apache配置文件命令
staticconstcommand_recdump_cmds[]=
{
{
"Dump",/*directivename*/
cmd_dump,/*configactionroutine*/
NULL,/*argumenttoincludeincall*/
OR_OPTIONS,/*whereavailable*/
RAW_ARGS,/*arguments*/
"Dumpdirective-anyarguments"
/*directivedescription*/
},
{NULL}
};
这个结构指明了可以在Apache配置文件(conf/httpd.conf)可使用的配置命令(本例中为“Dump”)、处理该命令的函数名称(本例中为cmd_dump)、传递参数的方式(本例中为RAW_ARGS)。
配置命令处理函数的写法参加模块例子。
一个模块中可以处理若干个配置命令,结构数组最后一个值为NULL。
2.定义内容处理函数
staticconsthandler_recdump_handlers[]=
{
{"dump-handler",dump_handler},
{NULL}
};
这个结构指明了内容处理函数的名称(用于Apache配置文件,本例中为"dump-handler")和内容处理函数的名称(本例中为dump_handler)。
一个模块中可以有若干个内容处理函数,结构数组的最后一个值为NULL。
3.定义模块结构
moduleMODULE_VAR_EXPORTdump_module=
{
STANDARD_MODULE_STUFF,
dump_init,/*moduleinitializer*/
dump_create_dir_config,/*per-directoryconfigcreator*/
dump_merge_dir_config,/*dirconfigmerger*/
dump_create_server_config,/*serverconfigcreator*/
dump_merge_server_config,/*serverconfigmerger*/
dump_cmds,/*commandtable*/
dump_handlers,/*listofhandlers*/
dump_translate_handler,/*filename-to-URItranslation*/
dump_check_user_id,/*check/validateuser_id*/
dump_auth_checker,/*checkuser_idisvalid*here**/
dump_access_checker,/*checkaccessbyhostaddress*/
dump_type_checker,/*MIMEtypechecker/setter*/
dump_fixer_upper,/*fixups*/
dump_logger/*logger*/
#ifMODULE_MAGIC_NUMBER>=19970103
dump_header_parser/*headerparser*/
#endif
#ifMODULE_MAGIC_NUMBER>=19970719
dump_child_init/*processinitializer*/
#endif
#ifMODULE_MAGIC_NUMBER>=19970728
dump_child_exit/*processexit/cleanup*/
#endif
#ifMODULE_MAGIC_NUMBER>=19970902
dump_post_read_request/*postread_requesthandling*/
#endif
};
这个结构指明了模块的各种回调函数。
如果不需要某个回调函数,可以填NULL。
4.实现各种回调函数
根据实际需求实现各种回调函数,最重要的是内容处理函数。
5.写Apache模块重点注意事项
1)内存的分配(malloc)和释放(free)一定要配对
CGI程序可以对分配的内存不释放,其相应的内存空间会在CGI程序结束时由Apache回收;Apache模块由于是Apache的一部分,和Apache一起总是驻留在内存中,分配的空间一定要在Apache模块处理完一次请求时完全释放。
2)文件的打开(fopen)和关闭(fclose)要配对
理由同1)
3)socket的打开(socket)和关闭(close)要配对
理由同1)
4)不能使用强行退出进程的exit()函数
CGI是以进程为单位的,处理完一次HTTP请求,返回HTTP响应,CGI进程也就结束了;Apache模块是Apache的一部分,处理完一次请求只是内容处理函数的一次调用结束。
七、有关ApacheAPI的源代码
(以下所有的内容都是基于apache1.3.26源码的,其它版本大同小异)
1.主要目录:
src/include子目录:
可以引用的.h文件,包括一些常用的结构定义、工具函数定义
src/modules子目录:
Apache模块的总目录,扩充的模块也可以放在这个目录下和Apache程序一起编译
src/main子目录:
Apache程序的实现
2.主要文件介绍
●src/include/httpd.h
包含结构request_rec、conn_rec、server_rec的定义
包含时间、字符串处理函数
包含HTTP响应返回码定义
●src/include/ap_alloc.h
包含结构table_entry的定义、table的操作函数
包含通过内存池使用内存、文件的函数
●src/main/alloc.c
包含结构table的定义
●src/include/util_uri.h
包含结构uri_components的定义
●src/include/http_protocol.h
包含各种输出的HTTP客户端的函数
3.主要数据结构介绍
●request_rec
作用
Apache在接收客户端请求时收集的各种信息,是各种回调函数接收的主要参数;内容处理程序的结果也通过这个结构返回给客户端。
所在文件
src/include/httpd.h
主要字段(注意,指针变量有可能是NULL)
ap_pool*pool
给请求使用的内存池,请求处理后释放
conn_rec*connection
和请求连接有关的数据信息,如远端IP
server_rec*server
Apache服务器的配置信息,对应配置文件
char*the_request
客户端请求的第一行,如“GET/HTTP/1.1”
intheader_only
是否为HEAD请求标志
char*protocol
协议信息,例“HTTP/1.1”
intproto_num
协议版本,以整数表示,1.1表示成1001
constchar*hostname
客户端请求URL中的机器名部分
time_trequest_time
服务器接收到请求的时间(服务器时钟)
constchar*method
请求方法,GET、POST、HEAD等
intmethod_number
请求方法整数表示,M_GET、M_POST等,定义在同一文件中
longremaining
未读取的字节数,读POST数据时可以设置这个值
longread_length
已读取的字节数
table*headers_in
客户端请求的头信息,不包括第一行
table*headers_out
响应输出的头信息,如设置cookie
constchar*content_type
响应的内容类型,如“text/html”,可直接设置
char*unparsed_uri
包括参数在内的URI,从the_request中分析得到
char*uri
URI中的路径部分,去掉了unparsed_uri中的参数部分
char*filename
URI对应服务器端的绝对路径名
char*path_info
path_info信息
char*args
GET命令的参数部分(QUERY_STRING)
void*per_dir_config
目录配置信息
void*request_config
请求配置信息
●table_entry
作用
存储属性,是table结构中的基本元素
所在文件
src/include/ap_alloc.h
定义
typedefstruct{
char*key;/*maybeNULLinfuture;
*checkwheniterating
*thrutable_elts
*/
char*val;
}table_entry;
●command_rec
作用
定义配置命令,指明相应的函数及参数传送方式。
所在文件
src/include/http_config.h
字段定义
constchar*name;
命令名称
constchar*(*func)();
命令处理函数指针
void*cmd_data;
额外数据,供处理多个命令的函数使用
intreq_override;
命令允许出现的位置掩码
enumcmd_howargs_how;
参数传递方式。
NO_ARGS表示无参数、TAKE1表示带一个参数,等等。
constchar*errmsg;
使用方法,在出现语法错误时显示
●cmd_parms
作用
Apache调用命令处理时传递的参数
所在文件
src/include/http_config.h
定义
typedefstruct{
void*info;/*Argumenttocommandfromcmd_table*/
intoverride;/*Whichallow-overridebitsareset*/
intlimited;/*Whichmethodsare
configfile_t*config_file;/*配置文件结构*/
ap_pool*pool;/*内存池*/
structpool*temp_pool;/*临时内存池*/
server_rec*server;/*配置文件出现server信息*/
char*path;/*配置文件中所用的目录*/
constcommand_rec*cmd;/*configurationcommand*/
constchar*end_token;/*endtokenrequiredtoendanestedsection*/
void*context;/*per_dir_configvectorpassed
*tohandle_command*/
}cmd_parms;
●module
作用
模块定义。
指明各种回调函数。
所在文件
src/include/http_config.h
定义
typedefstructmodule_struct{
intversion;/*API版本*/
intminor_version;/*API次版本号*/
intmodule_index;/*configvectors.指向该模块的索引*/
constchar*name;
void*dynamic_load_handle;
structmodule_struct*next;
unsignedlongmagic;/*标识模块的Cookie,用于DSO*/
#ifdefULTRIX_BRAIN_DEATH
void(*init)();
void*(*create_dir_config)();
void*(*merge_dir_config)();
void*(*create_server_config)();
void*(*merge_server_config)();
#else
void(*init)(server_rec*,pool*);
void*(*create_dir_config)(pool*p,char*dir);
void*(*merge_dir_config)(pool*p,void*base_conf,void*new_conf);
void*(*create_server_config)(pool*p,server_rec*s);
void*(*merge_server_config)(pool*p,void*base_conf,void*new_conf);
#endif
constcommand_rec*cmds;
consthandler_rec*handlers;
/*各种回调函数定义
*translate_handler---把URI转成文件名
*access_checker---检查访问权限
*check_user_id---检查来自HTTP请求的userid合法性
*auth_checker---check_user_id提供user是否OK
*type_checker---决定响应的MIME类型,设置
*content_type、_encoding和_language。
*logger---写模块专用日志
*post_read_request---在read_request
*和internal_redirect后马上执行的函数,不会在
*任何subrequests后执行
*/
int(*translate_handler)(request_rec*);
int(*ap_check_user_id)(request_rec*);
int(*auth_checker)(request_rec*);
int(*access_checker)(request_rec*);
int(*type_checker)(request_rec*);
int(*fixer_upper)(request_rec*);
int(*logger)(request_rec*);
int(*header_parser)(request_rec*);
#ifdefULTRIX_BRAIN_DEATH
void(*child_init)();
void(*child_exit)();
#else
void(*child_init)(server_rec*,pool*);
void(*child_exit)(server_rec*,pool*);
#endif
int(*post_read_request)(request_rec*);
}module;
4.主要函数介绍
●ap_table_set
作用
设置table中的一个属性
所在文件
src/include/ap_alloc.h
定义
API_EXPORT(void)ap_table_set(table*,constchar*name,constchar*val);
例子
/*设置Cookie*/
ap_table_set(r->headers_out,"Set-Cookie","module=dump;path=/");
●ap_table_get
作用
取table中的一个属性值
所在文件
src/include/ap_alloc.h
定义
API_EXPORT(constchar*)ap_table_get(consttable*,constchar*);
例子
/*取Content-Length*/
char*cl=ap_table_get(r->headers_in,"Content-Length");
●ap_palloc
作用
申请指定字节的内存空间,放在内存池中。
类似malloc
所在文件
src/include/ap_alloc.h
定义
API_EXPORT(void*)ap_palloc(structpool*,intnbytes);
例子
char*buf=(char*)ap_palloc(r->pool,len+1);
if(buf==NULL)
{
....
}
●ap_pfopen/ap_pfclose
作用
在内存池中打开/关闭一个文件。
类似fopen/fclose
所在文件
src/include/ap_alloc.h
定义
API_EXPORT(FILE*)ap_pfopen(structpool*,constchar*name,constchar*fmode);
API_EXPORT(int)ap_pfclose(structpool*,FILE*);
例子
FILE*fp=ap_pfopen(r->pool,"filename","r");
fclose(r->pool,fp);
●ap_rputs
作用
往请求结构中输出一个字符串。
类似puts
所在文件
src/include/http_protocol.h
定义
API_EXPORT(int)ap_rputs(constchar*str,request_rec*r);
例子
ap_rputs("字符串内容\n",r);
●ap_rprintf
作用
往请求结构中格式化输出数据。
类似printf
所在文件
src/include/http_protocol.h
定义
API_EXPORT_NONSTD(int)ap_rprintf(request_rec*r,constchar*fmt,...)
__attribute__((format(printf,2,3)));
例子
ap_rprintf(r,"the_request(请求第一行):
%s\n",r->the_request);
●ap_send_fd
作用
往请求结构中输出一个文件的内容
所在文件
src/include/http_protocol.h
定义
API_EXPORT(long)ap_send_fd(FILE*f,request_rec*r);
例子
FILE*fLogo=fopen("/path/to/logo.gif","r");
if(fLogo!
=NULL)
{
ap_send_fd(fLogo,r);
fclose(fLogo);
}
●ap_get_client_block
作用
从请求结构中读取一个数据块,如读POST数据
所在文件
src/include/http_protocol.h
定义
API_EXPORT(long)ap_get_client_block(request_rec*r,char*buffer,intbufsiz);
例子
/*取Content-Length*/
char*cl=ap_table_get(r->headers_in,"Content-Length");
intlen=r->remaining=atoi(cl);
char*buf=(c
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Apache 模块 嵌入 技术 初步 研究 总结