专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »编程综合 » plugin插件:Lighttpd1.4.20源码分析的插件系统(1)---plugin结构体和插件接口 »正文

plugin插件:Lighttpd1.4.20源码分析的插件系统(1)---plugin结构体和插件接口

来源: 发布时间:星期三, 2010年3月17日 浏览:0次 评论:0
  在lighttpd中使用插件形式来增加服务功能同时lighttpd提供了个插件公共接口给开发者方便第 3方提供额外插件Lighttpd插件接口主要提供在plugin.h文件中其中plugin结构体是最核心部分

  plugin结构体定义如下:

 1 typedef struct 
 2 {
 3     size_t version;
 4 
 5     buffer *name;                /* name of the plugin */
 6 
 7     void *(*init) ;
 8     handler_t(*_defaults) (server * srv, void *p_d);
 9     handler_t(*cleanup) (server * srv, void *p_d);
10 
11     /*
12      * is called ... 纯虚在子类中要予以赋值
13      */
14     handler_t(*handle_trigger) (server * srv, void *p_d);    /* once a second */
15     handler_t(*handle_sighup) (server * srv, void *p_d);    /* at a signup */
16     handler_t(*handle_uri_raw) (server * srv, connection * con, void *p_d); /* after uri_raw is  */
17     handler_t(*handle_uri_clean) (server * srv, connection * con, void *p_d);/* after uri is  */
18     handler_t(*handle_docroot) (server * srv, connection * con, void *p_d);    /* getting the document-root */
19     handler_t(*handle_physical) (server * srv, connection * con, void *p_d);    /* mapping url to physical path */
20     handler_t(*handle_request_done) (server * srv, connection * con, void *p_d);    /* at the end of a request */
21     handler_t(*handle_connection_close) (server * srv, connection * con, void *p_d);    /* at the end of a connection */
22     handler_t(*handle_joblist) (server * srv, connection * con, void *p_d);    /* after all events are handled */
23     handler_t(*handle_subrequest_start) (server * srv, connection * con, void *p_d);
24 
25     /*
26      * when a handler for the request has to be found 
27      */
28     handler_t(*handle_subrequest) (server * srv, connection * con, void *p_d);    /* */
29     handler_t(*connection_re) (server * srv, connection * con, void *p_d);    /* */
30     void *data;
31 
32     /*
33      * dlopen handle 
34      */
35     void *lib;
36 } plugin;


  可以看出在结构体plugin设计中作者使用了面向对象思想plugin结构体就是个虚基类其中数据成员如nameversion等都是子类公有而随后系列指针则是虚这些指针在plugin结构体中并没有进行赋值要求所有子类必须对其进行赋值区别子类对这些指针赋区别在进行时候就可以实现多态

  另外c语言毕竟不支持面向对象因此在通过c实现面向对象时候大多情况先是要靠人理解而不是语言上约束这里说plugin结构体是个虚基类实际上所有子类都是这个结构体例子而子类例子只有也就是他自己这就和C子类区别了

  在 plugin结构体中version成员比较重要很明显这个成员标记这个插件版本在plugin结构体中定义系列指针是插件对外接口也就是插件对lighttpd接口lighttpd只知道这些接口通过这些接口来完成工作随着lighttpd不断改进这些接口可能满足不了服务器要求因此要对其进行改进这样就有可能造成以前开发插件无法使用通过version成员在加载插件时候判断这个插件是否符合当前服务器版本也就是接口是否相符如果不相符则不加载插件这样就可以避免由于接口不相符造成服务器崩溃等问题

  这些指针在lighttpd文档中被称作'hooks'分为serverwide hooks和connectionwide hooksserverwide hooks是有服务器主要处理化等辅助工作包括:initcleanup, _defaults, handle_trigger和handle_sighupconnectionwide hooks主要是面向连接在处理连接时候这些hooks完成相应工作这些hooks大部分在 http_response_prepare中被

  至于这些hooks是在哪被都完成哪些功能在后面分析具体插件时候会详细介绍有兴趣读者可以阅读lighttpd源码包中doc文件夹下plugins文件

  在plugin.h中plugin结构体定义后面还有声明:

