Mod_rewrite从URL末尾提取IP地址并传递给查询字符串变量

时间:2017-10-11 16:15:17

标签: regex apache mod-rewrite url-rewriting

我试图编写一个简单的地理位置,将URL末尾的IP地址传递给查询字符串。

在我的apache.conf中,我有以下指令:

RewriteEngine On
RewriteBase /geo/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} .*/([0-9_._]+)/?$
RewriteRule .*  /lookup.php?ip=%1  [L,QSA]

所以我希望得到这个网址:

https://example.com/geo/100.101.0.101  or
https://example.com/geo/100.101.0.101/

将ipv4地址发送至:

 https://example.com/lookup.php?ip=100.101.0.101

让它与ipv6一起使用也是一个超级好的。

1 个答案:

答案 0 :(得分:0)

您的重写不是100%准确

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# IPv4
RewriteCond %{REQUEST_URI} ^/?geo/([0-9\.]+)/?$ [NC,OR]
# IPv6
RewriteCond %{REQUEST_URI} ^/?geo/([0-9a-f:]+)/?$ [NC]
RewriteRule ^.*$  /lookup.php?ip=%1  [L,QSA]

说明:

RewriteBase /geo/只有在你这样做时才有意义。 RewriteRule ^.*$ lookup.php?ip=%1 [L,QSA]lookup.php实际上位于http://example.com/geo/lookup.php

%{REQUEST_URI}应以geo/<ip>开头,具体取决于您的服务器是否包含前导/

IP仅包含数字(0-9),a-f(仅限IPv6)和.:,具体取决于IP地址的版本(IPv4或IPv6)

目前还可以发送无效的格式化IP地址,如: /geo/999..777.444但我猜您会在您的应用中查看此内容。 但如果你有/geo/xx+666=765,那么根本不会重写。

如果你真的只想重写有效的IP地址,那么你必须使用更复杂的RegEx:

# IPv4 
RewriteCond %{REQUEST_URI} ^/?geo/(((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/?$ [NC,OR]
# IPv6  
RewriteCond %{REQUEST_URI} ^/?geo/(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/?$ [NC]

基于https://stackoverflow.com/a/17871737/5427950

的RegEx

我用Apache 2.4.27测试了这个肯定的Ubuntu 16.04.03 LTS服务器