首页 »编程综合 » 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结构体就是 个虚基类 其中 数据成员 如name version等都是子类公有 而随后 系列 指针则是虚 这些 指针在plugin结构体中并没有进行赋值 要求所有 子类必须对其进行赋值 区别 子类对这些 指针赋区别 值 在进行 时候就可以实现多态 另外 c语言毕竟不支持面向对象 因此 在通过c实现面向对象 时候大多情况先是要靠人 理解 而不是语言上 约束 如 这里说plugin结构体是 个虚基类 实际上所有 子类都是这个结构体 例子 而子类 例子只有 个 也就是他自己 这就和C 中 子类区别了 在 plugin结构体中 version成员比较重要 很明显 这个成员标记这个插件 版本 在plugin结构体中定义 那 系列 指针是插件 对外接口 也就是插件对lighttpd 接口 lighttpd只知道这些接口 通过 这些接口来完成工作 随着lighttpd 不断改进 这些接口可能满足不了服务器 要求 因此要对其进行改进 这样就有可能造成以前开发 插件无法使用 通过version成员 在加载插件 时候判断这个插件是否符合当前服务器 版本 也就是接口是否相符 如果不相符 则不加载插件 这样就可以避免由于接口 不相符造成服务器 崩溃等问题 这些 指针在lighttpd 文档中被称作'hooks' 分为serverwide hooks和connectionwide hooks serverwide hooks是有服务器 主要处理 些 化等辅助 工作 包括:init cleanup, _defaults, handle_trigger和handle_sighup connectionwide 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中插件 加载和 化
相关文章
读者评论
发表评论
|
|