原文地址

ngx_http_rewrite_module 模块用于通过 PCRE 正则表达式改变请求 URI,返回重定向并可以有条件地选择配置。

break、if、return、rewrite 以及 set 指令的处理顺序如下:

  • 首先按顺序执行在 server 块中指定的该模块的指令
  • 然后循环:
    • 根据请求 URI 搜索 location
    • 该模块的指令在 location 内指定时,按顺序执行
    • 如果请求 URI 被重写,则重复循环但不超过 10 次。

1. 指令

break

break 的可用上下文有:server、location、if。用于停止处理当前的 ngx_http_rewrite_module 指令集合。

如果指令是在 location 中声明的,则在该 location 中继续处理请求。

示例:

if ($slow) {
limit_rate 10k;
break;
}

if

if 的可用上下文有:server、location。如果指定的条件为 true,则在花括号内指定的模块指令被执行,并且该请求被分配给 if 指令内的配置。if 指令中的配置从先前的配置级别继承。

条件可能是以下任何一种情况:

  • 变量名;如果变量值是空字符串或“0”则为 FALSE。注意,在 1.0.1 版本之前,任何以“0”开头的字符串都会被当做 FALSE。
  • 使用“=”和“!=”的变量跟字符串的比较
  • 使用“~”(区分大小写匹配)和“~*”(不区分大小写匹配)运算符将变量与正则表达式匹配。正则表达式可以包含捕获,之后可以通过 1.." role="presentation">1..1..9 这几个变量名重复使用。“!~”和“!~*”用作不匹配运算符。如果正则表达式包含“}”或“;”字符,则整个表达式应该用单引号或双引号括起来。
  • 用“-f”和“!-f”运算符检查文件是否存在
  • 用“-d”和“!-d”运算符检查目录是否存在
  • 用“-e”和“!-e”运算符检查文件、目录或符号链接的存在性
  • 用“-x”和“!-x”运算符检查可执行文件

示例:

if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
} if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
set $id $1;
} if ($request_method = POST) {
return 405;
} if ($slow) {
limit_rate 10k;
} if ($invalid_referer) {
return 403;
}

$invalid_referer 变量的值由 valid_referers 指令设置。

return

return 的可用上下文有:server、location、if。

停止处理并向客户端返回指定的代码。非标代码 444 会关闭连接并且不会发送响应头。

从 0.8.42 版本开始,可以指定重定向 URL(代码 301,302,303,307 和 308)或响应正文文本(用于其他代码)。响应正文文本和重定向 URL 可以包含变量。作为特殊情况,可以指定重定向 URL 作为此服务器本地的 URI,在这种情况下,完整重定向 URL 将根据请求方案($scheme)、server_name_in_redirect 以及 port_in_redirect 指令形成。

另外,可以将使用 302 代码的临时重定向 URL 指定为唯一参数。这样的参数应该以“http//”,“https//”或“$scheme”字符串开头。URL 中可以包含变量。

版本 0.7.51 之前的版本可以返回的代码(仅支持这些代码):204,400,402-406,408,410,411,413,416 和 500-504。

在 1.1.16 和 1.0.13 之后,代码 307 才开始被视为重定向。

在版本 1.13.0 之后,代码 308 才开始被视为重定向。

另请参阅 error_page 指令。

rewrite

rewrite 的可用上下文有:server、location、if。

如果指定的正则表达式与请求 URI 匹配,则将按照替换字符串修改 URI。rewrite 指令按照其在配置文件中的顺序依次执行。可以使用标志来终止指令。如果替换字符串以“http//”,“https//”或“$scheme”开头,则处理停止并且将重定向返回给客户端。

可选的标志有:

  • last:停止处理当前的 ngx_http_rewrite_module 指令集合,开始搜索能够匹配修改过的 URI 的新的 location
  • break:跟 break 指令一样,停止处理当前的 ngx_http_rewrite_module 指令集合
  • redirect:返回使用 302 代码的临时重定向,在替换字符串不以“http//”,“https//”或“$scheme”开头时使用
  • permanent:返回使用 301 代码的永久重定向

