如何阻止多个mod_rewrite的通行证(或无限循环)在htaccess的背景下(How to block multiple mod_rewrite passes (or infinite loops) in a .htaccess context)

   IT问题网   2019-04-01 00:00:00

问 题

我工作在一个共享的apache v2.2服务器上运行的网站,这样所有的配置是通过.htaccess文件,我想使用mod_rewrite映射在低于完全,直接的方式的url到文件系统。只是举例的缘故,让我们说,我想要做的是这样的:

  • 地图网址 www.mysite.com/alice 对文件系统的文件夹 /的public_html /鲍勃·
  • 地图网址 www.mysite.com/bob 对文件系统的文件夹 /的public_html /爱丽丝

现在,经过数个小时的工作精心设计的规则集(真钞,不翘/鲍勃之一!)我把在/的public_html .htaccess文件我都精心打造的重写规则,并测试了它......只得到500服务器错误!

我被抓出一个有据可查的"疑难杂症!"在apache的:当mod_rewrite规则用于内部.htaccess文件,重新编写的网址是重新提交的新一轮处理(就好像它是一个外部请求)。出现这种情况,以便在重新写入请求的目标文件夹的任何规则可以适用,但它可能会导致通过网络服务器一些非常反直觉的行为!

在上面的例子中,这意味着,对于 www.mysite.com/alice/foo.html 被改写为 /鲍勃请求/ foo.html ,然后重新提交(内部)到服务器的 www.mysite.com/bob/foo.html 的请求。这是然后重新改写回 /alice/foo.html 并重新提交,这会导致它被重新重新改写为 /鲍勃/ foo.html ,依此类推;一个无限循环随之而来......只有一台服务器超时错误中断。


的问题是,如何保证一个的.htaccess mod_rewrite的规则集只被应用一次?


在[l]标志的重写规则将停止所有进一步改写的在一个单一的闯关规则集的,但是的的阻止被重新应用整个规则集后重新写入url被重新提交到服务器。根据该文件,阿帕奇v2.3.9 +(目前处于测试阶段)包含一个[结束]标志,提供precisely此功能。不幸的是,虚拟主机仍然使用apache 2.2,和他们拒绝我彬彬有礼的要求升级到公测版本!

我们需要的是一个解决方法,它提供的功能类似于[结束]标志。我首先想到的是,我可以使用一个环境变量:第一个重写通将告诉以后的通行证做任何进一步的改写过程中设置一个标志。如果我打电话给我的标志变量"end"中,code可能是这样的:

 #prevent进一步改写,如果"end"被标记
的rewritecond%{env:end} = 1
重写规则。*-[l]

#地图/爱丽丝/鲍勃,和/鲍勃/爱丽丝,和标记"end"完成时
重写规则^爱丽丝(/.*)$鲍勃$ 1 [l,e = end:1]
重写规则^鲍勃(/.*)$爱丽丝$ 1 [l,e = end:1]
 

unforunately这code不起作用:经过一些实验,我发现环境变量不重新提交url重写的过程中生存下来到服务器。在此apache文档页面最后一行表明,环境变量应该的生存内部重定向,但我发现,不是这样的。

[编辑:在某些服务器上,它的确实的工作。如果是这样,它比如下下面更好的解决方案。你必须自己试一试自己的服务器上看到的。]

不过,总体思路可以废物利用。许多个小时的拔头发,有的建议从同事后,我意识到,http请求头的的pserved跨内部重定向,所以如果我可以存储我的标志,其中之一$ p $,它可能工作!


下面是我的解决办法:


 #这头标志,有没有更多的改写工作要做。
#这是一个杂牌组装电脑中的apache v2.3.9直到使用结束标志成为可能+
#########删除此指令为apache 2.3.9+,并改变所有的[...,l,e = end:1]
#########刚刚[...,结束]下面所有的规则!

requestheader设置特殊的头-stop-进一步-重写-kjhsdf87653vasj 1 env = end


#如果我们的特别结束的重写标头设置此规则将阻止所有进一步重写。
#########删除此指令为apache 2.3.9+,并改变所有的[...,l,e = end:1]
#########刚刚[...,结束]下面所有的规则!

的rewritecond%{http:特殊头-stop-进一步-重写-kjhsdf87653vasj} = 1 [nv]
重写规则。*-[l]


