您的位置:首页 > 运维架构 > Apache

Apache源代码解析之服务器端包含SSI

2009-05-26 14:26 288 查看
节选自《Apache源代码解析-基于Apache0.6.5》第七章。

网址:http://www.oldapache.org

论坛:http://bbs.oldapache.org

邮箱:tsingien@gmail.com

7.1概述

现在的Apache本身除了提供静态页面服务之外,还可以通过加载第三方扩展模块方式支持php、jsp等脚本语言,提供动态页面效果。您也许不知道,其实即便不使用这些脚本语言,Apache也支持在您的页面里面加入动态内容。

所谓的动态,就是在不同条件下显示不同的内容,比如当前时间的显示就属于动态内容显示。Apache0.6.5对动态内容支持包括两部分,一部分是本章描述的SSI,另一部分是将要在下一章描述的cgi脚本。

SSI全称是Server Side
Include,即服务器端包含。SSI允许在静态文件中显示一些系统变量甚至执行shell命令或cgi脚本。

服务器包含部分的功能在http_include.c中实现。

7.2 背景知识



7.2.1字符实体

如果您做过页面或者对HTML比较熟悉,一定对字符实体这个概念不陌生。

我们在做页面的时候,有时候会遇到这样的情况:我想在某个位置加入几个连续的空格,如果我在源代码里面输入空格,不论输入多少个,在页面显示的时候都是显示一个空格,因为HTML会自动截去多余的空格。不管你加多少空格,都被看做一个空格。

这时候我们一般的做法是用 来代替空格,也许您觉得 不够专业,明眼人一看就知道是空格,那好,我们还有一个替代方
案,使用 来代替空格。在源代码中连续输入几个 序列或 序列,用浏览器打开,是不是显示出几个
空格呢?

这个 或 就是HTML字符实体(HTML
Character Entities)。

一个字符实体分成三部分:第一部分是一个&符号;第二部分是实体(Entity)名字或者是#加上实体(Entity)编号;第三部分是一个分号。

用实体名字的好处是比较好理解,一看 ,大概就猜出是none-break
space的意思,但是其劣势在于并不是所有的浏览器都支持最新的Entity名字。而实体(Entity)编号,各种浏览器都能处理。

注意:Entity是区分大小写的。

最常用的字符实体

显示结果
说明
Entity Name
Entity Number
显示一个空格
 
 
<
小于
<
<
>
大于
>
>
&
&符号
&
&
其他常用的字符实体

更多HTMLver4的字符实体定义参看:http://www.w3.org/TR/html4/sgml/entities.html

7.2.2环境变量

做Java开发的人一定对环境变量这个概念不陌生,相信每个Java程序员在成功输出Hello
World之前都对环境变量进行了一些或艰苦或顺利的设置。

其实每个程序运行的时候都使用了环境变量,只是你没有察觉而已。

我们知道,如果想在Linux下执行一个可执行文件,一般需要给出这个可执行文件的绝对或相对位置,比如我们启动Apache的时候,就需要类似下面这样的方式:

[devel@RIZI src]$ pwd

/home/devel/apache_0.6.5/src

[devel@RIZI src]$ httpd

[devel@RIZI src]$

如果我们在/home/devel/apache_0.6.5/src目录外的任何位置执行下面的指令,是不能启动Apache的:

[devel@RIZI ~]$ pwd

/home/devel

[devel@RIZI ~]$ httpd

-bash: httpd: command not found

[devel@RIZI ~]$

这时因为系统“没找到”httpd这个可执行文件。那么系统都会在哪里“找”呢?答案是系统变量PATH中。

Bash(或任何您当前在使用的shell)根据您输入的命令在PATH系统变量指定的位置找对应的可执行文件,如果找到了,就根据您的输入参数执行这个程序,如果没找到,就会给出“命令没找到”提示。

系统常用命令都在PATH系统变量指定的目录中,这也是我们可以在任何目录执行系统命令如ls的原因。

我们可以通过env命令来查看当前登录用户的系统变量:

[devel@RIZI ~]$ env

SHELL=/bin/bash

HISTSIZE=1000

…… ……

PATH=/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/devel/bin

…… ……

OLDPWD=/home/devel/apache_0.6.5

[devel@RIZI ~]$

而ls命令的位置一般在/bin目录下:

[devel@RIZI ~]$ which ls

/bin/ls

[devel@RIZI ~]$

Apache维护一个自定义的环境变量数据结构供SSI使用。

