apache分析之三、配置文件解析

一、可配置型
作为当前世界上部署最为广泛的Web服务器,apache具有很好的扩展性。这种扩展性和内核中的扩展性几乎有相同的作用和意义(核心的实现方法也是相同的,这两个实现应该是有相互借鉴的,只是不确定最早是谁提出的,或者两者都不是,而是从另外更早的unix版本中提出,不确定。),但是它的可配置性更好一些,文件的配置可以通过配置文件来设置。各种mod内容在服务器启动的时候可以根据不同的需求进行裁剪。在网络上搜索的时候,无意间看到Apache可以作为A PAtCHy sErver的缩写,可见apache的扩展性还是很好的。
二、配置文件格式
apache的配置文件比通常的ini文件要复杂一些,因为ini文件中配置的都只是数据,而apache的配置文件中配置的是指令,其中每一条命令都可以看做是一个指令,其中的section可以看做是一种特殊的指令语句。从这一点看,apache的配置文件又和Tcl语言相同,如果大家对这个不是很熟悉,可以参考一下expect的功能和实现,不过我想大部分是应该是两种都不熟悉的。
奇妙的是,这些命令同样可以通过LoadModule来动态加载,这样只要你加载了一个模块,就可以在模块中加载更多的东西,所谓一生二、二生三、三生万物,就是这个道理。这样系统的扩展扩展性就非常好。
当然命令的注册同样有一些基础设施性质的功能,让命令的注册非常方便。我们常见的Location、Directy等在apache中同样是作为一个内置的命令定义的,虽然定义位置不同,但是它们和我们在LoadModule中添加的命令格式和功能都是相同的。
对于我们最为喜闻乐见的常见内容,它们作为核心组件位于core.c文件中、
static const command_rec core_cmds[] = {

/* Old access config file commands */

AP_INIT_RAW_ARGS("<Directory", dirsection, NULL, RSRC_CONF,
  "Container for directives affecting resources located in the specified "
  "directories"),
AP_INIT_RAW_ARGS("<Location", urlsection, NULL, RSRC_CONF,
  "Container for directives affecting resources accessed through the "
  "specified URL paths"),
AP_INIT_RAW_ARGS("<VirtualHost", virtualhost_section, NULL, RSRC_CONF,
  "Container to map directives to a particular virtual host, takes one or "
  "more host addresses"),
AP_INIT_RAW_ARGS("<Files", filesection, NULL, OR_ALL,
  "Container for directives affecting files matching specified patterns"),
AP_INIT_RAW_ARGS("<Limit", ap_limit_section, NULL, OR_LIMIT | OR_AUTHCFG,
  "Container for authentication directives when accessed using specified HTTP "
  "methods"),
这个结构类型和我们在mod_dav中注册的DAV命令使用的都是相同的结构定义
static const command_rec dav_cmds[] =
{
    /* per directory/location */
    AP_INIT_TAKE1("DAV", dav_cmd_dav, NULL, ACCESS_CONF,
                  "specify the DAV provider for a directory or location"),
三、在文件解析时节的意义
在配置文件中,可以通过 
<directive>
cmd
</directive>
来定义一些所谓节的内容。apache是内置支持这种格式的,它的意义在于能够将命令的使用范围现在在一个相对较小的section的范围内,这样就可以为不同的节定义不同的配置文件。apache对该配置的解析位于ap_build_config_sub文件中,
   if (cmd_name[0] == '<') {
        if (cmd_name[1] != '/') {
            (*current) = ap_add_node(curr_parent, *current, newdir, 1);
        }
        else if (*curr_parent == NULL) {
            parms->err_directive = newdir;
            return apr_pstrcat(p, cmd_name,
                               " without matching <", cmd_name + 2,
                               " section", NULL);
        }
        else {开始一个新的section
……

            /* done with this section; move up a level */
            *current = *curr_parent;
            *curr_parent = (*current)->parent;
        }
    }
    else {
        *current = ap_add_node(curr_parent, *current, newdir, 0);
    }
原文地址:https://www.cnblogs.com/tsecer/p/10487820.html