#地图/爱丽丝/鲍勃,和/鲍勃/爱丽丝,和标记"end"完成时

重写规则^爱丽丝(/.*)$鲍勃$ 1 [l,e = end:1]
重写规则^鲍勃(/.*)$爱丽丝$ 1 [l,e = end:1]
 

...而且,它的工作!这里的原因:内部.htaccess文件,与各种apache模块相关的指令在执行的的模块顺序的主apache配置定义(或者,这是我的理解,反正...)。在此情况下(和批判对这一解决方案的成功)mod_headers中设置的mod_rewrite后执行,所以requestheader指令被执行的的重写规则。这意味着在 special头-stop-进一步-重写-kjhsdf87653vasj 头被添加到http请求当且仅当有一个重写规则[e = end:1]在它的标志列表得到匹配。在下一阶段(后重新写入请求重新提交给服务器)的第一个重写规则检测到这个标题,并中止任何进一步重写。

有些事情需要注意该解决方案是:

  1. 如果apache配置为运行mod_headers中的的mod_rewrite的它不会工作。 (我不知道这甚至有可能,如果是这样,如何不寻常的它会是)。

  2. 如果外部用户包括 special头-stop-进一步-重写-kjhsdf87653vasj 报头中的http请求到服务器,它会禁用所有 url重写规则,并且用户将看到文件系统的目录结构"原样"。这对随机字符串在头名的末尾ascii字符的原因 - 这是使头很难猜测。这是否是一个功能或安全漏洞,取决于你的观点!

  3. 这里的想法是一种变通方法来模拟使用[结束]标志的apache的版本还没有拥有它。如果你想要的是,以确保您的规则集只运行一次,无论哪个规则被触发,那么你很可能跌落使用"end"环境变量,只是这样做:

     的rewritecond%{http:特殊头-stop-进一步-重写-kjhsdf87653vasj} = 1 [nv]
    重写规则。*-[l]
    
    requestheader设置特殊的头-stop-进一步-重写-kjhsdf87653vasj 1
    
    #地图/爱丽丝/鲍勃,和/鲍勃/爱丽丝
    重写规则^爱丽丝(/.*)$鲍勃$ 1 [l]
    重写规则^鲍勃(/.*)$爱丽丝$ 1 [l]
     

    甚至更好,这(虽然redirect_ *变量都记录在apache v2.2 documetation很差 - 他们似乎只提及的这里) - 所以我不能保证它会在所有的版本的apache):

     的rewritecond%!{env:redirect_status} ^ $
    重写规则。*-[l]。
    
    #地图/爱丽丝/鲍勃,和/鲍勃/爱丽丝
    重写规则^爱丽丝(/.*)$鲍勃$ 1 [l]
    重写规则^鲍勃(/.*)$爱丽丝$ 1 [l]
     

    不过,一旦你运行apache v2.3.9 +,我想到的是使用[结束]标记会比上面的解决方案更有效,因为(presumably)它完全避免了重写url为重另一个重写通提交到服务器。

    请注意,您可能还需要阻止重写子请求,在这种情况下,您可以在的rewritecond 的鸵鸟政策do-任何-更重写规则,像这样的:

     的rewritecond%{env:redirect_status}!^ $ [or]
    的rewritecond%{is_subreq} =真
    重写规则。*-[l]
     
  4. 这里的想法是一种变通方法,以取代使用[结束]标志的apache的版本还没有拥有它。但实际上,你可以使用这个通用的方法来存储更多的不仅仅是一个标志 - 你可以存储任意字符串或数字,将持续整个内部服务器重定向,并设计你的重写规则基于任何的测试条件依赖于它们rulecond提供。 (我不能把我的头顶部,想出一个理由的为什么的你会想这样做......但是,嘿,更多的灵活性和控制你有更好的,正确的?)


我猜是谁读到这里,已经想通了,我真的不问一个问题在这里任何人。它更是我已经找到了我自己的解决问题的办法我有,并希望将它张贴在了这里,以防别人参考的问题遇到了同样的问题。这是什么这个网站是一个重要组成部分,对吧?

...

但由于这的的应该是一个问题和回答的论坛上,我会问:

  • 在任何人都可以看到这个解决方案的潜在问题(比我已经提到的其他)?
  • 或者有没有人有实现同样的事情的一个更好的办法?
