首页 »编程综合 » plugin插件:Lighttpd1.4.20源码分析的插件系统(1)---plugin结构体和插件接口 »正文
plugin插件:Lighttpd1.4.20源码分析的插件系统(1)---plugin结构体和插件接口
来源: 发布时间:星期三, 2010年3月17日 浏览:0次 评论:0
在lighttpd中 ![](/icons/64894dou.gif) 使用插件 ![](/icons/64894de.gif) 形式来增加服务 ![](/icons/64894de.gif) 功能 ![](/icons/64894dou2.gif) 同时 ![](/icons/64894dou.gif) lighttpd提供了 ![](/icons/64894yi.gif) 个插件 ![](/icons/64894de.gif) 公共接口给开发者 ![](/icons/64894dou.gif) 方便第 3方提供额外 ![](/icons/64894de.gif) 插件 ![](/icons/64894dou2.gif) Lighttpd ![](/icons/64894de.gif) 插件接口主要提供在plugin.h文件中 ![](/icons/64894dou2.gif) 其中 ![](/icons/64894dou.gif) plugin结构体是最核心 ![](/icons/64894de.gif) 部分 ![](/icons/64894dou2.gif) plugin结构体 ![](/icons/64894de.gif) 定义如下: 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 ... 纯虚![](/icons/64894hanshu.gif) 在子类中要予以赋值![](/icons/64894dou2.gif) 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;
可以看出 ![](/icons/64894dou.gif) 在结构体plugin ![](/icons/64894de.gif) 设计中 ![](/icons/64894dou.gif) 作者使用了面向对象 ![](/icons/64894de.gif) 思想 ![](/icons/64894dou2.gif) plugin结构体就是 ![](/icons/64894yi.gif) 个虚基类 ![](/icons/64894dou.gif) 其中 ![](/icons/64894de.gif) 数据成员 ![](/icons/64894dou.gif) 如name ![](/icons/64894dou.gif) version等都是子类公有 ![](/icons/64894de.gif) ![](/icons/64894dou2.gif) 而随后 ![](/icons/64894de.gif) ![](/icons/64894yi.gif) 系列 ![](/icons/64894hanshu.gif) 指针则是虚 ![](/icons/64894hanshu.gif) ![](/icons/64894dou.gif) 这些 ![](/icons/64894hanshu.gif) 指针在plugin结构体中并没有进行赋值 ![](/icons/64894dou.gif) 要求所有 ![](/icons/64894de.gif) 子类必须对其进行赋值 ![](/icons/64894dou2.gif) 区别 ![](/icons/64894de.gif) 子类对这些 ![](/icons/64894hanshu.gif) 指针赋区别 ![](/icons/64894de.gif) 值 ![](/icons/64894dou.gif) 在进行 ![](/icons/64894hanshu.gif) ![](/icons/64894diaoyong.gif) ![](/icons/64894de.gif) 时候就可以实现多态 ![](/icons/64894dou2.gif) 另外 ![](/icons/64894dou.gif) c语言毕竟不支持面向对象 ![](/icons/64894dou.gif) 因此 ![](/icons/64894dou.gif) 在通过c实现面向对象 ![](/icons/64894de.gif) 时候大多情况先是要靠人 ![](/icons/64894de.gif) 理解 ![](/icons/64894dou.gif) 而不是语言上 ![](/icons/64894de.gif) 约束 ![](/icons/64894dou2.gif) 如 ![](/icons/64894dou.gif) 这里说plugin结构体是 ![](/icons/64894yi.gif) 个虚基类 ![](/icons/64894dou.gif) 实际上所有 ![](/icons/64894de.gif) 子类都是这个结构体 ![](/icons/64894de.gif) 例子 ![](/icons/64894dou.gif) 而子类 ![](/icons/64894de.gif) 例子只有 ![](/icons/64894yi.gif) 个 ![](/icons/64894dou.gif) 也就是他自己 ![](/icons/64894dou2.gif) 这就和C ![](/icons/64894jiajia.gif) 中 ![](/icons/64894de.gif) 子类区别了 ![](/icons/64894dou2.gif) 在 plugin结构体中 ![](/icons/64894dou.gif) version成员比较重要 ![](/icons/64894dou2.gif) 很明显 ![](/icons/64894dou.gif) 这个成员标记这个插件 ![](/icons/64894de.gif) 版本 ![](/icons/64894dou2.gif) 在plugin结构体中定义 ![](/icons/64894de.gif) 那 ![](/icons/64894yi.gif) 系列 ![](/icons/64894hanshu.gif) 指针是插件 ![](/icons/64894de.gif) 对外接口 ![](/icons/64894dou.gif) 也就是插件对lighttpd ![](/icons/64894de.gif) 接口 ![](/icons/64894dou.gif) lighttpd只知道这些接口 ![](/icons/64894dou.gif) 通过 ![](/icons/64894diaoyong.gif) 这些接口来完成工作 ![](/icons/64894dou2.gif) 随着lighttpd ![](/icons/64894de.gif) 不断改进 ![](/icons/64894dou.gif) 这些接口可能满足不了服务器 ![](/icons/64894de.gif) 要求 ![](/icons/64894dou.gif) 因此要对其进行改进 ![](/icons/64894dou.gif) 这样就有可能造成以前开发 ![](/icons/64894de.gif) 插件无法使用 ![](/icons/64894dou2.gif) 通过version成员 ![](/icons/64894dou.gif) 在加载插件 ![](/icons/64894de.gif) 时候判断这个插件是否符合当前服务器 ![](/icons/64894de.gif) 版本 ![](/icons/64894dou.gif) 也就是接口是否相符 ![](/icons/64894dou2.gif) 如果不相符 ![](/icons/64894dou.gif) 则不加载插件 ![](/icons/64894dou.gif) 这样就可以避免由于接口 ![](/icons/64894de.gif) 不相符造成服务器 ![](/icons/64894de.gif) 崩溃等问题 ![](/icons/64894dou2.gif) 这些 ![](/icons/64894hanshu.gif) 指针在lighttpd ![](/icons/64894de.gif) 文档中被称作'hooks' ![](/icons/64894dou2.gif) 分为serverwide hooks和connectionwide hooks ![](/icons/64894dou.gif) serverwide hooks是有服务器 ![](/icons/64894diaoyong.gif) ![](/icons/64894de.gif) ![](/icons/64894dou.gif) 主要处理 ![](/icons/64894yi.gif) 些 ![](/icons/64894chushi.gif) 化等辅助 ![](/icons/64894de.gif) 工作 ![](/icons/64894dou.gif) 包括:init ![](/icons/64894dou.gif) cleanup, ![](/icons/64894set.gif) _defaults, handle_trigger和handle_sighup ![](/icons/64894dou2.gif) connectionwide hooks主要是面向连接 ![](/icons/64894de.gif) ![](/icons/64894dou.gif) 在处理连接 ![](/icons/64894de.gif) 时候 ![](/icons/64894diaoyong.gif) 这些hooks完成相应 ![](/icons/64894de.gif) 工作 ![](/icons/64894dou2.gif) 这些hooks大部分在 ![](/icons/64894hanshu.gif) http_response_prepare ![](/icons/64894kh.gif) 中被 ![](/icons/64894diaoyong.gif) ![](/icons/64894dou2.gif)
至于这些hooks是在哪被 ![](/icons/64894diaoyong.gif) ![](/icons/64894dou.gif) 都完成哪些功能 ![](/icons/64894dou.gif) 在后面分析具体 ![](/icons/64894de.gif) 插件 ![](/icons/64894de.gif) 时候会详细介绍 ![](/icons/64894dou2.gif) 有兴趣 ![](/icons/64894de.gif) 读者可以阅读lighttpd源码包中doc文件夹下 ![](/icons/64894de.gif) plugins文件 ![](/icons/64894dou2.gif) 在plugin.h中 ![](/icons/64894dou.gif) plugin结构体 ![](/icons/64894de.gif) 定义后面还有 ![](/icons/64894yi.gif) 堆 ![](/icons/64894de.gif) ![](/icons/64894hanshu.gif) 声明: 1 plugins_load(server * srv); 2 void plugins_free(server * srv); 这两个很明显是加载和释放插件 ![](/icons/64894hanshu.gif) ![](/icons/64894dou2.gif) 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);
这 ![](/icons/64894yi.gif) 系列 ![](/icons/64894de.gif) plugins_call_XXXXX ![](/icons/64894hanshu.gif) 则是插件对外 ![](/icons/64894de.gif) 接口 ![](/icons/64894dou2.gif) 也就是说 ![](/icons/64894dou.gif) lighttpd服务器通过这些 ![](/icons/64894hanshu.gif) ![](/icons/64894dou.gif) ![](/icons/64894diaoyong.gif) 插件进行工作 ![](/icons/64894dou2.gif) lighttpd在 ![](/icons/64894diaoyong.gif) 插件 ![](/icons/64894de.gif) 时候并不知道到底 ![](/icons/64894diaoyong.gif) ![](/icons/64894de.gif) 是哪些插件 ![](/icons/64894dou.gif) 而仅仅 ![](/icons/64894diaoyong.gif) 上面 ![](/icons/64894de.gif) ![](/icons/64894hanshu.gif) ![](/icons/64894dou2.gif) 这些 ![](/icons/64894hanshu.gif) 再 ![](/icons/64894diaoyong.gif) 相应 ![](/icons/64894de.gif) 插件 ![](/icons/64894de.gif) ![](/icons/64894hanshu.gif) ![](/icons/64894dou.gif) 从而完成工作 ![](/icons/64894dou2.gif) 具体如何 ![](/icons/64894diaoyong.gif) 插件 ![](/icons/64894de.gif) ![](/icons/64894hanshu.gif) ![](/icons/64894dou.gif) 放在后面 ![](/icons/64894de.gif) 文章中介绍 ![](/icons/64894dou2.gif) 最后面 ![](/icons/64894de.gif) config_XXXXXX ![](/icons/64894hanshu.gif) 是处理 ![](/icons/64894yi.gif) 些配置问题 ![](/icons/64894dou.gif) 暂不讨论 ![](/icons/64894dou2.gif) 在plugin.h文件中还定义了 ![](/icons/64894yi.gif) 些宏: 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![](/icons/64894kh.gif) 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 前面 ![](/icons/64894de.gif) 3个宏(SERVER_FUNC, CONNECTION_FUNC和INIT_FUNC)定义了 ![](/icons/64894hanshu.gif) 签名 ![](/icons/64894de.gif) 模板 ![](/icons/64894dou2.gif) 后面 ![](/icons/64894de.gif) ![](/icons/64894yi.gif) 系列宏和plugin结构体中 ![](/icons/64894de.gif) ![](/icons/64894hanshu.gif) 指针对应 ![](/icons/64894dou.gif) 确定这些 ![](/icons/64894hanshu.gif) 指针所对应 ![](/icons/64894de.gif) ![](/icons/64894hanshu.gif) 签名 ![](/icons/64894dou2.gif) 在进行插件开发 ![](/icons/64894de.gif) 时候 ![](/icons/64894dou.gif) 插件中 ![](/icons/64894de.gif) ![](/icons/64894hanshu.gif) 签名要使用上面 ![](/icons/64894de.gif) 宏来生成 ![](/icons/64894dou2.gif) 这样可以保证接口 ![](/icons/64894de.gif) 统 ![](/icons/64894yi.gif) ![](/icons/64894dou2.gif)
最后 ![](/icons/64894dou.gif) 还要提 ![](/icons/64894yi.gif) 下plugin.c文件中 ![](/icons/64894de.gif) 结构体: 1 typedef struct 2 { 3 PLUGIN_DATA; 4 } plugin_data; PLUGIN_DATA是 ![](/icons/64894yi.gif) 个宏 ![](/icons/64894dou.gif) 定义为:# ![](/icons/64894define.gif) PLUGIN_DATA size_t id ![](/icons/64894dou2.gif) 这个结构体用来存放插件所需要使用 ![](/icons/64894de.gif) 数据 ![](/icons/64894dou.gif) 这个结构体作为plugin结构体中 ![](/icons/64894hanshu.gif) 指针 ![](/icons/64894de.gif) 最后 ![](/icons/64894yi.gif) 个参数:void *p_d传入对应 ![](/icons/64894de.gif) ![](/icons/64894hanshu.gif) 中 ![](/icons/64894dou2.gif) 在plugin.c结构体中plugin_data ![](/icons/64894de.gif) 定义很简单 ![](/icons/64894dou.gif) 仅仅包含 ![](/icons/64894yi.gif) 个数据成员id ![](/icons/64894dou2.gif) 在mod_*.c/h文件中 ![](/icons/64894dou.gif) 同样也包含有plugin_data结构体 ![](/icons/64894de.gif) 定义 ![](/icons/64894dou2.gif) 如:mod_cgi.c中 ![](/icons/64894dou.gif) 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; 等等 ![](/icons/64894dou2.gif) 这些定义有 ![](/icons/64894yi.gif) 个共通 ![](/icons/64894de.gif) 特点 ![](/icons/64894dou.gif) 那就是第 ![](/icons/64894yi.gif) 个成员都是PLUGIN_DATA ![](/icons/64894dou2.gif) 这又是 ![](/icons/64894yi.gif) 个窍门技巧 ![](/icons/64894dou2.gif) 所有这些plugin_data相当于是plugin.c中 plugin_data ![](/icons/64894de.gif) 子类 ![](/icons/64894dou2.gif) 这些子类开始 ![](/icons/64894de.gif) 部分和父类相同 ![](/icons/64894dou.gif) 这就允许子类 ![](/icons/64894de.gif) 指针转换成父类指针 ![](/icons/64894dou.gif) 然后再转换回去 ![](/icons/64894dou.gif) 并保证数据不会丢失 ![](/icons/64894dou2.gif) 这样 ![](/icons/64894dou.gif) lighttpd所面对 ![](/icons/64894de.gif) 插件数据接口是plugin.c中定义 ![](/icons/64894de.gif) plugin_data ![](/icons/64894dou.gif) 当lighttpd在 ![](/icons/64894diaoyong.gif) 插件中 ![](/icons/64894de.gif) ![](/icons/64894hanshu.gif) ![](/icons/64894dou.gif) 并把数据传进去 ![](/icons/64894de.gif) 时候 ![](/icons/64894dou.gif) 插件可以再把数据 ![](/icons/64894de.gif) 类型还原回去 ![](/icons/64894dou2.gif) 这样 ![](/icons/64894dou.gif) 对于lighttpd ![](/icons/64894dou.gif) 所面对 ![](/icons/64894de.gif) 数据接口就只有 ![](/icons/64894yi.gif) 个 ![](/icons/64894dou.gif) 插件所需要 ![](/icons/64894de.gif) 数据可以不对lighttpd公开 ![](/icons/64894dou.gif) 这就很好 ![](/icons/64894de.gif) 隐藏了数据 ![](/icons/64894dou2.gif) 同时也简化了lighttpd ![](/icons/64894de.gif) 复杂度 ![](/icons/64894dou.gif) 提高了 ![](/icons/64894chengxu.gif) ![](/icons/64894de.gif) 扩展性 ![](/icons/64894dou2.gif) 下 ![](/icons/64894yi.gif) 篇中 ![](/icons/64894dou.gif) 将解释lighttpd中插件 ![](/icons/64894de.gif) 加载和 ![](/icons/64894chushi.gif) 化
相关文章
读者评论
发表评论
|
|