【问题标题】:Virtual Hosts (Apache) with mod_rewrite issues具有 mod_rewrite 问题的虚拟主机 (Apache)
【发布时间】:2012-12-09 23:26:34
【问题描述】:

我试图解决这一整天都没有成功,所以我希望有人能够帮助我。我在http://localhost/ 有一个应用程序,它使用 Pylons 作为我托管的应用程序。除此之外,我需要托管一个 PHP/MySQL 站点,所以我也必须使用 Apache。

我目前的设置是我将 haproxy 与此配置一起用于 Apache 后端:

backend apache

mode http
timeout connect 4000
timeout server 30000
timeout queue 60000
balance roundrobin

server app02-8002 localhost:8002 maxconn 1000

这是由此触发的:

acl image url_sub images
use_backend apache if image

所以,当我打开我的 IP/图像时,它会触发它并打开 Apache,然后使用端口 8002。

对于 Apache,我创建了虚拟主机,这是“图像”:

<VirtualHost *:8002>
 ServerAdmin my@email.com
 ServerName image
 ServerAlias image
 DocumentRoot /srv/www/image/public_html/
 ErrorLog /srv/www/image/logs/error.log
 CustomLog /srv/www/image/logs/access.log combined
</VirtualHost>

所以,一切都很好,当我输入 IP/images 时,它会打开 /srv/www/image/public_html。但随后问题来了。由于我使用的是图像上传脚本,它涉及大量重写,所以我必须启用该模块。这是位于 public_html/images 文件夹中的 .htaccess(我不知何故也不得不制作这个子文件夹,以将 URL 与 public_html 中的实际位置“匹配”。 SetEnv PHP_VER 5_3

RewriteEngine On
# You must define your installation directory and uncomment the line :
RewriteBase /images/

RewriteRule ^([a-zA-Z]+)\.(jpg|gif|png|wbmp)$ controller/Resizer.php?m=original&a=$1&e=$2 [L]
RewriteRule ^(icon|small|medium|square)\/([a-zA-Z]+)\.(jpg|gif|png|wbmp)$ controller/Resizer.php?m=$1&a=$2&e=$3 [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) application.php?request=$1 [L,QSA]

所以,基本上,这在某种程度上是行不通的。我猜想这个虚拟主机、子目录、重写什么的有冲突,但是我似乎无法隔离它。

有点令人困惑的是,当我打开 IP/images/xxxx.jpg 时,它会打开位于 public_html/images/upload/original 文件夹中的图像,因此重写工作正常。其他规则似乎不起作用。所有的缩略图和较小的版本都没有正确呈现(图标、小、中、方形),这使得网站非常不可用。

这里是开发服务器的链接:http://localhost/images/

提前感谢您的时间和帮助!

【问题讨论】:

    标签: apache mod-rewrite virtualhost


    【解决方案1】:

    您应该做的第一件事是确定 mod_rewrite 是否确实是问题的一部分,方法是通过重写后的形式直接访问其中一个失败的 URL 并验证您是否获得了预期的结果。

    确实,问题可能只是用于较小分辨率的 PHP 脚本“不起作用”,而它适用于原始大小的分辨率。以下 URL 中的第一个很好地为我提供了图像;第二个应该给我相同图像的较小版本,但为我提供了 HTTP 500:

    http://106.186.21.176/images/controller/Resizer.php?m=original&a=q&e=png  
    http://106.186.21.176/images/controller/Resizer.php?m=small&a=q&e=png
    

    对于您帖子中提到的任何较小格式名称,我得到了相同的结果 (HTTP 500),这与您的问题描述相符。

    一旦您确认脚本按预期工作,问题很可能出在 mod_rewrite 上。如果是这样,启用重写日志记录:使用RewriteLog 指令来激活它,并使用RewriteLogLevel 来控制它的详细程度。尤其是在更高的日志级别,它可以为您提供关于它正在做什么的非常详细的信息。这应该可以使问题从日志中显而易见。

    此外,如果可能,请尽量避免在 .htaccess 文件中配置 mod_rewrite 规则——将它们移动到您的主服务器配置文件中。原因在Apache mod_rewrite Technical Details,“API 阶段”部分进行了解释:

    难以置信地 mod_rewrite 在每个目录的上下文中提供 URL 操作,即在 .htaccess 文件中,尽管在 URL 被转换为文件名之后很长时间才能达到这些操作。必须这样,因为 .htaccess 文件存在于文件系统中,所以处理已经到了这个阶段。换句话说:根据此时的 API 阶段,任何 URL 操作都为时已晚。为了克服这个先有鸡还是先有蛋的问题,mod_rewrite 使用了一个技巧:当您在每个目录上下文中操作 URL/文件名时,mod_rewrite 首先将文件名重写回其相应的 URL(这通常是不可能的,但请参阅下面的 RewriteBase 指令以获取技巧实现这一点),然后使用新的 URL 发起一个新的内部子请求。这将重新启动 API 阶段的处理。

    再次,mod_rewrite 努力使这个复杂的步骤对用户完全透明,但您应该记住:虽然在每个服务器上下文中的 URL 操作确实非常快速和高效,但由于这只鸡,每个目录的重写速度很慢而且效率低下和鸡蛋问题。但另一方面,这是 mod_rewrite 可以向普通用户提供(本地限制)URL 操作的唯一方式。

    一般来说,完全不使用 .htaccess 有一个额外的好处,您可以告诉 Apache 甚至不要打扰和禁用所有功能,这使 Apache 不必扫描它为 .htaccess 文件提供服务的每个目录级别.

    【讨论】:

    • 感谢您的回答。我对脚本及其生成链接的方式有点困惑(我不是作者),所以我没有想到不重写就检查这些确切的链接。因此,当我意识到脚本本身可能有问题时,我也检查了一些日志,发现了我之前错过的一些东西,PHP 错误。在那里我们调用了不存在的函数,我发现原因是缺少 GD 库。同样,脚本的作者没有说明正在使用它,所以当我安装它时,一切都按预期工作。
    猜你喜欢
    • 2015-10-06
    • 2011-05-20
    • 2012-11-16
    • 2010-10-22
    • 2010-11-02
    • 2012-10-29
    • 1970-01-01
    • 2018-11-21
    • 2011-07-31
    相关资源
    最近更新 更多