首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RewriteRule重写ProxyPass

RewriteRule重写ProxyPass
EN

Stack Overflow用户
提问于 2022-08-04 19:56:01
回答 1查看 123关注 0票数 1

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

代码语言:javascript
复制
<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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-05 11:12:10

RewriteRule ^/* /index.php L#问题规则

你的规则改写了一切。您只需为要代理的URL路径设置一个例外。例如:

代码语言:javascript
复制
RewriteRule !^/mediaproxy /index.php [L]

!模式上的RewriteRule前缀否定表达式。因此,当它不匹配时,它是成功的。

这现在重写了除了启动/mediaproxy的URL路径之外的所有内容。

注意,regex *中的尾随^/*量化符重复前面的令牌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 ^/字体/(.*)/site/v1/content/字体/$1 L RewriteRule ^/* /index.php L#问题规则

这两个条件(RewriteCond指令)在这里没有做任何事情。当在虚拟主机上下文中使用时,REQUEST_FILENAMEREQUEST_URI是相同的,因为它在请求映射到文件系统之前被提前处理。因此,这两种(被否定的)条件都是成功的,下面的规则总是被处理的。在vhost上下文中,您需要使用前瞻性,即。LA-U:REQUEST_FILENAME,OR使用DOCUMENT_ROOT服务器变量构造文件路径,或者将规则移动到目录上下文中。

然而,这两个条件只适用于下面的第一条规则。因此,所有剩余的规则(包括最后一个“有问题的”规则)无论如何都是无条件地处理的。对于前端控制器模式(最后一条规则)来说,这通常是不正确的,也许应该这样写:

代码语言:javascript
复制
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule !^/mediaproxy /index.php [L]

这现在重写了除URL路径之外的所有内容,这些路径不启动/mediaproxy,也不映射到目录,也不映射到文件。

或者,如果这些允许应该应用于所有规则,那么就创建一个否定的规则。例如:

代码语言:javascript
复制
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]
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73241608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档