如何在 Nginx 服务器上执行不区分大小写的正则表达式?
How to do case insensitive regex on an Nginx server?
将服务器从 Ubuntu 迁移到 Debian 后出现严重问题。 Debian 不允许两个文件,例如“a.html
”和“A.html
”位于同一目录中。
我的服务器收到三种类型的请求,这是当前状态:
请求如/archive/2014/www.Test.com
随文件一起提供:/archive/2014/blank.html
/archive/2015/Test.com
和 /archive/2015/www.Test.com
等请求随文件一起提供 /archive/2015/T.html
/archive/2015/test.com
和 /archive/2015/www.test.com
等请求随文件一起提供 /archive/2015/t.html
我希望最后两种类型的请求在两种情况下(以不区分大小写的方式)提供文件 /archive/2015/t.html
。
我怎样才能达到这个结果?
当前服务器设置为:
server {
listen 127.0.0.1:80;
server_name 127.0.0.1;
access_log /srv/siteone/logs/access.log;
error_log /srv/siteone/logs/error.log error;
location / {
root /srv/siteone/html;
index index.html index.htm;
expires 1d;
}
rewrite ^/archive/2014/(.+)$ /archive/2014/blank.html last;
rewrite ^/archive/2015/(www\.)*(.)(.+)$ /archive/2015/.html last;
error_page 403 /403.html;
error_page 404 /404.html;
}
有很多方法可以解决这个问题。
由于您只需要将一个特定字母更改为小写,您可以将 "map" 与不区分大小写的正则表达式一起使用:
map $request $letter {
"~*^/archive/[0-9]{4}/(www\.)?a(.*)?$" a;
"~*^/archive/[0-9]{4}/(www\.)?b(.*)?$" b;
"~*^/archive/[0-9]{4}/(www\.)?c(.*)?$" c;
"~*^/archive/[0-9]{4}/(www\.)?d(.*)?$" d;
"~*^/archive/[0-9]{4}/(www\.)?e(.*)?$" e;
"~*^/archive/[0-9]{4}/(www\.)?f(.*)?$" f;
"~*^/archive/[0-9]{4}/(www\.)?g(.*)?$" g;
"~*^/archive/[0-9]{4}/(www\.)?h(.*)?$" h;
"~*^/archive/[0-9]{4}/(www\.)?i(.*)?$" i;
"~*^/archive/[0-9]{4}/(www\.)?j(.*)?$" j;
"~*^/archive/[0-9]{4}/(www\.)?k(.*)?$" k;
"~*^/archive/[0-9]{4}/(www\.)?l(.*)?$" l;
"~*^/archive/[0-9]{4}/(www\.)?m(.*)?$" m;
"~*^/archive/[0-9]{4}/(www\.)?n(.*)?$" n;
"~*^/archive/[0-9]{4}/(www\.)?o(.*)?$" o;
"~*^/archive/[0-9]{4}/(www\.)?p(.*)?$" p;
"~*^/archive/[0-9]{4}/(www\.)?q(.*)?$" q;
"~*^/archive/[0-9]{4}/(www\.)?r(.*)?$" r;
"~*^/archive/[0-9]{4}/(www\.)?s(.*)?$" s;
"~*^/archive/[0-9]{4}/(www\.)?t(.*)?$" t;
"~*^/archive/[0-9]{4}/(www\.)?u(.*)?$" u;
"~*^/archive/[0-9]{4}/(www\.)?v(.*)?$" v;
"~*^/archive/[0-9]{4}/(www\.)?w(.*)?$" w;
"~*^/archive/[0-9]{4}/(www\.)?x(.*)?$" x;
"~*^/archive/[0-9]{4}/(www\.)?y(.*)?$" y;
"~*^/archive/[0-9]{4}/(www\.)?z(.*)?$" z;
}
server {
listen 127.0.0.1:80;
server_name 127.0.0.1;
access_log /srv/siteone/logs/access.log;
error_log /srv/siteone/logs/error.log error;
root /srv/siteone/html;
location / {
index index.html index.htm;
expires 1d;
}
rewrite ^/archive/2014/(.+)$ /archive/2014/blank.html last;
rewrite ^/archive/2015/(www\.)?(.)(.+)$ /archive/2015/$letter.html last;
error_page 403 /403.html;
error_page 404 /404.html;
}
如果你安装了嵌入式 Perl 模块(sudo apt-get install nginx-extras),你可以使用 Perl 将请求行变成小写:
perl_set $uri_lowercase 'sub {
my $r = shift;
return lc($r->uri);
}';
server {
listen 127.0.0.1:80;
server_name 127.0.0.1;
access_log /srv/siteone/logs/access.log;
error_log /srv/siteone/logs/error.log error;
root /srv/siteone/html;
location / {
index index.html index.htm;
expires 1d;
}
rewrite ^/archive/2014/(.+)$ /archive/2014/blank.html last;
rewrite ^/archive/2015/(www\.)?(.)(.+)$ $uri_lowercase;
rewrite ^/archive/2015/(www\.)?(.)(.+)$ /archive/2015/.html last;
error_page 403 /403.html;
error_page 404 /404.html;
}
如果你更喜欢 Lua 而不是 Perl,你可以用 Lua 做同样的事情(同样,你需要安装 nginx-extras):
server {
listen 127.0.0.1:80;
server_name 127.0.0.1;
access_log /srv/siteone/logs/access.log;
error_log /srv/siteone/logs/error.log error;
root /srv/siteone/html;
location / {
index index.html index.htm;
expires 1d;
}
rewrite ^/archive/2014/(.+)$ /archive/2014/blank.html last;
rewrite_by_lua 'ngx.req.set_uri(string.lower(ngx.var.uri), false)';
rewrite ^/archive/2015/(www\.)?(.)(.+)$ /archive/2015/.html last;
error_page 403 /403.html;
error_page 404 /404.html;
}
如果您不喜欢以上所有内容,总有一些 Nginx 的黑暗技巧可以提供帮助(但我真的不推荐它):
server {
listen 127.0.0.1:8484;
access_log off;
rewrite ^.*$ /archive/2015/$host.html;
root /srv/siteone/html;
location / {
index index.html index.htm;
expires 1d;
}
}
server {
listen 127.0.0.1:80;
server_name 127.0.0.1;
access_log /srv/siteone/logs/access.log;
error_log /srv/siteone/logs/error.log error;
root /srv/siteone/html;
location / {
index index.html index.htm;
expires 1d;
}
location ~* ^/archive/2015/(?<letter>[A-Z])\.html$ {
proxy_set_header Host $letter;
proxy_pass http://127.0.0.1:8484;
}
rewrite ^/archive/2014/(.+)$ /archive/2014/blank.html last;
rewrite ^/archive/2015/(www\.)?(.)(.+)$ /archive/2015/.html last;
error_page 403 /403.html;
error_page 404 /404.html;
}
将服务器从 Ubuntu 迁移到 Debian 后出现严重问题。 Debian 不允许两个文件,例如“a.html
”和“A.html
”位于同一目录中。
我的服务器收到三种类型的请求,这是当前状态:
请求如/archive/2014/www.Test.com
随文件一起提供:/archive/2014/blank.html
/archive/2015/Test.com
和 /archive/2015/www.Test.com
等请求随文件一起提供 /archive/2015/T.html
/archive/2015/test.com
和 /archive/2015/www.test.com
等请求随文件一起提供 /archive/2015/t.html
我希望最后两种类型的请求在两种情况下(以不区分大小写的方式)提供文件 /archive/2015/t.html
。
我怎样才能达到这个结果?
当前服务器设置为:
server {
listen 127.0.0.1:80;
server_name 127.0.0.1;
access_log /srv/siteone/logs/access.log;
error_log /srv/siteone/logs/error.log error;
location / {
root /srv/siteone/html;
index index.html index.htm;
expires 1d;
}
rewrite ^/archive/2014/(.+)$ /archive/2014/blank.html last;
rewrite ^/archive/2015/(www\.)*(.)(.+)$ /archive/2015/.html last;
error_page 403 /403.html;
error_page 404 /404.html;
}
有很多方法可以解决这个问题。
由于您只需要将一个特定字母更改为小写,您可以将 "map" 与不区分大小写的正则表达式一起使用:
map $request $letter { "~*^/archive/[0-9]{4}/(www\.)?a(.*)?$" a; "~*^/archive/[0-9]{4}/(www\.)?b(.*)?$" b; "~*^/archive/[0-9]{4}/(www\.)?c(.*)?$" c; "~*^/archive/[0-9]{4}/(www\.)?d(.*)?$" d; "~*^/archive/[0-9]{4}/(www\.)?e(.*)?$" e; "~*^/archive/[0-9]{4}/(www\.)?f(.*)?$" f; "~*^/archive/[0-9]{4}/(www\.)?g(.*)?$" g; "~*^/archive/[0-9]{4}/(www\.)?h(.*)?$" h; "~*^/archive/[0-9]{4}/(www\.)?i(.*)?$" i; "~*^/archive/[0-9]{4}/(www\.)?j(.*)?$" j; "~*^/archive/[0-9]{4}/(www\.)?k(.*)?$" k; "~*^/archive/[0-9]{4}/(www\.)?l(.*)?$" l; "~*^/archive/[0-9]{4}/(www\.)?m(.*)?$" m; "~*^/archive/[0-9]{4}/(www\.)?n(.*)?$" n; "~*^/archive/[0-9]{4}/(www\.)?o(.*)?$" o; "~*^/archive/[0-9]{4}/(www\.)?p(.*)?$" p; "~*^/archive/[0-9]{4}/(www\.)?q(.*)?$" q; "~*^/archive/[0-9]{4}/(www\.)?r(.*)?$" r; "~*^/archive/[0-9]{4}/(www\.)?s(.*)?$" s; "~*^/archive/[0-9]{4}/(www\.)?t(.*)?$" t; "~*^/archive/[0-9]{4}/(www\.)?u(.*)?$" u; "~*^/archive/[0-9]{4}/(www\.)?v(.*)?$" v; "~*^/archive/[0-9]{4}/(www\.)?w(.*)?$" w; "~*^/archive/[0-9]{4}/(www\.)?x(.*)?$" x; "~*^/archive/[0-9]{4}/(www\.)?y(.*)?$" y; "~*^/archive/[0-9]{4}/(www\.)?z(.*)?$" z; } server { listen 127.0.0.1:80; server_name 127.0.0.1; access_log /srv/siteone/logs/access.log; error_log /srv/siteone/logs/error.log error; root /srv/siteone/html; location / { index index.html index.htm; expires 1d; } rewrite ^/archive/2014/(.+)$ /archive/2014/blank.html last; rewrite ^/archive/2015/(www\.)?(.)(.+)$ /archive/2015/$letter.html last; error_page 403 /403.html; error_page 404 /404.html; }
如果你安装了嵌入式 Perl 模块(sudo apt-get install nginx-extras),你可以使用 Perl 将请求行变成小写:
perl_set $uri_lowercase 'sub { my $r = shift; return lc($r->uri); }'; server { listen 127.0.0.1:80; server_name 127.0.0.1; access_log /srv/siteone/logs/access.log; error_log /srv/siteone/logs/error.log error; root /srv/siteone/html; location / { index index.html index.htm; expires 1d; } rewrite ^/archive/2014/(.+)$ /archive/2014/blank.html last; rewrite ^/archive/2015/(www\.)?(.)(.+)$ $uri_lowercase; rewrite ^/archive/2015/(www\.)?(.)(.+)$ /archive/2015/.html last; error_page 403 /403.html; error_page 404 /404.html; }
如果你更喜欢 Lua 而不是 Perl,你可以用 Lua 做同样的事情(同样,你需要安装 nginx-extras):
server { listen 127.0.0.1:80; server_name 127.0.0.1; access_log /srv/siteone/logs/access.log; error_log /srv/siteone/logs/error.log error; root /srv/siteone/html; location / { index index.html index.htm; expires 1d; } rewrite ^/archive/2014/(.+)$ /archive/2014/blank.html last; rewrite_by_lua 'ngx.req.set_uri(string.lower(ngx.var.uri), false)'; rewrite ^/archive/2015/(www\.)?(.)(.+)$ /archive/2015/.html last; error_page 403 /403.html; error_page 404 /404.html; }
如果您不喜欢以上所有内容,总有一些 Nginx 的黑暗技巧可以提供帮助(但我真的不推荐它):
server { listen 127.0.0.1:8484; access_log off; rewrite ^.*$ /archive/2015/$host.html; root /srv/siteone/html; location / { index index.html index.htm; expires 1d; } } server { listen 127.0.0.1:80; server_name 127.0.0.1; access_log /srv/siteone/logs/access.log; error_log /srv/siteone/logs/error.log error; root /srv/siteone/html; location / { index index.html index.htm; expires 1d; } location ~* ^/archive/2015/(?<letter>[A-Z])\.html$ { proxy_set_header Host $letter; proxy_pass http://127.0.0.1:8484; } rewrite ^/archive/2014/(.+)$ /archive/2014/blank.html last; rewrite ^/archive/2015/(www\.)?(.)(.+)$ /archive/2015/.html last; error_page 403 /403.html; error_page 404 /404.html; }