完整的重定向 URL 根据请求方案($scheme)、server_name_in_redirect 以及 port_in_redirect 指令构成。

示例:

server {
...
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra last;
return 403;
...
}

但是如果这些指令被放到了“/download”这个 location 中,last 标志需要替换为 break,否则 Nginx 会在循环 10 次后返回 500 错误:

location /download/ {
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break;
return 403;
}

如果替换字符串包含新的请求参数,之前的请求参数会追加在新请求参数后面。如果不希望这样,那么在替换字符串的末尾添加一个问号可以避免添加它们,例如:

rewrite ^/users/(.*)$ /show?user=$1? last;

如果正则表达式包含“}”或“;”字符,整个正则表达式需要放在单引号或双引号里。

rewrite_log

语法:rewrite_log on | off;

默认值:rewrite_log off;

rewrite_log 的可用上下文有: http、server、location、if。

启用或禁用将 ngx_http_rewrite_module 模块指令处理结果记录到通知级别(notice)的 error_log 中。

set

语法:set $variable value;

默认值:无

set 的可用上下文有:server、location、if。

为指定的变量设置一个值。该值可以包含文本,变量及其组合。

uninitialized_variable_warn

语法:uninitialized_variable_warn on | off

默认值:uninitialized_variable_warn on;

uninitialized_variable_warn 的可用上下文有:http、server、location、if。

是否将未初始化变量导致的警告写入日志。

2. 内部实现

ngx_http_rewrite_module 模块的指令在配置阶段被编译成内部指令,在请求处理期间会被解释。解释器是一个简单的虚拟堆栈机器。

例如,下面的指令

location /download/ {
if ($forbidden) {
return 403;
} if ($slow) {
limit_rate 10k;
} rewrite ^/(download/.*)/media/(.*)\..*$ /$1/mp3/$2.mp3 break;
}

会被翻译成这些指令:

variable $forbidden
check against zero
return 403
end of code
variable $slow
check against zero
match of regular expression
copy "/"
copy $1
copy "/mp3/"
copy $2
copy ".mp3"
end of regular expression
end of code

注意,上面的 limit_rate 指令没有对应的指令,因为它与 ngx_http_rewrite_module 模块无关。会为 if 块创建一个单独的配置。如果条件成立,则将请求分配给 limit_rate 等于 10k 的此配置。

这个指令中:

rewrite ^/(download/.*)/media/(.*)\..*$ /$1/mp3/$2.mp3 break;

如果正则表达式中的第一个斜杠放在圆括号中,可以减少最终的指令:

rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;

相关指令看起来是这个样子:

match of regular expression
copy $1
copy "/mp3/"
copy $2
copy ".mp3"
end of regular expression
end of code

