节选自《Apache源代码解析-基于Apache0.6.5》第九章。
9.1 概述
Apache除了可以把客户端请求的页面内容发送给客户端之外,还可以在没有页面的时候根据配置自己创建页面。
小王同学是做音乐的,有一些自己的原创音乐,会不定时上传一些音乐到网上供大家下载、试听、交流,但是小王同学不懂得网页制作,让我给他做一个个人音乐的展示、下载站点。要求在我不参与的情况下更新页面显示。
根据他的要求,我给他配置了一个站点出来,仅仅找了几个图标,修改了Apache的配置文件,就达到了他的要求。
配置文件及相关资源可以通过http://www.oldapache.org/example/chapter9/wang.rar 下载。下载后解压缩,可以看到有三个目录:icons、conf和htdocs。您需要把原有的htdocs目录和conf目录下的所有文件删除,使用下载的两个目录内容替换原有的同名目录;把icons目录下的3个图片复制到您原来的icons目录下即可。
启动您的Apache,打开浏览器,在地址栏输入http://www.yourdomain.com/ ,如果没有意外,页面显示效果类似于下图:
如果您打开htdocs目录,可以看到,在这个目录里面并没有类似于index.html这样的“主页”文件,直接在这个里面增加新的文件,会自动显示在“主页”里面。这就是Apache的自动索引目录功能产生的效果。
学术的定义:自动索引目录提供了一种在目录下没有默认主文件(如index.html)的时候显示目录下面所有非隐藏文件及其属性的功能。
那么我们需要怎么配置这个功能呢?
9.2 配置自动索引目录
Apache0.6.5提供了IndexIgnore、IndexOptions、AddIcon、AddIconByType、 AddIconByEncoding、AddAlt、AddAltByType、AddAltByEncoding、DefaultIcon、 ReadmeName、 HeaderName和AddDescription
共计12个指令来配置是否使用以及如何使用自动索引目录功能。
下面我们详细说明这11个指令的格式以及所达到的功效
1. IndexIgnore 指令
语法:IndexIgnore
file [
file ] …
功能:当自动索引目录的时候隐藏列表中指定的文件
示例:IndexIgnore
.
html
上面这个示例指令表示,在自动索引目录下内容的时候,不要显示该文件夹下的HTML文件。
2. IndexOptions 指令
语法:IndexOptions [+|-]
option [[+|-]
option ] ...
功能:自动索引目录时的各种配置选项
示例:IndexOptions SuppressSize
上面这个示例表示,在自动索引目录中显示文件大小列。
Apache0.6.5
支持7个可选的值,分别为:
FancyIndexing
:
对每种类型的文件前加上一个小图标以示区别。
IconsAreLinks
:图标成为一个链接。默认情况下,目录下的文件名作为一个链接可供人们点击进行下载。但是人们可能对更直观图标有爱好。这个选项开启后,人们可以通过点击文件名前的图标来下载相应的文件,开启这个选项需要同时开启FancyIndexing。
ScanHTMLTitles
:如果您的列表目录下有html文件,开启这个选项后,Apache会从这些html文件里面找到它们的title,并把title的内容作为文件的介绍来显示。
SuppressLastModified
:如果打开这个选项,文件的最后修改日期将作为一个列显示。
SuppressSize
:如果打开这个选项,文件的大小将作为一个列显示
SuppressDescription
:如果打开这个选项,文件的描述将作为一个列显示,之后可以通过AddDescription指令指定特定的文件(或文件类型)的描述。
None
:仅显示一个文件名及其链接
3. AddDescription 指令
语法:AddDescription
string file [
file ] ...
功能:对 file类型(名字)的文件设置描述内容为string
示例:AddDescription "Zip file" *.zip
上面的示例说明,对所有以.zip作为扩展名的文件,它的描述属性为“Zip file”。
4. AddIcon 指令
语法:AddIcon
icon name [
name ] ...
功能:对 name指定的文件类型使用icon图标
示例:AddIcon /icons/dir.gif ^^DIRECTORY^^
上面的示例说明,如果列表中的文件是一个目录,则使用/icons/dir.gif作为它的图标显示在文件(目录也是一种文件)名前面。
5. AddIconByType 指令
语法:AddIconByType
icon MIME-type [
MIME-type ] ...
功能:用来指定与图标相关联的文件,将应用于那些没有使用AddType指定进行关联的文件。和名字含义一样,这条指令给特定MINE类型的文件指定显示图标。
示例:AddIconByType /icons/image3.gif image/*
上面的示例说明,对于MIME类型是image/*的文件,它的图标将使用/icons/image3.gif。
6. AddIconByEncoding 指令
语法:AddIconByEncoding
icon MIME-encoding [
MIME-encoding ] ...
功能:用一种编码类型与指定的图标关联。
示例:AddIconByEncoding (compressed, /icons/compressed.gif) x-compress
上例说明,用x-compress编码的文件,它前面的图标将会是/icons/compressed.gif。如果这个图标的alt属性将被设置成compressed
7. DefaultIcon 指令
语法:DefaultIcon
url-path
功能:自动索引的目录将在没有匹配任何 AddIcon 指令的图像位置显示 DefaultIcon 。
示例: DefaultIcon /icon/unknown.gif
上例说明,如果有的文件类型没能通过AddIcon类指令匹配到相对应的icon的时候,显示icon的位置将会使用/icon/unknown.gif文件。
8. AddAlt 指令
语法:AddAlt
string file [
file ]
功能:将会对file类型的文件图标增加alt属性,属性值为string
示例:AddAlt Compressed *.zip
上例说明,如果一个文件的扩展名是.zip,那么它的图标的alt属性值将会是Compressed。
9. AddAltByType 指令
语法:AddAltByType
string MIME-type [
MIME-type ] ...
功能:将会对特定MIME类型的文件图标的alt属性指定string值。
示例:AddAltByType 'plain text' text/plain
上例说明,如果文件的MIME类型是text/plain,那么它前面显示的图标alt属性的值将会是plain text。
10. AddAltByEncoding 指令
语法:AddAltByEncoding
string MIME-encoding [
MIME-encoding ] ...
功能:指定特定编码类型的文件前显示图标的alt属性值
示例:AddAltByEncoding gzip x-gzip
上例说明,对应x-gzip编码的文件,前面显示图标的alt属性值将会是gzip。
11. ReadmeName 指令
语法:ReadmeName
filename
功能: 索引底部嵌入文件的文件名
示例:ReadmeName /FOOTER.html
上例说明,在索引目录的下面,将会显示/FOOTER.html文件的内容
12. HeaderName 指令
语法:HeaderName
filename
功能: 索引顶部嵌入文件的文件名
示例:HeaderName /HEADER.html
上例说明,在索引目录的上面,将会显示/FOOTER.html文件的内容
9.1
中提到的相关配置,您可以通过查看srm.conf文件获取。
配置有了,Apache是怎么使这些配置生效的呢?
9.3 配置数据的获取
Apache使用http_dir.c来实现自动索引目录的功能。在这个文件里面定义了两个重要结构:ent和item。其中ent是显示的每个文件(文件夹)的属性,元素如下:
struct ent {
char *name; // 文件(目录)名,如果是上级目录,显示"Parent Directory"
char *icon; // 文件类型相应的图标
char *alt; // 图标alt属性的值
char *desc; // 对文件的描述
size_t size; // 文件大小,如果是目录,显示'-'
time_t lm; // 文件最后修改时间
struct ent *next;
};
从9.2节我们知道,某些条目是否显示可以配置的。可以对照9.1节中的效果图来认识这个结构。
另外一个重要的结构是item,内容如下:
struct item {
int type;
char *apply_to;
char *apply_path;
char *data;
struct item *next;
};
由于这个结构的每个部分在不同的实例链表中含义不同,我们无法整体定义每个属性的含义,具体到每个实例中每个属性的含义,参看下面调试信息的输出内容。
Apache定义了item的几个链表:
- icon_list :由配置文件中AddIcon系列指令定义的内容列表
- alt_list:由配置文件中AddAlt系列指令定义的内容列表
- desc_list:由配置文件中AddDescription指令定义的内容列表(也有可能是HTML文件的title)
- ign_list:由配置文件中IndexIgnore系列指令定义的内容列表
- hdr_list:header文件列表
- rdme_list:readme文件列表
- opts_list:由配置文件中IndexOptions指令定义的内容列表
这些链表在读取配置文件后会相应赋值,它们的值我们可以通过自己设计一个调试函数来显示。我设计的自定义函数的输出类似于:
1.icon_list:
icon_list[0]->type = 0 icon_list[0]->apply_to = *^^BLANKICON^^
icon_list[0]->apply_path = /* icon_list[0]->data = /icons/blank.gif
icon_list[1]->type = 0 icon_list[1]->apply_to = *^^DIRECTORY^^
icon_list[1]->apply_path = /* icon_list[1]->data = /icons/forder.gif
…… ……
icon_list[16]->type = 1 icon_list[16]->apply_to = text/*
icon_list[16]->apply_path = /* icon_list[16]->data = /icons/text.gif
2.alt_list:
alt_list[0]->type = 1 alt_list[0]->apply_to = audio/*
alt_list[0]->apply_path = /* alt_list[0]->data = SND
…… ……
alt_list[2]->type = 1 alt_list[2]->apply_to = text/*
alt_list[2]->apply_path = /* alt_list[2]->data = TXT
3.desc_list:
desc_list[0]->type = 0 desc_list[0]->apply_to = *.zip
desc_list[0]->apply_path = /* desc_list[0]->data = Zip file
4.ign_list:
ign_list[0]->type = 0 ign_list[0]->apply_to = * /README*
ign_list[0]->apply_path = /* ign_list[0]->data = (null)
…… ……
ign_list[4]->type = 0 ign_list[4]->apply_to = * /.??*
ign_list[4]->apply_path = /* ign_list[4]->data = (null)
5.hdr_list:
hdr_list[0]->type = 0 hdr_list[0]->apply_to = (null)
hdr_list[0]->apply_path = /* hdr_list[0]->data = /HEADER.html
6.rdme_list:
rdme_list[0]->type = 0 rdme_list[0]->apply_to = (null)
rdme_list[0]->apply_path = /* rdme_list[0]->data = /FOOTER.html
7.opts_list:
opts_list[0]->type = 61 opts_list[0]->apply_to = (null)
opts_list[0]->apply_path = /* opts_list[0]->data = (null)
…… ……
opts_list[2]->type = 0 opts_list[2]->apply_to = (null)
opts_list[2]->apply_path = /* opts_list[2]->data = (null)
9.4 代码注释
限于篇幅,注释代码部分请参看本书官网。
节选自《Apache源代码解析-基于Apache0.6.5》第九章。