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

Posted

技术标签:

【中文标题】设置自定义处理程序时重定向失败【英文标题】:Redirect failed when setting a custom handler 【发布时间】:2014-07-14 17:21:06 【问题描述】:

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

<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

什么可能导致这个问题?另外,请注意faq/.. 的第二个RewriteRule 工作正常。我在每个目录的 htaccess 文件中还有一些重写规则,它们都在正常工作。

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


听从covener和anubhava的建议;我将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

【问题讨论】:

【参考方案1】:

要使其正常工作,您需要从&lt;Directory&gt; 容器中取出这段代码 sn-p 并将其放入&lt;VirtualHost&gt; 块中:

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

它在&lt;VirtualHost&gt; 块中起作用的原因是因为重写发生在早期阶段 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>

【讨论】:

我在VirtualHost 部分中放置了代码如上所示,它非常适合http://localhost/index.phps 请求显示突出显示的文本。我已将我的 VirtualHost 条目放在上面。 +1 因为你肯定是最擅长为初学者详细解释事物的人,但我把赏金给了@covener,他完成了任务中最难的部分,找到了技术限制.希望你能理解。 给他赏金完全没问题,这是你的特权。【参考方案2】:

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

每个目录的替换做两件事:

将处理程序设置为特殊的 mod_rewrite 处理程序 为映射的文件名加上重定向前缀:

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

这是每个目录重写的记录限制,并且此 H= 标志不起作用,但并不是说它会破坏重写:

更改与请求关联的元数据的标志(T=、H=、E=) 在每个目录和 htaccess 上下文中没有影响,当 替换(“-”除外)在同一轮 重写处理。

您应该将重写指令从 上下文中拉出,并将前导前缀 (/ ?) 恢复到您的第一个参数,并确保您的第二个参数替换是绝对 URL 路径而不是相对 URL 路径。在目录上下文之外,不需要内部重定向,一切都简单得多。

例如使其对非 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->file 映射。 我

【讨论】:

有趣。如果您添加有关 Header/Handler 错误的更多详细信息以及 ou-of-directory rewrite 的示例,我现在就给您赏金。 我不确定我理解你的意思。第二条规则没有给我任何问题。前导 /? 匹配有效,因为没有名为 faq 的目录。发生的情况是第一条规则(将所有 .phps 请求重定向到具有自定义标头的相应 .php 文件)尝试正确重定向但返回 404 错误。 @regilero,我在答案中详细说明了一点。 hjpotter92 - 问题是自定义处理程序(不是标题)在重写过程中没有保留,它在每个目录上下文中不可用。这实际上是有记录的。 我更新了conf文件并重启了服务器。问题依然存在。

以上是关于设置自定义处理程序时重定向失败的主要内容,如果未能解决你的问题,请参考以下文章

Angular 2:在应用程序启动时重定向到页面

更改设备方向时重绘自定义 uiview

容器在启动时重定向日志文件的方法

Spring Security 3.1.1 - 自定义登录成功问题

在自定义属性更改时重绘自定义 CALayer 子类

Spring Security 自定义登录处理 URL 始终重定向到故障处理程序