Nginx 模块 - ngx_http_rewrite_module的更多相关文章

  1. nginx 模块介绍

    nginx模块在编译文件下的odjs目录下 cat 查看ngx_modules.c文件 可以看到一些基本extern模块 常用标准模块 1. 性能相关配置 worker_processes numbe ...

  2. nginx 模块简介

    nginx模块一般分为5类:核心模块.标准http模块.可选http模块.邮件服务模块.第三方模块. 其中核心模块和标准http模块在快速编译之后就包含在了nginx中. 主要看一下核心模块.标准ht ...

  3. Nginx模块详解

    Nginx模块介绍 核心模块:core module 标准模块: HTTP modules: Standard HTTP modules Optional HTTP modules Mail modu ...

  4. OpenResty / Nginx模块,Lua库和相关资源的列表

    OpenResty / Nginx模块,Lua库和相关资源的列表 什么是OpenResty OpenResty是一个成熟的网络平台,它集成了标准的Nginx核心,LuaJIT,许多精心编写的Lua库, ...

  5. 结合源码看nginx-1.4.0之nginx模块组织结构详解

    目录 0. 摘要 1. nginx模块组织结构 2. nginx模块数据结构 3. nginx模块初始化 4. 一个简单的http模块 5. 小结 6. 参考资料 0. 摘要 nginx有五大优点:模 ...

  6. 【转】Nginx模块开发入门

    转自: http://kb.cnblogs.com/page/98352/ 结论:对Nginx模块开发入门做了一个helloworld的示例,简单易懂.也有一定的深度.值得一看. Nginx模块开发入 ...

  7. Nginx模块开发入门

    前言 Nginx是当前最流行的HTTP Server之一,根据W3Techs的统计,目前世界排名(根据Alexa)前100万的网站中,Nginx的占有率为6.8%.与Apache相比,Nginx在高并 ...

  8. Nginx模块fastcgi_cache的几个注意点 转

    Nginx模块fastcgi_cache的几个注意点   去年年底,我对nginx的fastcgi_cache进行摸索使用.在我的测试过程中,发现一些wiki以及网络上没被提到的注意点,这里分享一下. ...

  9. 开发Nginx模块

    开发Nginx模块 前面的哪些话 关于Nginx模块开发的博客资料,网上很多,很多.但是,每篇博客都只提要点,无法"step by step"照着做,对于初次接触Nginx开发的同 ...

随机推荐

  1. [BZOJ 3731] Gty的超级妹子树 (树分块)

    [BZOJ 3731] Gty的超级妹子树 (树分块) 题面 给出一棵树(或森林),每个点都有一个值.现在有四种操作 1.查询x子树里>y的值有多少个 2.把点x的值改成y 3.添加一个新节点, ...

  2. BZOJ 1100 &&luogu 3454(计算几何+KMP)

    题面 给定一个多边形,求对称轴数量. 分析 初看这似乎是一道计算几何的题目,但是如果暴力枚举对称轴,再去判断对称轴两边的边和角是否相等,时间复杂度为\(O(n^2)\),显然会TLE 问题转换 顺时针 ...

  3. java synchronized实现可见性对比volatile

    问题: 大家可以先看看这个问题,看看这个是否有问题呢? 那里有问题呢? public class ThreadSafeCache { int result; public int getResult( ...

  4. hdu6357 Hills And Valleys (最长不下降子序列)

    题目传送门 题意: 给你0~9的字符串,问你翻转哪个区间后使得其最长不下降子序列长度最长 思路: 因为字符是0~9,所以我们可以定义一个b数组来枚举L,R, 去和原来的字符串去求最长公共子序列长度,不 ...

  5. 分布式唯一ID生成器

    在应用程序中,经常需要全局唯一的ID作为数据库主键.如何生成全局唯一ID? 首先,需要确定全局唯一ID是整型还是字符串?如果是字符串,那么现有的UUID就完全满足需求,不需要额外的工作.缺点是字符串作 ...

  6. 银联银行卡查询服务-dubbo实现

    最近看到银联开放了一个银行卡查询的服务,具体内容见官网https://open.unionpay.com/tjweb/api/detail?apiSvcId=51 尝尝鲜 在文档下载目录下,下载upa ...

  7. HDU 4678 Mine(博弈)

    Mine Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submi ...

  8. centos7 内网可达,外网不可达

    参考:https://www.cnblogs.com/operationhome/p/10207257.html 网关地址改为192.168.1.1

  9. 设置div 居中 和得到dom元素高度

    javascript中获取dom元素高度和宽度的方法如下: 网页可见区域宽: document.body.clientWidth网页可见区域高: document.body.clientHeight网 ...

  10. Mybatis(三)MyBatis 注解方式的基本 用法

    在 MyBatis注解 SQL 中,最基本的就是@Select.@Insert.@Update 和@Delete 四种.