7.3配置Apache支持SSI

如果您要使用SSI,需要修改两个配置文件:srm.conf和access.conf

7.3.1 配置方法

1.在srm.conf中找到这样的行:

#AddType text/x-server-parsed-html .shtml

如果没有,增加这样一行,并去掉前面的注释(#)。

AddType的含义请参看

2.在access.conf中找到您要使用SSI的目录,如您的站点根目录

<Directory
/home/devel/apache-0.6.5//htdocs>

Options Indexes FollowSymLinks

</Directory>

在Opetion后面增加Includes选项。

7.3.2 配置指令解析

1.AddType
指令

语法:
AddType

MIME-type
extension
[

extension
]
...


功能:

在给定的文件扩展名与特定的内容类型间建立映射

示例:

AddType text/x-server-parsed-html .shtml

上例说明,.shtml为扩展名的文件是text/x-server-parsed-html类型的文件

2.Option
指令

语法:
Options

可选项
[

可选项
] ...


功能:配置在特定目录使用哪些特性

示例:
Options Indexes FollowSymLinks


上例说明,可以在指定的目录下列表文件,可以使用符号链接。具体参数及含义如下:


Indexes:如果服务器收到了一个映射到该目录的URL请求,而目录下又没有DirectoryIndex(如index.html),那么服务器返回一个格式化目录列表。

Includes:允许服务器端包含

IncludesNOEXEC:允许服务器端包含,但禁用#exec命令和#exec CGI

FollowSymLinks:服务器会在此目录中使用符号连接

SymLinksIfOwnerMatch:符号连接仅当与它的目的文件或目录具有相同的用户ID时才使用。简单理解就是符号链接的所有者和它指向的文件或目录是同一个人

execCGI:允许执行CGI脚本

MultiViews:这是一个被诟病的功能。允许你访问页面时不需要文件的扩展名。比如,你有一个叫"uation.txt"的文件,在启用
MultiViews的站点,你可以用"example.com/uation"来访问到这个文件,该指令在我们要讲解的版本中不予支持

None:都不允许

All:除MultiViews之外的所有特性

7.4 SSI命令解说

SSI命令是嵌入在正常的HTML源代码中的。

SSI在使用时遵循以下格式:

 
<!--#directive
parameter="value"-->

其中,directive是向服务器发送的指令名称,parameter是指令的操作对象,而value则是用户希望得到的指令处理结果。

所有的SSI命令都是以"<!--#"开始,其中"<!-"和"#"之间不能有任何空格,否则服务器会把SSI命令当称普通的文件注释处理,
不会显示出任何结果,也不会产生错误提示。此外,SSI命令中的"="两边不能有空格,右边的值必须包含在双引号内,后面可以跟空格,最后是结束标
签"-->"。

Apache0.6.5支持6种类型的SSI命令,如下所示:

Config errmsg, timefmt,
sizefmt

include virtual, file

echo

var

fsize
file

flastmod file

exec

cmd, cgi

下面我们根据实例,一一解说。

7.4.1 config命令

Config命令主要用于修改SSI的默认设置。主要有一个内容设置和两个格式设置:

1.
errmsg

内容设置,设置错误信息的内容,在里面你可以加上自己的邮件地址之类的个人自定义信息。如:

<!--#config errmsg="Error! Please email
webmaster@mydomain.com -->

2.
timefmt

格式设置,可以重新设置SSI输出时间的格式,需要在显示某个时间前面设置,如:

<!--#config timefmt="%A, %B %d,
%Y"-->

<!--#echo var="LAST_MODIFIED"
-->

显示结果为:

Thursday, March 26, 2009

具体的时间格式参看附录。

3.
sizefmt

格式设置,可以定义文件的大小以什么为单位显示。是以字节、千字节还是兆字节为单位表示。如果以字节为单位,参数值为"bytes";对于千字节和兆字节可以使用缩写形式。同样,sizefmt参数必须放在fsize命令的前面才能使用。

<!--#config sizefmt="bytes"
-->

<!--#fsize file="index.html"
-->

7.4.2 include命令

有时候我们在所有的页面里面会引用一些内容,比如会有几个固定链接,如“版权信息 | 关于我们 |
友情链接”等。如果我们在每个页面里面都直接插入这样的信息,一旦有相关信息的变动,如关于我们页面的地址从/include/aboutus.html
改到了/res/aboutus.html,我们就需要修改每个页面。这样的工作是繁杂且容易出错的。这时候我们可以使用include指令来解决这个问
题。这个命令也许是SSI里面最有价值且使用频率最高的命令了

Include命令可以有两个不同的参数:

1.Virtual
:给出到服务器端某个文档的虚拟路径。例如:

 <!--#include virtual="/res/readme.html"
-->

2.File
:给出到当前目录的相对路径,其中不能使用"../",也不能使用绝对路径。例如:

 <!--#include file="readme.html"
-->

 这就要求每一个目录中都包含一个readme.html文件。

7.4.3 echo命令

Echo命令可以显示以下各环境变量:

1.DOCUMENT_NAME

显示当前文档的名称。

<!--#echo var="DOCUMENT_NAME"
-->

显示结果为:hello.shtml

2.DOCUMENT_URL

显示当前文档的虚拟路径。例如:

<!--#echo var="DOCUMENT_URI"
-->

显示结果为:/hello.shtml

3.DATE_LOCAL

显示服务器设定时区的日期和时间。

<!--#echo var="DATE_LOCAL" -->

显示结果为:Thursday, 26-Mar-09 16:59:31 CST

4.DATE_GMT

功能与DATE_LOCAL一样,只不过返回的是以格林尼治标准时间为基准的日期

<!--#echo var="DATE_GMT" -->

显示结果为:Thursday, 26-Mar-09 08:59:31 GMT

5.LAST_MODIFIED

显示当前文档的最后更新时间。

<!--#echo var="LAST_MODIFIED"
-->

显示结果为:Thursday, 26-Mar-09 16:57:27 CST

6.CGI环境变量

PATH:服务器PATH信息

SERVER_SOFTWARE:服务器软件版本信息

SERVER_NAME:服务器名

SERVER_PORT:服务端口号

REMOTE_HOST:客户端名称

REMOTE_ADDR:客户端地址

DOCUMENT_ROOT:站点根目录

SERVER_ADMIN:站点管理员邮件地址

REMOTE_USER:远程用户

AUTH_TYPE:认证类型

REDIRECT_QUERY_STRING:重定向参数信息

REDIRECT_URL:重定向URL

最后两项和重定向有关,REMOTE_USER和AUTH_TYPE跟认证有关。这四项只有在特定情况下才能有值。

7.4.4 fsize命令

显示指定文件的大小。如:

<!--#fsize file="hello.zip"
-->

输出为:1K

可以结合config命令的sizefmt参数定制输出格式,如:

<!--#config sizefmt="bytes"
-->

<!--#fsize file="hello.zip"
-->

输出为:2

说明这个文件只有2字节。

7.4.5 flastmod命令

显示指定文件的最后修改日期。

<!--#flastmod file="hello.zip"
-->

输出为:Friday, 20-Mar-09 16:33:12 CST

7.4.6 exec命令

exec命令可以执行CGI脚本或者shell命令。使用方法如下:

  cmd:使用/bin/sh执行指定的字串。如果服务器配置Option时使用了IncludesNOEXEC选项,则该命令将被屏蔽。

 
cgi:可以用来执行CGI脚本。例如,下面这个例子中使用服务端cgi-bin目录下的date脚本程序显示当前时间:

  <!--#exec cgi="/cgi-bin/date"
-->

7.4.7 一个简单的实例

本小节我们提供一个简单的,使用SSI功能的HTML页面,来检测Apache对SSI的支持。该HTML文件的源代码如下:

<html
xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type"
content="text/html; charset=UTF-8" />

<title>SSI测试</title>

</head>

<body>

<!--#config timefmt="%A, %B %d, %Y"
-->

当前本地时间是:<!--#echo var="DATE_LOCAL"
-->

<br/>

本文件大小是:<!--#fsize file="ssi.shtml"
-->

</body>

</html>

您可以在http://www.oldapache.org/example/chapter7/ssi.rar
下载该代码。下载后解压缩,将解压缩后得到的ssi.shtml文件放到您的htdocs目录,按照7.3节中的说明配置Apache,重新启动Apache使新配置生效。从浏览器中访问页面http://www.yourdomain.com/ssi.shtml
,在我的浏览器中得到的结果如下图所示:





7.5

代码注释

限于篇幅,注释代码部分请参看本书官网。

节选自《Apache源代码解析-基于Apache0.6.5》第七章。

网址:http://www.oldapache.org

论坛:http://bbs.oldapache.org

邮箱:tsingien@gmail.com
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: