Lighttpd - Configuration
来源:互联网 发布:淘宝里添加门店库 编辑:程序博客网 时间:2024/05/22 02:29
配置文件应该是lighttpd源代码里面比较难的一部分,其中涉及了大量的结构体、变量、函数,
parser部分还涉及了一些编译原理的知识。这一部分我看了好几天,每天看之前都要复习一下
几个重要的结构体的组成和它们之间的关系。
我打算在对lighttpd的整个框架都理解透了以后再写分析,因为单独去分析某个部分的话会让人
不理解这个部分在整个项目中的作用,而且有些细节只有在理解整体之后才能知道到底为什么要
这样设计。
下面只是简单地分析一下整个配置文件的分析过程,不会涉及到具体的细节。
以下会涉及一点编译原理的知识,如tokenlize, scan, parse等并不特指某个
函数,而是编译过程的特定步骤。
1. server.c -> main
当用户使用-f选项指定了配置文件之后,在getopt中就会调用config_read(srv, optarg);这是整个分析的入口函数。后面还有一个配置函数:
config_set_defaults(srv);这个函数是用来检查一些必要的配置项是否正确,以及设置一些系统相关的配置。
2. 相关变量
在继续分析之前,先来看一下server结构体中的几个与配置信息有关的变量:array *config; /* 存放global配置的 */array *config_touched; /* 记录哪些配置项被使用了,在后面会看到它 */array *config_context; /* 存放所有的原始配置信息,即使用lemon parse出来 * 的所有符合语法(但不一定是有效(支持)的)的数据 *//* 把config_context中有效的配置信息提取出来存放在这里 */specific_config **config_storage; server_config srvconf; /* 存放与server关系比较大的配置信息 */
3. configfile.c -> config_read
config_t context; /* 作为Parse的第4个参数,存储parse过程中的信息 */...context->all_configs = srv->config_context; /* 在parse过程中所有对context->all_configs * 的修改就相当于对srv->config_context */... /* 一些默认的全局配置,var.PID和var.CWD */config_parse_file(srv, &context, fn); /* 读取文件并分析 */
4. configfile.c -> config_parse_file
tokenlizer_t t; /* 用于控制tokenlize过程的信息 */... /* 与文件路径和stream有关的一些判断 */tokenlizer_init(&t, filename, s.start, s.size);ret = config_parse(srv, context, &t); /* 真正开始scan和parse */
5. configfile.c -> config_parse
这个函数其实就是执行使用lemon的套路,关于lemon的简单使用之前写过了,这里就不再说了。简化之后就是这样:
pParser = configparserAlloc(malloc);while (config_tokenlizer(srv, t, &token_id, token)) configparser(pParser, token_id, token, context);configparser(pParser, 0, NULL, context);configparserFree(pParser, free);
6. configfile.c -> config_tokenlizer
config_tokenlizer就相当于一个scanner,把文件流中的字符切成一个一个的token,这个函数比较繁杂,我就不分析了,只需要稍微了解编译原理的知识应该就没什么问题了。
7. configfile.c -> config_read
经过上面几个分析过程之后就回到了这里,这个时候对配置文件的分析其实就结束了,之后就是要保证"mod_indexfile" "mod_dirlisting" "mod_staticfile"这三个模块
必须要加载,而且"mod_indexfile"必须是所有模块中的第一个,因为接受到客户端的请求
时,是按照配置的顺序传给相应的模块的,这样模块的顺序就需要考虑了,至于为什么
"mod_indexfile"要是第一个就不属于这里要写的内容了。
在这个函数的最后就是要从存放在context->all_configs (srv->config_context)里面的
原始数据中提取出有效(支持)的配置信息,存放在srv->context_storage:
config_insert(srv);
8. configfile.c -> config_insert
从srv->config_context中提取有效配置的关键就在于:config_values_t cv[] = {...}; /* 这里存储了所有支持的配置项,如果srv->config_context * 里面的匹配这里的配置项,那么这一个配置就是有效的 */... /* 下面的一大段都是为了初始化cv[]的,其中cv[x]->destination * 指向了每一个配置项的值存放的地方,提取出来的信息就是存放在这里的 */config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv);
9. configfile-glue.c -> config_insert_values_global
这个函数只是简单地把srv->config_context里面使用到的有效配置项记录到srv->config_touched里面,然后调用config_insert_values_internal。
10. configfile-glue.c -> config_insert_values_internal
根据cv[i].type把srv->config_context提取出来的配置项的值复制到相应的cv[i].destination里面。到了这一步,所有从配置文件读出来的配置项的值就存放到相应的地方了。
11. configparser.y
最后在来看一下这个lemon使用的文件,这个文件比较复杂,这里只是提一下需要注意的地方:%extra_argument {config_t *ctx} /* 之前提到的第4个参数 */%name configparser /* 生成的代码函数接口的前缀,默认是Parse */... /* 后面是针对每个rule reduce时要执行代码。由于要支持嵌套结构,所以其中要用到一些栈的思想和操作, * 栈的信息存储在ctx->configs_stack中。还有一点值得注意的是,内层嵌套的配置项的值是“继承”外层的, * 也就是说,如果内层出现了和外层一样的配置项的话,那么内层配置项的值要先从外层拷贝进来,然后再在 * 后面加上新的值,而外层的值不会收到内层的影响。*/
好吧,就先分析到这里。分析这一部分确实比较累人,以后可能会结合不同配置项在整个程序中的作用再具体分析。
- Lighttpd - Configuration
- Lighttpd PHP fastcgi configuration
- lighttpd
- lighttpd
- lighttpd
- lighttpd
- /etc/lighttpd/lighttpd.conf
- configuration
- configuration
- configuration
- Configuration
- Configuration
- Configuration
- Configuration
- @Configuration
- configuration
- Lighttpd + ror
- lighttpd 笔记
- [Effective WX] 理解wxWindow中增加和去除/销毁子窗口的过程
- 无法解密受保护的XML节点“DTS:Password”
- 通过继承来扩展接口
- 关于Handler与Message与Messager的问题
- Linux消息队列详解
- Lighttpd - Configuration
- 关于vmware player列表无法删除虚拟机和无法添加虚拟机的解决办法。
- Qt___常用事件____操作
- C++中的继承
- input file 检验格式名验证是否上传
- 语录:101条伟大的计算机编程名言
- 关于iframe中嵌套的页面刷新的问题
- [Effective WX] wxEvtHandler类相关
- Android中如何查看内存