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

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

</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);

    }