.htaccess 重写规则覆盖ProxyPass

gv8xihay  于 2022-11-16  发布在  其他
关注(0)|答案(1)|浏览(180)

在centos 7机器上,我想在apache服务器旁边运行python服务器,我认为最简单的方法是将apache配置为反向代理。下面是我的VirtualHost配置:

<VirtualHost *:443>
        DocumentRoot /home/username/mydomain/src
        ServerName mydomain.com
        ErrorLog logs/mydomain-error_log
        CustomLog logs/mydomain-access_log common
        DirectoryIndex index.php

    <Directory /home/username/mydomain/src>
        Options -Indexes +FollowSymLinks
        AllowOverride None
        Require all granted
        AddOutputFilterByType DEFLATE text/html text/plain text/xml
    </Directory>

    ProxyPreserveHost On
    ProxyPass /mediaproxy http://127.0.0.1:9001/mediaproxy
    ProxyPassReverse /mediaproxy http://127.0.0.1:9001/mediaproxy

    LogLevel alert rewrite:trace6
    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^/api/media/(.*) /data/$1 [L]
    RewriteRule ^/api/v1/* /api/v1/index.php [L]
    RewriteRule ^/assets/(.*) /site/v1/content/assets/$1 [L]
    RewriteRule ^/css/(.*) /site/v1/content/css/$1 [L]
    RewriteRule ^/js/(.*) /site/v1/content/js/$1 [L]
    RewriteRule ^/fonts/(.*) /site/v1/content/fonts/$1 [L]
    RewriteRule ^/* /index.php [L] # problematic rule

    // lets encrypt entries

现在,我的问题是重写规则优先于ProxyPass。当我访问mydomain.com/mediaproxy/somepage时,它提供/index.php的内容,指定为RewriteRule ^/* /index.php [L]。如果我删除有问题的规则,反向代理可以正常工作。不幸的是,我需要保留它。
我如何告诉apache首先使用ProxyPass规则,只有在没有匹配的情况下才使用RewriteRule

zfciruhq

zfciruhq1#

RewriteRule ^/* /index.php [L] # problematic rule

您的规则会重写 * 所有内容 *。您可以只为要代理的URL路径设置例外。例如:

RewriteRule !^/mediaproxy /index.php [L]

RewriteRulepattern 上的!前缀会否定表达式。因此,如果它 * 不 * 匹配,则成功。
这将重写所有内容,* 除了 * 以/mediaproxy开头的URL路径。
请注意,正则表达式^/*中尾部的*量词与前面的标记重复了0次或多次。本例中前面的标记是斜杠。您缺少前面的.(点)。或者完全省略.*,因为它是多余的(而且效率较低)。

  • 旁白 *
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/api/media/(.*) /data/$1 [L]
RewriteRule ^/api/v1/* /api/v1/index.php [L]
RewriteRule ^/assets/(.*) /site/v1/content/assets/$1 [L]
RewriteRule ^/css/(.*) /site/v1/content/css/$1 [L]
RewriteRule ^/js/(.*) /site/v1/content/js/$1 [L]
RewriteRule ^/fonts/(.*) /site/v1/content/fonts/$1 [L]
RewriteRule ^/* /index.php [L] # problematic rule

两个条件(RewriteCond指令)在这里没有做任何事情。当在虚拟主机上下文中使用时,REQUEST_FILENAMEREQUEST_URI相同,因为它在请求Map到文件系统之前被提前处理。因此,(negated)conditions 将始终成功,并且始终处理以下规则。在vhost上下文中,您需要使用lookahead,即LA-U:REQUEST_FILENAME,或者使用DOCUMENT_ROOT服务器变量构造文件路径,或者将规则移动到 * 目录 * 上下文中。
然而,这两个条件只适用于后面的第一个规则。所以所有剩下的规则(包括最后一个“有问题”的规则)无论如何都会被无条件地处理。这对于前端控制器模式(最后一个规则)通常是不正确的,也许应该这样写:

RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule !^/mediaproxy /index.php [L]

这将重写除URL路径以外的所有内容,这些路径不以/mediaproxy开头,也不Map到目录,也不Map到文件。
或者,如果这些 * 条件 * 应套用至所有规则,则改为建立否定规则。例如:

DirectoryIndex index.php

RewriteEngine on

# Prevent further processing if root directory or "index.php" requested
RewriteRule ^/(index\.php)?$ - [L]

# Prevent further processing if the request maps to a directory or file
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f
RewriteRule ^/. - [L]

RewriteRule ^/api/media/(.*) /data/$1 [L]

# This rule is not required since the DirectoryIndex handles this case (the regex is also "incorrect").
#RewriteRule ^/api/v1/* /api/v1/index.php [L]

RewriteRule ^/assets/(.*) /site/v1/content/assets/$1 [L]
RewriteRule ^/css/(.*) /site/v1/content/css/$1 [L]
RewriteRule ^/js/(.*) /site/v1/content/js/$1 [L]
RewriteRule ^/fonts/(.*) /site/v1/content/fonts/$1 [L]
RewriteRule !^/mediaproxy /index.php [L]

相关问题