<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Terry.Li-彬

    虛其心,可解天下之問;專其心,可治天下之學(xué);靜其心,可悟天下之理;恒其心,可成天下之業(yè)。

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      143 隨筆 :: 344 文章 :: 130 評論 :: 0 Trackbacks

    Apache模塊 mod_rewrite

    說明 一個(gè)基于一定規(guī)則的實(shí)時(shí)重寫URL請求的引擎
    狀態(tài) 擴(kuò)展(E)
    模塊名 rewrite_module
    源文件 mod_rewrite.c
    兼容性 僅在 Apache 1.3 及以后的版本中可用

    概述

    此模塊提供了一個(gè)基于正則表達(dá)式分析器的重寫引擎來實(shí)時(shí)重寫URL請求。它支持每個(gè)完整規(guī)則可以擁有不限數(shù)量的子規(guī)則以及附加條件規(guī)則 的靈活而且強(qiáng)大的URL操作機(jī)制。此URL操作可以依賴于各種測試,比如服務(wù)器變量、環(huán)境變量、HTTP頭、時(shí)間標(biāo)記,甚至各種格式的用于匹配URL組成 部分的查找數(shù)據(jù)庫。

    此模塊可以操作URL的所有部分(包括路徑信息部分),在服務(wù)器級的(httpd.conf)和目錄級的(.htaccess)配置都有效,還可以生成最終請求字符串。此重寫操作的結(jié)果可以是內(nèi)部子處理,也可以是外部請求的轉(zhuǎn)向,甚至還可以是內(nèi)部代理處理。

    但是,所有這些功能和靈活性帶來一個(gè)問題,那就是復(fù)雜性,因此,不要指望一天之內(nèi)就能看懂整個(gè)模塊。

    更多的討論、細(xì)節(jié)、示例,請查看詳細(xì)的URL重寫文檔

    特殊字符的引用

    在Apache 1.3.20中,TestStringSubstitution中的特殊字符可以用前導(dǎo)斜杠(\)來實(shí)現(xiàn)轉(zhuǎn)義(即忽略其特殊含義而視之為普通字符)。 比如,Substitution可以用"\$"來包含一個(gè)美元符號,以避免mod_rewrite把它視為反向引用。

    環(huán)境變量

    此模塊會跟蹤兩個(gè)額外的(非標(biāo)準(zhǔn))CGI/SSI環(huán)境變量,SCRIPT_URLSCRIPT_URI。他們包含了當(dāng)前資源的邏輯網(wǎng)絡(luò)視圖,而標(biāo)準(zhǔn)CGI/SSI變量SCRIPT_NAMESCRIPT_FILENAME包含的是物理系統(tǒng)視圖。

    注意:這些變量保持的是其最初被請求時(shí)的URI/URL,即在任何重寫操作之前的URI/URL。其重要性在于他們是重寫操作重寫URL到物理路徑名的原始依據(jù)。

    示例

    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/

    實(shí)用方案

    我們提供了URL重寫指南高級URL重寫指南文檔,列舉了許多基于URL的問題的實(shí)用方案,其中你可以找到真實(shí)有用的規(guī)則集。

    RewriteBase 指令

    說明 設(shè)置目錄級重寫的基準(zhǔn)URL
    語法 RewriteBase URL-path
    默認(rèn)值 參見使用方法
    作用域 directory, .htaccess
    覆蓋項(xiàng) FileInfo
    狀態(tài) 擴(kuò)展(E)
    模塊 mod_rewrite

    RewriteBase指令顯式地設(shè)置了目錄級重寫的基準(zhǔn)URL。在下文中,你將看到RewriteBasephysical-directory-path"。

    在對一個(gè)新的URL進(jìn)行替換時(shí),此模塊必須把這個(gè)URL重新注入到服務(wù)器處理中。為此,它必須知道其對應(yīng)的URL前綴或者說URL基準(zhǔn)。通常,此前綴就是對應(yīng)的文件路徑。但是,大多數(shù)網(wǎng)站URL不是直接對應(yīng)于其物理文件路徑的,因而一般不能做這樣的假定! 所以在這種情況下,就必須用RewriteBase指令來指定正確的URL前綴。

    例如,目錄級配置文件內(nèi)容如下:

    # /abc/def/.htaccess -- /abc/def 目錄的配置文件
    # 注意:/abc/def 是 /xyz 的物理路徑(例如存在一條'Alias /xyz /abc/def'指令)。

    RewriteEngine On

    # 讓服務(wù)器知道我們使用的是 /xyz 而不是物理路徑 /abc/def
    RewriteBase /xyz

    # 重寫規(guī)則
    RewriteRule ^oldstuff\.html$ newstuff.html

    上述例子中,對/xyz/oldstuff.html的請求被正確地重寫為對物理文件/abc/def/newstuff.html的請求。

    僅供Apache Hacker們參考

    以下列出了內(nèi)部處理的詳細(xì)步驟:

    請求:
    /xyz/oldstuff.html

    內(nèi)部處理過程:
    /xyz/oldstuff.html -> /abc/def/oldstuff.html (per-server Alias)
    /abc/def/oldstuff.html -> /abc/def/newstuff.html (per-dir RewriteRule)
    /abc/def/newstuff.html -> /xyz/newstuff.html (per-dir RewriteBase)
    /xyz/newstuff.html -> /abc/def/newstuff.html (per-server Alias)

    結(jié)果:
    /abc/def/newstuff.html

    雖然這個(gè)過程看來很繁復(fù),但是由于目錄級重寫的到來時(shí)機(jī)已經(jīng)太晚了,它不得不把這個(gè)(重寫)請求重新注入到 Apache核心中,所以Apache內(nèi)部確實(shí)是這樣處理的。但是:它的開銷并不象看起來的那樣大,因?yàn)橹匦伦⑷胪耆贏pache服務(wù)器內(nèi)部進(jìn)行,而且 這樣的過程在Apache內(nèi)部也為其他許多操作所使用。所以,你可以充分信任其設(shè)計(jì)和實(shí)現(xiàn)是正確的。

    RewriteCond 指令

    說明 定義重寫發(fā)生的條件
    語法 RewriteCond TestStringCondPattern [flags]
    作用域 server config, virtual host, directory, .htaccess
    覆蓋項(xiàng) FileInfo
    狀態(tài) 擴(kuò)展(E)
    模塊 mod_rewrite

    RewriteCond指令定義了規(guī)則生效的條件,即在一個(gè)RewriteRule指令之前可以有一個(gè)或多個(gè)RewriteCond指令。條件之后的重寫規(guī)則僅在當(dāng)前URI與Pattern匹配并且滿足此處的條件(TestString能夠與CondPattern匹配)時(shí)才會起作用。

    TestString是一個(gè)純文本的字符串,但是還可以包含下列可擴(kuò)展的成分:

    • RewriteRule反向引用 ,引用方法是:

      $N

      (0 <= N <= 9)引用當(dāng)前(帶有若干RewriteRule指令的)RewriteCond中的與Pattern匹配的分組成分(圓括號!)。
    • RewriteCond反向引用 ,引用方法是:

      %N

      (1 <= N <= 9)引用當(dāng)前若干RewriteCond條件中最后符合的條件中的分組成分(圓括號!)。
    • RewriteMap擴(kuò)展 ,引用方法是:

      ${mapname:key|default}

      細(xì)節(jié)請參見RewriteMap 指令
    • 服務(wù)器變量 ,引用方法是:

      %{NAME_OF_VARIABLE}

      NAME_OF_VARIABLE可以是下表列出的字符串之一:
      HTTP頭連接與請求
      HTTP_USER_AGENT
      HTTP_REFERER
      HTTP_COOKIE
      HTTP_FORWARDED
      HTTP_HOST
      HTTP_PROXY_CONNECTION
      HTTP_ACCEPT
      REMOTE_ADDR
      REMOTE_HOST
      REMOTE_PORT
      REMOTE_USER
      REMOTE_IDENT
      REQUEST_METHOD
      SCRIPT_FILENAME
      PATH_INFO
      QUERY_STRING
      AUTH_TYPE

      服務(wù)器自身日期和時(shí)間其它
      DOCUMENT_ROOT
      SERVER_ADMIN
      SERVER_NAME
      SERVER_ADDR
      SERVER_PORT
      SERVER_PROTOCOL
      SERVER_SOFTWARE
      TIME_YEAR
      TIME_MON
      TIME_DAY
      TIME_HOUR
      TIME_MIN
      TIME_SEC
      TIME_WDAY
      TIME
      API_VERSION
      THE_REQUEST
      REQUEST_URI
      REQUEST_FILENAME
      IS_SUBREQ
      HTTPS

      這些變量都對應(yīng)于類似命名的HTTP MIME頭、Apache服務(wù)器的C變量、Unix系統(tǒng)中的struct tm字段,其中的大多數(shù)在其他的手冊或者CGI規(guī)范中都有說明。 其中為mod_rewrite所特有的變量如下:

      IS_SUBREQ
      如果正在處理的請求是一個(gè)子請求,它將包含字符串"true",否則就是"false"。模塊為了解析URI中的附加文件,可能會產(chǎn)生子請求。
      API_VERSION
      這是正在使用中的Apache模塊API(服務(wù)器和模塊之間內(nèi)部接口)的版本, 其定義位于include/ap_mmn.h中。此模塊API版本對應(yīng)于正在使用的Apache的版本(比如在Apache 1.3.14的發(fā)行版中這個(gè)值是19990320:10)。 通常,對它感興趣的是模塊的開發(fā)者。
      THE_REQUEST
      這是由瀏覽器發(fā)送的完整的HTTP請求行(比如:"GET /index.html HTTP/1.1")。它不包含任何瀏覽器發(fā)送的其它頭信息。
      REQUEST_URI
      這是在HTTP請求行中所請求的資源(比如上述例子中的"/index.html")。
      REQUEST_FILENAME
      這是與請求相匹配的完整的本地文件系統(tǒng)的文件路徑名。
      HTTPS
      如果連接使用了SSL/TLS,它將包含字符串"on",否則就是"off"(無論mod_ssl是否已經(jīng)加載,該變量都可以安全的使用)。

    其它注意事項(xiàng):

    1. SCRIPT_FILENAME和REQUEST_FILENAME包含的值是相同的——即Apache服務(wù)器內(nèi)部的request_rec結(jié)構(gòu)中的filename字段。 第一個(gè)就是大家都知道的CGI變量名,而第二個(gè)則是REQUEST_URI(request_rec結(jié)構(gòu)中的uri字段)的一個(gè)副本。
    2. 特殊形式:%{ENV:variable} ,其中的variable可以是任意環(huán)境變量。它是通過查找Apache內(nèi)部結(jié)構(gòu)或者(如果沒找到的話)由Apache服務(wù)器進(jìn)程通過getenv()得到的。
    3. 特殊形式:%{SSL:variable} ,其中的variable可以是一個(gè)SSL環(huán)境變量的名字,無論mod_ssl模塊是否已經(jīng)加載都可以使用(未加載時(shí)為空字符串)。比如:%{SSL:SSL_CIPHER_USEKEYSIZE}將會被替換為128
    4. 特殊形式:%{HTTP:header} ,其中的header可以是任意HTTP MIME頭的名稱。它總是可以通過查找HTTP請求而得到。比如:%{HTTP:Proxy-Connection}將被替換為Proxy-Connection:HTTP頭的值。
    5. 預(yù)設(shè)形式:%{LA-U:variable}variable的最終值在執(zhí)行一個(gè)內(nèi)部(基于URL的)子請求后確定。 當(dāng)需要使用一個(gè)目前未知但是會在之后的過程中設(shè)置的變量的時(shí)候,就可以使用這個(gè)方法。

      例如,需要在服務(wù)器級配置(httpd.conf文件)中根據(jù)REMOTE_USER變量進(jìn)行重寫, 就必須使用%{LA-U:REMOTE_USER}。因?yàn)榇俗兞渴怯蒛RL重寫(mod_rewrite)步驟之后的認(rèn)證步驟設(shè)置的。 但是另一方面,因?yàn)閙od_rewrite是通過API修正步驟來實(shí)現(xiàn)目錄級(.htaccess文件)配置的, 而認(rèn)證步驟先于API修正步驟,所以可以用%{REMOTE_USER}

    6. 預(yù)設(shè)形式:%{LA-F:variable}variable的最終值在執(zhí)行一個(gè)內(nèi)部(基于文件名的)子請求后確定。 大多數(shù)情況下和上述的LA-U是相同的。

    CondPattern是條件模式,即一個(gè)應(yīng)用于當(dāng)前TestString實(shí)例的正則表達(dá)式。TestString將被首先計(jì)算,然后再與CondPattern匹配。

    注意: CondPattern是一個(gè)perl兼容的正則表達(dá)式,但是還有若干增補(bǔ):

    1. 可以在CondPattern串的開頭使用'!'(驚嘆號)來指定不匹配
    2. CondPatterns有若干特殊的變種。除了正則表達(dá)式的標(biāo)準(zhǔn)用法,還有下列用法:
      • '<CondPattern'(詞典順序的小于)
        CondPattern視為純字符串,與TestString按詞典順序進(jìn)行比較。如果TestString小于CondPattern則為真。
      • '>CondPattern'(詞典順序的大于)
        CondPattern視為純字符串,與TestString按詞典順序進(jìn)行比較。如果TestString大于CondPattern則為真。
      • '=CondPattern'(詞典順序的等于)
        CondPattern視為純字符串,與TestString按詞典順序進(jìn)行比較。如果TestString等于CondPattern(兩個(gè)字符串逐個(gè)字符地完全相等)則為真。如果CondPattern""(兩個(gè)雙引號),則TestString將與空字符串進(jìn)行比較。
      • '-d'(目錄)
        TestString視為一個(gè)路徑名并測試它是否為一個(gè)存在的目錄。
      • '-f'(常規(guī)文件)
        TestString視為一個(gè)路徑名并測試它是否為一個(gè)存在的常規(guī)文件。
      • '-s'(非空的常規(guī)文件)
        TestString視為一個(gè)路徑名并測試它是否為一個(gè)存在的、尺寸大于0的常規(guī)文件。
      • '-l'(符號連接)
        TestString視為一個(gè)路徑名并測試它是否為一個(gè)存在的符號連接。
      • '-x'(可執(zhí)行)
        TestString視為一個(gè)路徑名并測試它是否為一個(gè)存在的、具有可執(zhí)行權(quán)限的文件。該權(quán)限由操作系統(tǒng)檢測。
      • '-F'(對子請求存在的文件)
        檢查TestString是否為一個(gè)有效的文件,而且可以在服務(wù)器當(dāng)前的訪問控制配置下被訪問。它使用一個(gè)內(nèi)部子請求來做檢查,由于會降低服務(wù)器的性能,所以請謹(jǐn)慎使用!
      • '-U'(對子請求存在的URL)
        檢查TestString是否為一個(gè)有效的URL,而且可以在服務(wù)器當(dāng)前的訪問控制配置下被訪問。它使用一個(gè)內(nèi)部子請求來做檢查,由于會降低服務(wù)器的性能,所以請謹(jǐn)慎使用!

      注意

      所有這些測試都可以用驚嘆號作前綴('!')以實(shí)現(xiàn)測試條件的反轉(zhuǎn)。
    3. 還可以在CondPattern之后追加特殊的標(biāo)記[flags]作為RewriteCond指令的第三個(gè)參數(shù)。flags是一個(gè)以逗號分隔的以下標(biāo)記的列表:
      • 'nocase|NC'(忽略大小寫)
        它使測試忽略大小寫,擴(kuò)展后的TestStringCondPattern中'A-Z' 和'a-z'是沒有區(qū)別的。此標(biāo)記僅用于TestStringCondPattern的比較,而對文件系統(tǒng)和子請求的檢查不起作用。
      • 'ornext|OR'(或下一條件)
        它以O(shè)R方式組合若干規(guī)則的條件,而不是隱含的AND。典型的例子如下:
        RewriteCond %{REMOTE_HOST}  ^host1.*  [OR]
        RewriteCond %{REMOTE_HOST} ^host2.* [OR]
        RewriteCond %{REMOTE_HOST} ^host3.*
        RewriteRule ... 針對這3個(gè)主機(jī)的規(guī)則集 ...
        如果不用這個(gè)標(biāo)記,你就必須要書寫三次條件/規(guī)則對。

    舉例

    如果要按請求頭中的"User-Agent:"重寫一個(gè)站點(diǎn)的主頁,可以這樣寫:

    RewriteCond  %{HTTP_USER_AGENT}  ^Mozilla.*
    RewriteRule ^/$ /homepage.max.html [L]

    RewriteCond %{HTTP_USER_AGENT} ^Lynx.*
    RewriteRule ^/$ /homepage.min.html [L]

    RewriteRule ^/$ /homepage.std.html [L]

    解釋:如果你使用的瀏覽器識別標(biāo)志是'Mozilla',則你將得到內(nèi)容最大化的主頁(含有Frames等等)。如果你使用的是 (基于終端的)Lynx,則你得到的是內(nèi)容最小化的主頁(不含table等等)。如果上述條件都不滿足(使用的是其他瀏覽器),則你得到的是一個(gè)標(biāo)準(zhǔn)的主 頁。

    RewriteEngine 指令

    說明 打開或關(guān)閉運(yùn)行時(shí)的重寫引擎
    語法 RewriteEngine on|off
    默認(rèn)值 RewriteEngine off
    作用域 server config, virtual host, directory, .htaccess
    覆蓋項(xiàng) FileInfo
    狀態(tài) 擴(kuò)展(E)
    模塊 mod_rewrite

    RewriteEngine指令打開或關(guān)閉運(yùn)行時(shí)的重寫引擎。如果設(shè)置為off,則此模塊在運(yùn)行時(shí)不執(zhí)行任何重寫操作, 同時(shí)也不更新SCRIPT_URx環(huán)境變量。

    使用該指令可以使此模塊無效,而無須注釋所有的RewriteRule指令!

    注意:默認(rèn)情況下,重寫配置是不可繼承的,也就是必須在每個(gè)需要使用重寫引擎的虛擬主機(jī)中設(shè)置一個(gè)RewriteEngine on指令。

    RewriteLock 指令

    說明 設(shè)置RewriteMap同步所使用的鎖文件名
    語法 RewriteLock file-path
    作用域 server config
    狀態(tài) 擴(kuò)展(E)
    模塊 mod_rewrite

    此指令設(shè)置mod_rewrite為了和RewriteMap程序通訊而使用的同步鎖文件的名稱。 在需要使用重寫映射表程序(rewriting map-program)時(shí),它必須是一個(gè)本地路徑(而不能是一個(gè)NFS掛接設(shè)備)。對其他類型的重寫映射表(rewriting map),則無此要求。

    RewriteLog 指令

    說明 設(shè)置重寫引擎日志的文件名
    語法 RewriteLog file-path
    作用域 server config, virtual host
    狀態(tài) 擴(kuò)展(E)
    模塊 mod_rewrite

    RewriteLog指令設(shè)置用于記錄所有重寫操作的日志文件的名稱。如果此文件名不以斜杠('/')開頭,則它是相對于Server Root的,此指令應(yīng)該在每個(gè)服務(wù)器級別的配置中僅僅出現(xiàn)一次。

    如果要關(guān)閉對重寫操作的記錄,不推薦將Filename設(shè)為/dev/null ,因?yàn)椋m然重寫引擎不能輸出記錄了,但仍會在內(nèi)部建立這個(gè)日志文件,這樣會使服務(wù)器速度降低,而且對管理員毫無益處!要關(guān)閉日志,可以刪除或注解RewriteLog指令, 或者使用"RewriteLogLevel 0"的設(shè)置

    安全

    參見安全方面的提示文檔,其中講述了為什么如果存放日志的目錄對除了啟動服務(wù)器以外的用戶是可寫的會帶來安全隱患。

    示例

    RewriteLog "/usr/local/var/apache/logs/rewrite.log"

    RewriteLogLevel 指令

    說明 設(shè)置重寫日志的詳細(xì)程度
    語法 RewriteLogLevel Level
    默認(rèn)值 RewriteLogLevel 0
    作用域 server config, virtual host
    狀態(tài) 擴(kuò)展(E)
    模塊 mod_rewrite

    RewriteLogLevel指令設(shè)置重寫引擎日志的詳細(xì)程度的級別。0(默認(rèn)級別)意味著不記錄,而9或更大的值意味著記錄所有操作。

    要關(guān)閉重寫引擎日志,可以簡單地將Level設(shè)為0,以關(guān)閉所有重寫操作的記錄。

    較高的Level值會使Apache服務(wù)器速度急劇下降!大于2的Level值只用于調(diào)試目的!

    示例

    RewriteLogLevel 3

    RewriteMap 指令

    說明 定義用于關(guān)鍵詞查找的映射函數(shù)
    語法 RewriteMap MapNameMapType:MapSource
    作用域 server config, virtual host
    狀態(tài) 擴(kuò)展(E)
    模塊 mod_rewrite
    兼容性 Apache 2.0.41 及以后的版本中可以使用不同的dbm類型

    RewriteMap指令定義了一個(gè)映射表(Rewriting Map),映射函數(shù)將使用該表來查找關(guān)鍵字然后插入/替換字段。此查找操作的源可以是多種類型。

    MapName 是映射表的名稱,指定了一個(gè)映射函數(shù),用于重寫規(guī)則的字符串替換,它可以是下列形式之一:

    ${ MapName : LookupKey }
    ${ MapName : LookupKey | DefaultValue }

    如果使用了這樣的形式,則會在MapName中查找關(guān)鍵詞LookupKey。如果找到了,則被替換成SubstValue; 如果沒有找到,則被替換成DefaultValue,如果沒有指定DefaultValue,則被替換成空字符串。

    例如,你可能定義這樣一個(gè)RewriteMap

    RewriteMap examplemap txt:/path/to/file/map.txt

    然后你就可以像下面這樣在RewriteRule中使用該映射:

    RewriteRule ^/ex/(.*) ${examplemap:$1}

    可以使用下列MapTypeMapSource的組合:

    • 標(biāo)準(zhǔn)純文本
      MapType: txt, MapSource: 有效的Unix文件系統(tǒng)文件名

      這是重寫映射表的標(biāo)準(zhǔn)形式。MapSource是一個(gè)純文本文件,包含空行、注釋行(以字符'#'打頭),以及每行一個(gè)的替換對,如下所示:

      MatchingKeySubstValue

      例子

      ##  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

    • 隨機(jī)純文本
      MapType: rnd, MapSource: 有效的Unix文件系統(tǒng)文件名

      這個(gè)與上述的標(biāo)準(zhǔn)純文本很相似,但它有一個(gè)特殊的后處理特性:查找完畢后,會解析其中包含的"|"符號(含義為"或")。 也就是說,會隨機(jī)地選擇其中之一作為返回值。雖然這看似毫無意義,但設(shè)計(jì)它的意圖是在一個(gè)查找值是服務(wù)器名稱的反向代理環(huán)境中實(shí)現(xiàn)負(fù)載平衡。

      例子

      映射文件

      ##  map.txt -- rewriting map

      static www1|www2|www3|www4
      dynamic www5|www6

      配置指令

      RewriteMap servers rnd:/path/to/file/map.txt

      RewriteRule ^/(.*\.(png|gif|jpg)) http://${servers:static}/$1 [NC,P,L]
      RewriteRule ^/(.*) http://${servers:dynamic}/$1 [P,L]

    • 散列文件
      MapType: dbm[=type], MapSource: 有效的Unix文件系統(tǒng)文件名

      這里的源是一個(gè)二進(jìn)制格式的DBM文件,包含了與純文本相同的內(nèi)容,但是因?yàn)樗袃?yōu)化了的特殊表現(xiàn)形式,使它的查找速度明顯快得多。 此type可以是sdbm, gdbm, ndbm, db(由編譯時(shí)配置決定)。如果省略type,則使用編譯時(shí)選擇的缺省值。 你可以使用任何DBM工具或者下列Perl腳本來創(chuàng)建這個(gè)文件,但必須保證DBM的類型正確。建立NDBM文件的例子如下:

      #!/path/to/bin/perl
      ##
      ## txt2dbm -- 將 txt 映射表轉(zhuǎn)換為 dbm 格式
      ##

      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 (<TXT>) {
      next if (/^\s*#/ or /^\s*$/);
      $DB{$1} = $2 if (/^\s*(\S+)\s+(\S+)/);
      }

      untie %DB;
      close(TXT);

      $ txt2dbm map.txt map.db

    • 內(nèi)部函數(shù)
      MapType: int, MapSource: Apache內(nèi)部函數(shù)

      這里的源是一個(gè)Apache的內(nèi)部函數(shù)。目前,還不能由你自己建立,只能使用下列已經(jīng)存在的函數(shù):

      • toupper:
        轉(zhuǎn)換查找關(guān)鍵詞為大寫
      • tolower:
        轉(zhuǎn)換查找關(guān)鍵詞為小寫
      • escape:
        轉(zhuǎn)換查找關(guān)鍵詞中的特殊字符為十六進(jìn)制編碼
      • unescape:
        轉(zhuǎn)換查找關(guān)鍵詞中的十六進(jìn)制編碼為特殊字符
    • 外部的重寫程序
      MapType: prg, MapSource: 有效的Unix文件系統(tǒng)文件名

      這里的源是一個(gè)程序,而不是一個(gè)映射表文件。程序設(shè)計(jì)語言可以隨意選擇,但最終結(jié)果必須是可執(zhí)行的(或者是目標(biāo)代碼,或者是首行為'#!/path/to/interpreter'的腳本)。

      此程序僅在Apache服務(wù)器啟動時(shí)啟動一次,隨后通過stdinstdout文件句柄與重寫引擎交互。 對每個(gè)映射函數(shù)的查找操作,它從stdin接收以回車結(jié)束的查找關(guān)鍵詞,然后把查找的結(jié)果以回車結(jié)束反饋到stdout,如果查找失敗,則返回四個(gè)字符的字符串"NULL"(對給定的關(guān)鍵詞沒有對應(yīng)的值)。此程序的最簡單形式是一個(gè)1:1的映射(即:key == value),例如:

      #!/usr/bin/perl
      $| = 1;
      while (<STDIN>) {
      # ...在這里放置轉(zhuǎn)換和查找...
      print $_;
      }

      但是必須注意:

      1. "簡單就是美"(KISS: Keep it simple, stupid!)。此程序的崩潰會直接導(dǎo)致Apache服務(wù)器的崩潰。
      2. 絕不要對stdout做I/O緩沖(一個(gè)常見的錯(cuò)誤),它會導(dǎo)致死循環(huán)!所以上述例子中才會使用"$|=1"來預(yù)防。
      3. 使用RewriteLock指令定義一個(gè)鎖文件,用于同步mod_rewrite和此程序之間的通訊。默認(rèn)是沒有同步操作的。

    RewriteMap指令可以多次出現(xiàn)。對每個(gè)映射函數(shù)都可以使用一個(gè)RewriteMap指令來定義其重寫映射表。雖然不能在目錄上下文(per-directory context)中定義映射表,但是完全可以在其中使用映射表。

    注意

    對于純文本和DBM格式的文件,已經(jīng)查找過的關(guān)鍵詞會被緩存在內(nèi)核中,直到映射表的mtime改變了或者服務(wù)器重啟了。這樣,你可以把每個(gè)請求都會用到的映射函數(shù)放在規(guī)則中,這是沒有問題的,因?yàn)橥獠坎檎抑贿M(jìn)行一次。

    RewriteOptions 指令

    說明 為重寫引擎設(shè)置一些特殊的選項(xiàng)
    語法 RewriteOptions Options
    作用域 server config, virtual host, directory, .htaccess
    覆蓋項(xiàng) FileInfo
    狀態(tài) 擴(kuò)展(E)
    模塊 mod_rewrite
    兼容性 MaxRedirects在2.1及以后的版本中已經(jīng)不可用

    RewriteOptions指令為當(dāng)前服務(wù)器級和目錄級的配置設(shè)置一些選項(xiàng)。Option當(dāng)前僅可以是如下值:

    inherit
    此值強(qiáng)制當(dāng)前配置繼承其父配置。在虛擬主機(jī)級配置中,它意味著主服務(wù)器的映射表、條件和規(guī)則可以被繼承。在目錄級配置中,它意味著其父目錄的.htaccess中的條件和規(guī)則可以被繼承。

    RewriteRule 指令

    說明 為重寫引擎定義重寫規(guī)則
    語法 RewriteRule PatternSubstitution [flags]
    作用域 server config, virtual host, directory, .htaccess
    覆蓋項(xiàng) FileInfo
    狀態(tài) 擴(kuò)展(E)
    模塊 mod_rewrite
    兼容性 cookie-flag在Apache 2.0.40及以后的版本中可用

    RewriteRule指令是重寫引擎的根本。此指令可以多次使用。每個(gè)指令定義一個(gè)簡單的重寫規(guī)則。這些規(guī)則的定義順序尤為重要——在運(yùn)行時(shí),規(guī)則是按這個(gè)順序逐一生效的。

    Pattern 是一個(gè)作用于當(dāng)前URL的perl兼容的正則表達(dá)式。"當(dāng)前URL"是指該規(guī)則生效時(shí)刻的URL的值。它可能與被請求的URL截然不同,因?yàn)槠渌?guī)則可能在此之前已經(jīng)發(fā)生匹配并對它做了改動。

    正則表達(dá)式的一些用法示例:

    										文本
    										
    . 任意一個(gè)單字符
    [chars] 字符類: "chars"中的任意一個(gè)字符
    [^chars] 字符類: 不在"chars"中的字符
    text1|text2 選擇: text1 或 text2

    量詞
    ? 前面的字符出現(xiàn) 0 或 1 次
    * 前面的字符出現(xiàn) 0 或 N 次(N > 0)
    + 前面的字符出現(xiàn) 1 或 N 次(N > 1)

    分組
    (text) text 組
    (常用于設(shè)置一個(gè)選擇的邊界,或用于生成后引用:
    在RewriteRule中可以用 $N 引用第N個(gè)分組)


    ^ 錨定到行首
    $ 錨定到行尾

    轉(zhuǎn)義
    \c 對給定的字符c進(jìn)行轉(zhuǎn)義
    (比如對".[]()"進(jìn)行轉(zhuǎn)義,等等)

    更多有關(guān)正則表達(dá)式的資料請參見perl正則表達(dá)式手冊頁("perldoc perlre")。另外,在mod_rewrite中,還可以使用否字符('!')前綴實(shí)現(xiàn)反轉(zhuǎn)。比如:"如果當(dāng)前URL與模式相匹配"它用于使用否定式匹配模式較容易描述的某些情況,或者作為最后一條規(guī)則。

    注意

    使用否字符以反轉(zhuǎn)匹配模式時(shí),匹配模式中不能使用分組的通配成分。由于模式不匹配而使分組的內(nèi)容是空的,所以它是不可能實(shí)現(xiàn)的。 因此,如果使用了否定式匹配模式,那么后繼的字符串中就不能使用$N

    重寫規(guī)則中的Substitution是當(dāng)原始URL與Pattern相匹配時(shí),用來替代(或替換)的字符串。除了純文本,還可以包含:

    1. Pattern的反向引用($N)
    2. 對最后匹配的RewriteCond的反向引用(%N)
    3. 規(guī)則條件測試字符串(%{VARNAME})中的服務(wù)器變量
    4. 映射函數(shù)調(diào)用(${mapname:key|default})

    反向引用的$N(N=0..9)是指用Pattern匹配的第N組的內(nèi)容去替換URL。服務(wù)器變量與RewriteCond指令的TestString相同。映射函數(shù)由RewriteMap指令決定,其說明也參見該指令。這三種類型變量按上面列表中的順序被展開。

    如上所述,所有的重寫規(guī)則都是按配置文件中的定義順序作用于Substitution的。URL被Substitution完全替換,并繼續(xù)處理直到所有規(guī)則處理完畢,除非用L標(biāo)記顯式地終結(jié)(見下文)。

    '-'是一個(gè)特殊的替換串,意思是不替換。它可以用于僅僅匹配某些URL而無須替換的情況,比如,在發(fā)生替換前,允許以C(chain)標(biāo)記連接的多個(gè)匹配模式同時(shí)起作用。

    此外,在Substitution之后還可以追加[flags]標(biāo)記作為RewriteRule指令的第三個(gè)參數(shù)。Flags是一個(gè)包含以逗號分隔的下列標(biāo)記的列表:

    注意:絕對URL的替換

    當(dāng)替換字段以"http://thishost[:thisport]"作為前綴時(shí),mod_rewrite會將它自動剝離出去。在配合生成主機(jī)名部分的映射函數(shù)使用的時(shí)候,這個(gè)對隱含的外部重定向URL的簡化操作是有用的而且是重要的。下面的第一個(gè)例子有助于理解這點(diǎn)。

    謹(jǐn)記:由于此功能的存在,以"http://thishost"為前綴的無條件外部重定向到自身所在的服務(wù)器是無效的。要實(shí)現(xiàn)一個(gè)到自身的重定向,必須使用R標(biāo)記。

    注意:查詢字符串

    Pattern不會按照查詢字符串進(jìn)行匹配。為了達(dá)到這個(gè)目的,你必須使用一個(gè)帶有%{QUERY_STRING}變量的RewriteCond指令。當(dāng)然,你也可以在替換字符串中創(chuàng)建包含查詢字符串的URL:在替換字符串串中使用問號,以標(biāo)明其后的部分應(yīng)該被重新注入到QUERY_STRING中。而要刪除一個(gè)已有的請求串,則可以用問號來終結(jié)替換字符串。為了聯(lián)合新舊查詢字符串,請使用[QSA]標(biāo)志。

    以下是所有可能的替換組合及其含義:

    在服務(wù)器級配置中(httpd.conf)
    對給定的請求"GET /somepath/pathinfo":

    										給定的規(guī)則
    										得到的替換字符串
    										
    ---------------------------------------------- ----------------------------------
    ^/somepath(.*) otherpath$1 非法,不被支持

    ^/somepath(.*) otherpath$1 [R] 非法,不被支持

    ^/somepath(.*) otherpath$1 [P] 非法,不被支持
    ---------------------------------------------- ----------------------------------
    ^/somepath(.*) /otherpath$1 /otherpath/pathinfo

    ^/somepath(.*) /otherpath$1 [R] http://thishost/otherpath/pathinfo
    通過外部重定向

    ^/somepath(.*) /otherpath$1 [P] 毫無意義,不被支持
    ---------------------------------------------- ----------------------------------
    ^/somepath(.*) http://thishost/otherpath$1 /otherpath/pathinfo

    ^/somepath(.*) http://thishost/otherpath$1 [R] http://thishost/otherpath/pathinfo
    通過外部重定向

    ^/somepath(.*) http://thishost/otherpath$1 [P] 毫無意義,不被支持
    ---------------------------------------------- ----------------------------------
    ^/somepath(.*) http://otherhost/otherpath$1 http://otherhost/otherpath/pathinfo
    通過外部重定向

    ^/somepath(.*) http://otherhost/otherpath$1 [R] http://otherhost/otherpath/pathinfo
    通過外部重定向
    ([R]標(biāo)記是多余的)

    ^/somepath(.*) http://otherhost/otherpath$1 [P] http://otherhost/otherpath/pathinfo
    通過內(nèi)部代理

    /somepath的目錄級配置中
    (也就是/physical/path/to/somepath/.htacccess文件中含有:RewriteBase /somepath)
    對給定的請求"GET /somepath/localpath/pathinfo":

    										給定的規(guī)則
    										得到的替換字符串
    										
    ---------------------------------------------- ----------------------------------
    ^localpath(.*) otherpath$1 /somepath/otherpath/pathinfo

    ^localpath(.*) otherpath$1 [R] http://thishost/somepath/otherpath/pathinfo
    通過外部重定向

    ^localpath(.*) otherpath$1 [P] 毫無意義,不被支持
    ---------------------------------------------- ----------------------------------
    ^localpath(.*) /otherpath$1 /otherpath/pathinfo

    ^localpath(.*) /otherpath$1 [R] http://thishost/otherpath/pathinfo
    通過外部重定向

    ^localpath(.*) /otherpath$1 [P] 毫無意義,不被支持
    ---------------------------------------------- ----------------------------------
    ^localpath(.*) http://thishost/otherpath$1 /otherpath/pathinfo

    ^localpath(.*) http://thishost/otherpath$1 [R] http://thishost/otherpath/pathinfo
    通過外部重定向

    ^localpath(.*) http://thishost/otherpath$1 [P] 毫無意義,不被支持
    ---------------------------------------------- ----------------------------------
    ^localpath(.*) http://otherhost/otherpath$1 http://otherhost/otherpath/pathinfo
    通過外部重定向

    ^localpath(.*) http://otherhost/otherpath$1 [R] http://otherhost/otherpath/pathinfo
    通過外部重定向
    ([R]標(biāo)記是多余的)

    ^localpath(.*) http://otherhost/otherpath$1 [P] http://otherhost/otherpath/pathinfo
    通過內(nèi)部代理
    posted on 2011-02-16 09:01 禮物 閱讀(1188) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發(fā)表評論。

    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 91成人免费在线视频| 男女超爽刺激视频免费播放 | 青青操免费在线观看| 日本中文一区二区三区亚洲| 亚洲国产精品精华液| 久久精品a一国产成人免费网站| 亚洲精品视频在线观看视频| 99久久99热精品免费观看国产| 亚洲国产成人私人影院| 久久国产免费一区二区三区| 久久久久亚洲AV片无码| 99热这里只有精品6免费| 亚洲成人黄色在线观看| 免费下载成人电影| 亚洲国产精品精华液| 免费一级毛片一级毛片aa| 一级成人a做片免费| 亚洲综合另类小说色区| www免费黄色网| 国产综合亚洲专区在线| 免费人成网站在线观看不卡| 在线电影你懂的亚洲| 免费看黄视频网站| 综合偷自拍亚洲乱中文字幕| 亚洲一级特黄无码片| 久久狠狠躁免费观看2020| 亚洲一级黄色大片| 国产小视频在线观看免费| 一级毛片免费不卡| 久久亚洲AV成人无码电影| 美女被免费视频网站a国产| 四虎影视在线看免费观看| 亚洲韩国精品无码一区二区三区 | 91麻豆最新在线人成免费观看| 国产成人精品日本亚洲11| 免费jjzz在线播放国产| 最近中文字幕大全免费版在线| 免费网站看v片在线香蕉| 久久久精品国产亚洲成人满18免费网站| 国产亚洲综合成人91精品 | 三级黄色免费观看|