1  plugins_load(server * srv);
2  void plugins_free(server * srv);


  这两个很明显是加载和释放插件

 1 handler_t plugins_call_handle_uri_raw(server * srv, connection * con);
 2 handler_t plugins_call_handle_uri_clean(server * srv, connection * con);
 3 handler_t plugins_call_handle_subrequest_start(server * srv, connection * con);
 4 handler_t plugins_call_handle_subrequest(server * srv, connection * con);
 5 handler_t plugins_call_handle_request_done(server * srv, connection * con);
 6 handler_t plugins_call_handle_docroot(server * srv, connection * con);
 7 handler_t plugins_call_handle_physical(server * srv, connection * con);
 8 handler_t plugins_call_handle_connection_close(server * srv, connection * con);
 9 handler_t plugins_call_handle_joblist(server * srv, connection * con);
10 handler_t plugins_call_connection_re(server * srv, connection * con);
11 
12 handler_t plugins_call_handle_trigger(server * srv);
13 handler_t plugins_call_handle_sighup(server * srv);
14 
15 handler_t plugins_call_init(server * srv);
16 handler_t plugins_call__defaults(server * srv);
17 handler_t plugins_call_cleanup(server * srv);


  这系列plugins_call_XXXXX则是插件对外接口也就是说lighttpd服务器通过这些插件进行工作 lighttpd在插件时候并不知道到底是哪些插件而仅仅上面这些相应插件从而完成工作具体如何插件放在后面文章中介绍

  最后面config_XXXXXX是处理些配置问题暂不讨论

  在plugin.h文件中还定义了些宏:

 1 # SERVER_FUNC(x) \
 2          handler_t x(server *srv, void *p_d)
 3  # CONNECTION_FUNC(x) \
 4      handler_t x(server *srv, connection *con, void *p_d)
 5 # INIT_FUNC(x)   void *x
 6 
 7 # FREE_FUNC          SERVER_FUNC
 8 # TRIGGER_FUNC       SERVER_FUNC
 9 # SETDEFAULTS_FUNC   SERVER_FUNC
10 # SIGHUP_FUNC        SERVER_FUNC
11 # SUBREQUEST_FUNC    CONNECTION_FUNC
12 # JOBLIST_FUNC       CONNECTION_FUNC
13 # PHYSICALPATH_FUNC  CONNECTION_FUNC
14 # REQUESTDONE_FUNC   CONNECTION_FUNC
15 # URIHANDLER_FUNC    CONNECTION_FUNC


  前面 3个宏(SERVER_FUNC, CONNECTION_FUNC和INIT_FUNC)定义了签名模板后面系列宏和plugin结构体中指针对应确定这些指针所对应签名

  在进行插件开发时候插件中签名要使用上面宏来生成这样可以保证接口

  最后还要提下plugin.c文件中结构体:

1 typedef struct 
2 {
3     PLUGIN_DATA;
4 } plugin_data;


  PLUGIN_DATA是个宏定义为:# PLUGIN_DATA  size_t id

  这个结构体用来存放插件所需要使用数据这个结构体作为plugin结构体中指针最后个参数:void *p_d传入对应在plugin.c结构体中plugin_data定义很简单仅仅包含个数据成员id在mod_*.c/h文件中同样也包含有plugin_data结构体定义如:mod_cgi.c中

1 typedef struct {
2     PLUGIN_DATA;
3     buffer_pid_t cgi_pid;
4     buffer *tmp_buf;
5     buffer *parse_response;
6     plugin_config **config_storage;
7     plugin_config conf;
8 } plugin_data;


  在mod_cml.h中:

1 typedef struct {
2     PLUGIN_DATA;
3     buffer *basedir;
4     buffer *baseurl;
5     buffer *trigger_handler;
6     plugin_config **config_storage;
7     plugin_config conf;
8 } plugin_data;


  等等

  这些定义有个共通特点那就是第个成员都是PLUGIN_DATA这又是个窍门技巧所有这些plugin_data相当于是plugin.c中 plugin_data子类这些子类开始部分和父类相同这就允许子类指针转换成父类指针然后再转换回去并保证数据不会丢失这样lighttpd所面对插件数据接口是plugin.c中定义plugin_data当lighttpd在插件中并把数据传进去时候插件可以再把数据类型还原回去这样对于lighttpd所面对数据接口就只有插件所需要数据可以不对lighttpd公开这就很好隐藏了数据同时也简化了lighttpd复杂度提高了扩展性



  下篇中将解释lighttpd中插件加载和



0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: