OpenResty之replace-filter-nginx-module


原文: openresty/replace-filter-nginx-module

1. 概要

location /t {
    default_type text/html;
    echo abc;
    replace_filter 'ab|abc' X;
}

location / {
    # proxy_pass/fastcgi_pass/...

    # caseless global substitution:
    replace_filter '\d+' 'blah blah' 'ig';
    replace_filter_types text/plain text/css;
}

location /a {
    # proxy_pass/fastcgi_pass/root/...

    # remove line-leading spaces and line-trailing spaces,
    # as well as blank lines:
    replace_filter '^\s+|\s+$' '' g;
}

location /b {
    # proxy_pass/fastcgi_pass/root/...

    # only remove line-leading spaces and line-trailing spaces:
    replace_filter '^[ \f\t]+|[ \f\t]+$' '' g;
}

location ~ '\.cpp$' {
    # proxy_pass/fastcgi_pass/root/...

    replace_filter_types text/plain;

    # skip C/C++ string literals:
    replace_filter "'(?:\\\\[^\n]|[^'\n])*'" $& g;
    replace_filter '"(?:\\\\[^\n]|[^"\n])*"' $& g;

    # remove all those ugly C/C++ comments:
    replace_filter '/\*.*?\*/|//[^\n]*' '' g;
}

2. 描述

該 Nginx 輸出過濾模塊嘗試盡可能以非緩存模式執行正則表達式替換。

該模塊沒有使用像 PCRE 這樣的傳統回溯正則表達式 engines,而是使用由作者實現的新的 sregex 庫,它從一開始就考慮了流處理。

sregex 支持 Perl 5 正則表達式的一個很好的公共子集。關於完整的功能列表,可查看 sregex 的文檔: sregex Syntax Supported.

響應體數據僅在絕對必要時才進行緩存,例如面對屬於數據塊邊界附近可能匹配的不完整捕獲。

3. 指令

3.1 replace_filter

syntax: replace_filter <regex> <replace>

syntax: replace_filter <regex> <replace> <options>

defaultL no

context: http, server, location, location if

phase: output body filter

通過可選地正則標志指定正則模式和要被替換為的文本。

By default, the filter topped matching after the first match is found. This behavior can be changed by specifying the g regex option.

支持如下正則選項:

  • g:全局搜索和替換(默認關閉該功能)
  • i:不區分大小寫(默認關閉)

在一個單獨的字符串參數中可以聯合多個選項,如下:

replace_filter hello hiya ig;

Nginx 變量可以插入到要替換的文本中,如下:

replace_filter \w+ "[$foo,$bar]";

如果要使用 '$' 字符,則使用 '$$',例如:

replace_filter \w "$$";

支持使用子匹配捕獲變量,如 $&, $1, $2 等等,如下示例:

replace_filter [bc]|d [$&-$1-$2] g;

子匹配捕獲變量的語義與 Perl 5 語言完全相同。

在同一范圍下支持多個 replace_filter 指令,所有的 pattern 將在 tokenizer 中同時應用。不會使用最長的 token 匹配語義,而是根據配置文件中的順序對 pattern 進行優先級排序。

如下示例是從 C/C++ 源文件中刪除所有的 C/C++ 注釋:

replace_filter "'(?:\\\\[^\n]|[^'\n])*'" $& g;
replace_filter '"(?:\\\\[^\n]|[^"\n])*"' $& g;
replace_filter '/\*.*?\*/|//[^\n]*' '' g;

Content-Encoding 響應頭部不為空(類似 gzip)時,響應主體將始終保持不變。因此,如果是 ngx_proxy 模塊的話,通常需要在 nginx.conf 中添加如下行,以在后端服務器響應中禁用 gzip 壓縮:

proxy_set_header Accept-Encoding '';

響應仍然可以在 Nginx 服務器級別上進行 gzip 壓縮。

3.2 replace_filter_types

syntax: replace_filter_types <mime-type> ...

default: replace_filter_types text/html

context: http, server, location, location if

phase: output body filter

指定要被處理的一個或多個 MIME 類型(在 Content-Type 響應頭部中)。

默認情況下,僅處理 text/html 類型的響應。

3.3 replace_filter_max_buffered_size

syntax: replace_filter_max_buffered_size <size>

default: replace_filter_max_buffered_size 8k

context: http, server, location, location if

phase: output body filter

限制模塊在運行時緩沖的數據的總大小,默認為 8k。

當達到限制值時,replace_filter 將立即停止處理,並保留所有剩余的響應正文數據。

3.4 replace_filter_last_modified

syntax: replace_filter_last_modified keep | clear

default: replace_filter_last_modified clear

context: http, server, location, location if

phase: output body filter

控制如何去處理現有的 Last-Modified 響應頭。

默認情況下,該模塊將清除 Last-Modified 響應頭(如果有)。可以通過指定如下行來保留原始的 Last-Modified 響應頭:

replace_filter_last_modified keep;

3.5 replace_filter_skip

syntax: replace_filter_skip $var

default: no

context: http, server, location, location if

phase: output header filter

該指令控制是否基於每個請求跳過所有的 replace_filter 規則。

該指令支持常量值或者包含 Nginx 變量的字符串。

當在請求輸出 header 階段將值評估為空值("")或者值 "0" 時,將不會跳過當前請求的 replace_filter 規則。否則,將會跳過當前請求的所有 replace_filter 規則。

如下一個簡單的示例:

set $skip '';
location /t {
    content_by_lua '
        ngx.var.skip = 1
        ngx.say("abcabd")
    ';
    replace_filter_skip $skip;
    replace_filter abcabd X;
}

4. 安裝

首先安裝 sregex 庫: https://github.com/agentzh/sregex

然后重新編譯 Nginx:

./configure --add-module=/path/to/replace-filter-nginx-module

如果 sregex 不是安裝在默認前綴路徑下(如 /usr/local),則可以在執行 ./configure 腳本前,通過 SREGEX_INCSREGEX_LIB 環境變量來指定 sregex 的安裝位置。

export SREGEX_INC=/opt/sregex/include
export SREGEX_LIB=/opt/sregex/lib

從 Nginx 1.9.11 版本以上,可以在 ./configure 命令行上通過使用 --add-dynamic-module=PATH 選項來代替 --add-module=PATH ,從而將該模塊編譯為動態模塊,然后在 ngxin.conf 上通過 load_module 指令顯示加載該模塊。

load_module /path/to/modules/ngx_http_replace_filter_module.so;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM