设置自定义处理程序时重定向失败

时间:2014-05-26 01:28:06

标签: apache .htaccess mod-rewrite redirect apache2.4

我的自定义配置文件中包含以下代码。

<Directory "/www">
    Options Indexes FollowSymLinks
    AllowOverride All
    <FilesMatch "\.phps$">
        SetHandler application/x-httpd-php-source
    </FilesMatch>
    ErrorDocument 403 "Please disable proxies to view content."
    RewriteEngine On
    RewriteRule ^(.*\.php)s$ $1 [H=application/x-httpd-php-source]
    RewriteRule ^faq/(\w+)/(\d+)/?$ faq.php?code=$1&num=$2 [NC]
</Directory>

现在,当我浏览到/index.phps/some/other/dir/and/file.phps这样的网页时,我在浏览器中收到404错误,并在apache的错误日志中记录以下内容:

[<date>] [:error] [pid 15154:tid 3024079728] [client <IP>] script 'redirect:/request/get_req.php' not found or unable to stat
[<date>] [:error] [pid 15152:tid 2914974576] [client <IP>] script 'redirect:/index.php' not found or unable to stat

可能导致此问题的原因是什么?另请注意,RewriteRule的第二个faq/..工作正常。我在每个目录基础htaccess文件中还有一些重写规则,并且所有这些规则都正常工作。

我使用的服务器版本是 Apache / 2.4.9(Unix)


遵循coveneranubhava的建议;我将conf文件更新为:

<VirtualHost *:80>
    DocumentRoot "/www"
    <FilesMatch "\.phps$">
        SetHandler application/x-httpd-php-source
    </FilesMatch>
    LogLevel warn
</VirtualHost>
<Directory "/www">
    Options Indexes FollowSymLinks
    AllowOverride All
    RewriteEngine On
    # RewriteRule ^(.*\.php)s$ %{DOCUMENT_ROOT}/$1 [H=application/x-httpd-php-source]
    # RewriteRule ^/?(.*\.php)s$ %{DOCUMENT_ROOT}/$1 [H=application/x-httpd-php-source]
    # RewriteRule ^(.*\.php)s$ $1 [H=application/x-httpd-php-source]
    RewriteRule ^(.*\.php)s$ %{DOCUMENT_ROOT}/$1 [H=application/x-httpd-php-source]
    RewriteRule ^faq/(\w+)/(\d+)/?$ faq.php?code=$1&num=$2 [NC]
</Directory>

但是php源代码的处理程序仍然记录了同样的错误:

[<date>] [:error] [pid 17586:tid 2956938096] [client <IP>] script 'redirect:/index.php' not found or unable to stat

2 个答案:

答案 0 :(得分:2)

你不能进行每个目录的替换并设置Handler(H =),因为mod_rewrite执行每个目录替换的机制需要将处理程序设置为mod_rewrite本身。

per-dir替换有两件事:

  • 将处理程序设置为特殊的mod_rewrite处理程序
  • 使用redirect:
  • 为映射的文件名添加前缀

因此,通过设置H =,您将吹走1并在您的错误消息中看到apache的核心试图处理“redirect:/ ...”作为文件名。

这是每个目录重写的文档限制,这个H =标志不起作用,但不是它打破了重写:

  

更改与请求关联的元数据的标志(T =,H =,E =)   在a目录和htaccess上下文中没有任何影响   替换(除了' - ')在同一轮中执行   重写处理。

您应该从&lt; Directory&gt;中提取重写指令上下文并将前导前缀(/?)恢复为第一个参数,并确保第二个参数替换是绝对URL路径而不是相对URL路径。在目录上下文之外,不需要内部重定向,一切都更简单。

e.g。为非per-dir环境安全:

RewriteRule ^(.*\.php)s$ %{DOCUMENT_ROOT}/$1 [H=application/x-httpd-php-source]
RewriteRule ^/faq/(\w+)/(\d+)/?$ /faq.php?code=$1&num=$2 [NC]

在此上下文中,您的URL被映射到文件并设置了处理程序,没有将URL重新引入Apache处理,因为它是一个简单的uri-&gt;文件映射。 我

答案 1 :(得分:2)

要使其正常工作,您需要从<Directory>容器中取出此代码段并将其放在<VirtualHost>块中:

<FilesMatch "\.phps$">
    SetHandler application/x-httpd-php-source
</FilesMatch>
RewriteEngine On
RewriteRule ^(.*\.php)s$ $1 [H=application/x-httpd-php-source]

它在<VirtualHost>块中起作用的原因是因为重写发生在早期阶段 apache处理,即per-server上下文。但是当它发生在per-dir上下文中时,它会在后期发生并导致请求在替换后重新启动。如果在每个目录上下文中进行替换,则会使用新URL发出新的内部子请求,从而重新开始处理请求阶段。

有关详细信息,请参阅此mod_rewrite tech reference

我的VirtualHost条目:

<VirtualHost *:80>
   <FilesMatch "\.phps$">
        SetHandler application/x-httpd-php-source
    </FilesMatch>
    ErrorDocument 403 "Please disable proxies to view content."
    RewriteEngine On
    RewriteRule ^([^.]+\.php)s$ $1 [H=application/x-httpd-php-source,NC]
</VirtualHost>