解决方案

根据您的apache编译,这种情况可能工作(添加"停止重写"的规则:即重写规则*-[ l]..或者只是针对特定问题的规则):

 的rewritecond%{env:redirect_status} ^ $
 

redirect_status 将是空的第一个/初始重写,并有 200 (或者其他值值还有 - 有没有检查过深),在任何后续的周期

不幸的是它的工作原理在某些系统上,并没有别人,我个人不知道什么是负责制作它的工作。

除了这个最常见的就是通过解析%{the_request} 变量,例如添加重写条件检查原始url,例如。的rewritecond%{the_request} ^ [az] + \ s + \ php \ shttp /.+- 但这仅仅是有道理的个别问题的规则。

在一般 - 你应该避免这样的"改写a- > b,然后乙 - >甲"的情况(我是pretty的一定要意识到这一点)

至于自己的解决方案 - "不解决,如果它不破。" - 如果它的工作原理则是伟大的,因为我没有看到任何重大的问题,这样的方法

标签:如何阻止禁止阻挠阻拦通行证或者无限无穷循环



分享:

  • 微信
  • QQ好友
  • QQ空间
  • 新浪微博


热门推荐

Zend框架和Word preSS集成(Zend Framework and Wordpress Integration)

problem we have an existing zend framework site hosted at ...

如何删除"网络/ app_dev.php"从Symfony2的网址?(How to remove "web/app_dev.php" from Symfony2 URLs)

problem i just created my first symfony2 project. but the ...

通过301重定向404误差的.htaccess的搜索引擎优化等(Redirecting 404 error with .htaccess via 301 for SEO etc)

problem i couldn't find a straight answer to my question ...

而不进行任何验证的IP地址(Allow IP address without authentication)

problem i have set up a site that is currently work in pr ...

HTTP的当量=英寸×UA兼容"内容=IE =边缘,镀铬= 1......在.htaccess把这个?(http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" ... Putting this in .htaccess)

problem i downloaded html5 boilerplate and it wouldnt val ...

如何使用mod_headers中和mod_expires缓存(how to use mod_headers and mod_expires to cache)

problem i want to cache images and other files on my site ...

如何从一个子目录中删除的.htaccess密码保护(How to remove .htaccess password protection from a subdirectory)

problem i have password protected my entire website using ...

请.git目录网站无法访问(Make .git directory web inaccessible)

problem i have a website that i use github (closed source ...

重写URL以htaccess的(rewrite url with htaccess)

problem first of all i am a beginner so please answer in ...

重写QUOT&; pretty的网址"?(Rewrite to "pretty URL")

problem this is an example of what i am trying to achieve ...

需要mod_rewrite的URL信息(mod_rewrite URL info required)

problem i am new to this mod_rewrite. i have been success ...

的.htaccess,迫使斜线和www(.htaccess, forcing a slash and www)

problem can someone please help me to force my website to ...

简单的301重定向在.htaccess与查询字符串不以重定向指令工作(Simple 301 redirect in .htaccess with query string does not work with Redirect directive)

problem i am trying to redirect a single url in a .htacce ...

如何将文本转换使用的.htaccess为小写的网址(How to convert text to lowercase URLs using .htaccess)

problem i want to set up 301 redirects in my .htaccess fi ...

"双向"改写("Two Way" Rewrite)

problem so, i'm trying to accomplish this: we have a url ...

与字preSS除非使用URL重写不工作[R](Url rewriting not working with wordpress unless using [R])

problem i have a wordpress installation on my website on ...

通过htaccess的重定向所有的HTTP和HTTPS非www网址https://www.xyz.com(Redirect all http AND https non-www URLS to https://www.xyz.com via htaccess)

problem for reasons much too long and complex to get into ...

重定向的* .htm为* .PHP(Redirect *.htm to *.php)

problem i am trying find out how to redirect all traffic ...

HTTPS重定向到非www和http到www(Redirect https to non-www and http to www)

problem i searched and found hundreds of related cases, b ...

如何从URL使用htaccess的本地主机和主机服务器删除“/公众”?(how can remove '/public' from url using htaccess for localhost and host server)

problem i'm using zend framework 2 on xampp. i created .h ...