Apache的Mod_rewrite学习(四)

Apache的Mod_rewrite学习(四)

  今天学习重写影射等内容。

RewriteMap
Syntax: RewriteMap MapName MapType:MapSource
  RewriteMap指令定义一个重写影射(Rewriting Map),在规则的substitution串中,通过影射函数(mapping-functions)来查找关键字(key),并用关键字对应的值来进行来行插入或替换操作。这个查找的对象,可以是各种各样的。
  MapName是影射的名字,将用来通过下列的某种结构来为substitution定义影射函数:
${ MapName : LookupKey }
${ MapName : LookupKey | DefaultValue }
当这些结构之一出现substitution串中时,重写引擎会到mapname影射中查找lookupkey关键字,如果找到了就用返回的值(substvalue)来替换该结构,如果找不到就用defaultvalue来替换该结构,如果没有defaultvalue,就用空串来替换。
  MapType 和mapSource组合有以下几种:

  1. 标准的普通文本(Standard Plain Text)
    MapType: txt, MapSource: Unix文件系统中合法的带有路径的regular file名
    此种情况下,MapSource文件是一个普通的ASCII文本文件,可以含有空行、注释行(以#打头),及以下结构的键值对行(每个键值对一行)。
    MatchingKey SubstValue
    例如:Mapsource文件叫/path/to/file/map.txt,其内容为
    ##
    ## map.txt -- rewriting map
    ##
    Ralf.S.Engelschall rse # Bastard Operator From Hell
    Mr.Joe.Average joe # Mr. Average

    在配置文件中则可以这样定义重写映射:
    RewriteMap real-to-user txt:/path/to/file/map.txt

  2. 随机的普通文本(Randomized Plain Text)
    MapType: rnd, MapSource: Unix文件系统中合法的带有路径的regular file名

      这种情况与标准普通文本情况很相似,差别只是在SubstValue的格式上:此时的SubstValue由一些用”|”分隔的值组成的串,这个“|”是“或者”的意思。当根据键值找到对应的SubstValue后,mod_rewrite借助“|”将此串分解为一些候选项,然后随机选择一项作为最终的SubstValue的值返回。这听起来有点疯狂或毫无用处,其实这是设计用来在反向代理(reverse proxy)的情况下做负载均衡,用来查找服务器的名字。
    例如:MapSource文件的名字为/path/to/file/map.txt,内容如下:

    ##
    ## map.txt -- rewriting map
    ##
    static www1|www2|www3|www4
    dynamic www5|www6

    在配置文件中定义的重写影射为:
    RewriteMap servers rnd:/path/to/file/map.txt

  3. Hash File
    MapType: dbm, MapSource: Unix文件系统中合法的带有路径的regular file名

      这儿的Mapsource文件是一个二进制的NDBM格式的文件,含有与普通文本格式文件时相同的内容,为了实现快速查找进行了优化处理后以一种特殊的格式来表达。 可以用任何NDBM工具或者用下面的Perl脚本txt2dbm.pl来创建这种格式的文件:

    #!/path/to/bin/perl
    ##
    ## txt2dbm -- convert txt map to dbm format
    ##

    use NDBM_File;
    use Fcntl;

    ($txtmap, $dbmmap) = @ARGV;

    open(TXT, "<$txtmap") or die "Couldn't open $txtmap!/n";
    tie (%DB, 'NDBM_File', $dbmmap,O_RDWR|O_TRUNC|O_CREAT, 0644) or die "Couldn't create $dbmmap!/n";

    while ( ) {
    next if (/^/s*#/ or /^/s*$/);
    $DB{$1} = $2 if (/^/s*(/S+)/s+(/S+)/);
    }

    untie %DB;
    close(TXT);


    此脚本的使用方法如下:
    $ perl txt2dbm.pl map.txt map.db

  4. Apache内部函数(Internal Function)
    MapType: int, MapSource: Apache内部函数

      这时,MapSource是一个Apache内置函数,目前还不能创建自己的内部函数,只能使用Apache已经定义好的:

    • toupper
      将键值转换为大写
    • tolower
      将键值转换为小写
    • escape
      将键值中的特殊字符转换为以16进制表示。
    • unescape
      将键值中16进制表示的特殊字符转换为原来的样子。

  5. 外部重写程序(External Rewriting Program)
    MapType: prg, MapSource: Unix文件系统中合法的带有路径的regular file名

      这儿的MapSource是一个程序而不是一个影射文件。你可以使用任何语言创建这个程序,但这个程序必须是可执行的(也就是说,要么是二进制码,要么是首行带有”#!/path/to/interpreter”格式的解释器的可执行脚本)。

      这个程序在Apache启动时被运行,然后它就用它的标准输入与标准输出的文件句柄与重写引擎通信(暗指程序能无限时等待标准输入,见下列)。对每个影射函数的查找要求,它把其标准输入中得到的字符串(newline-terminated string?)作为键值,然后通过标准输出返回查找到的值,如果找不到相应的值,则返回以四字符的字符串”NULL“。下面一个简单的例子,实现将键值作为查找结果返回:

    #!/usr/bin/perl
    $| = 1;
    while ( ) {
    # ...put here any transformations or lookups...
    print $_;
    }

    注意:
    1. ``Keep it simple, stupid'' (KISS),因为当规则执行时,一量这个外部程序挂起,整个Apache服务器就挂起了
    2. 避免下述常见错误:缓存了标准输出的I/O。这会导致死循环。这也是为什么上例中有``$|=1''这么一行的原因
    3. 用RewriteLock指令定义一个lockfile,以同步与外部程序的通信。默认情况下并没有这样的同步


  RewriteMap可以出现不只一次。每个影射函数用RewriteMap来声明它的影射文件. While you cannot declare a map in per-directory context it is of course possible to use this map in per-directory context.(?)对普通文本和DBM格式的文件,其键值被缓存在Apache内核中,直到影射文件的mtime 变化了或Apache重启动了。此时,可以将规则中的影射函数用于每个请求。
RewriteBase
Syntax: RewriteBase URL-path
  RewriteBase明确地指出目录范围内的重写结果的baseURL.RewriteRule指令可以用在目录范围内的配置文件里(.htaccess)。在目录范围的重写实施时,由本地路径信息构成的前缀已经被去掉,重写规则只对剩余的部分进行处理。处理结束后,被去掉的路径信息要自动加上,因为当对一个URL进行替换后,重新引擎需要将它重新插入到服务器的处理流程中去。如果服务器端的URL与文件的物理路径有直接有关系,则每当在.htacess文中定义重写规则时都需要用RewriteBase指URL-path。
杂项Environment Variables
  mod_rewrite还维护着两个非标准的CGI/SSI环境变量,名为SCRIPT_URL和 SCRIPT_URI,存放着当前资源的逻辑web视图(logical Web-view)。标准的CGI/SSI变量SCRIPT_NAME 和 SCRIPT_FILENAME中存放着当前资源的物理系统视图(physical System-view)。请看例子:
SCRIPT_NAME=/sw/lib/w3s/tree/global/u/rse/.www/index.html
SCRIPT_FILENAME=/u/rse/.www/index.html
SCRIPT_URL=/u/rse/
SCRIPT_URI=http://en1.engelschall.com/u/rse/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值