【问题标题】:mod_rewrite RewriteRule if-then-else troublesmod_rewrite RewriteRule if-then-else 麻烦
【发布时间】:2011-01-14 15:47:45
【问题描述】:

我的 Apache 配置使用 mod_rewrite 调用外部应用程序(使用 RewriteMap prg)来重写 URL。这很好用。我需要处理的是边界条件,即请求 URL 与我们要查找的 URL 不完全匹配。另外,外部应用程序返回错误,我们需要重定向到错误页面。

代码如下:

RewriteMap forwardURL "prg:\"C:/Program Files/Java/jdk1.6.0_11/bin/java.exe\" -jar \"C:/app/Mapper.jar\""

RewriteLock bin\map.sub.lock

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/SomeScript.asp(.*)$ ${forwardURL:%{QUERY_STRING}}
RewriteRule ^/error(.*)$ /error.html [L]

RewriteRule ^(.*)$ - [F]

当我们收到对旧 ASP 脚本 (SomeScript.asp) 的请求时,会调用 Java 应用程序来查找正确的 URL。它将返回正确的 URL 或“/error”。如果返回“/error”,我们希望 RewriteRule 将其更改为错误页面。所以规则 1 和 2 是捆绑在一起的。如果规则 1 运行,则规则 2 需要运行。如果规则 1 和规则 2 匹配,则规则 3 不应运行。规则 3 是返回 403- Forbidden 错误的 catch all 规则。

上面的代码很接近,但不完全在那里。包罗万象的最终规则是捕获太多。如果规则 1 匹配,则规则 3 也会捕获它并返回 403。

我们如何编写这样规则 1 和 2 的工作方式如上,但如果它们不匹配,则返回 403 错误?

谢谢

【问题讨论】:

    标签: java apache mod-rewrite


    【解决方案1】:

    使用 [L] 标志,该标志表示如果匹配则停止重写过程。所以为 1st 和 第二个标签添加这个标签。

    编辑--

    too fast;:您还需要将 [C] 标签添加到第一个规则,以便它与第二个规则链接,这使得如果第一个匹配,则第二个规则运行。只有第二个需要 [L]

    结束编辑--

    关于 rewriteMap prg,apache 文档要求在不匹配的情况下返回 'NULL',而不是“错误”。

    如果您仍然对 mod-rewrite 有一些疑问并且害怕 apache mod-rewrite 文档,请查看 servfault 上的这个优秀文档:everything-you-ever-wanted-to-know-about-mod-rewrite-rules-but-were-afraid-to-ask

    【讨论】:

    • 以下行不通:RewriteRule ^/SomeScript.asp(.*)$ ${forwardURL:%{QUERY_STRING}} [C] RewriteRule ^/error(.*)$ /error.html [L] RewriteRule ^(.*)$ - [F] 这导致总是返回 403。如果第一条规则成功,则最后一种情况总是匹配的。我想要返回的“/error”,这样我们就可以检测是否存在参数问题并将请求定向到错误页面。
    • 当第一个是好的时,只有当第二个不匹配时,你才会得到第三个。应该管用。你重启了apache吗?您可以使用 RewriteLog 和 RewriteLogLevel 指令调试发生的重写
    • 是的,一直在这样做。如果第一行响应并跳过第二行,则第三行捕获所有行...捕获它并返回 403。
    • 所以在第二个和 403 之间添加一个新规则,从第一个没有被第二个捕获的第一个中捕获所有有效响应。
    【解决方案2】:

    这就是我们最终要做的事情:我们去掉了第二行,并更改了 java 应用程序以返回错误文件的 URL。任何与第一行不匹配的内容都会被最后的 catch-all 行捕获,并以 Forbidden 消息进行响应。 mod_rewrite 逻辑可能无法实现我们想要做的事情。

    RewriteMap forwardURL "prg:\"C:/Program Files/Java/jdk1.6.0_11/bin/java.exe\" -jar \"C:/app/Mapper.jar\""
    
    RewriteLock bin\map.sub.lock
    
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^/SomeScript.asp(.*)$ ${forwardURL:%{QUERY_STRING}} [L]
    RewriteRule ^(.*)$ - [F]
    

    然后我们决定让单个 Java 应用程序回答重写问题的瓶颈太多,并将其转换为在 Tomcat 下运行的 servlet。通过这种方式,我们获得了更好的性能,也可以完全控制响应标头。给 regilero 一个尝试。

    【讨论】:

      猜你喜欢
      • 2010-12-01
      • 1970-01-01
      • 2012-02-10
      • 1970-01-01
      • 2013-11-14
      • 1970-01-01
      • 2016-04-03
      • 1970-01-01
      相关资源
      最近更新 更多