【问题标题】:RewriteRule includding only last part of REQUESTI_URIRewriteRule 仅包括 REQUEST_URI 的最后一部分
【发布时间】:2021-12-30 20:21:28
【问题描述】:
<LocationMatch /foo/>
 ProxyPreserveHost On
 RewriteEngine on
 RewriteCond %{HTTP:Upgrade} websocket [NC]
 RewriteCond %{HTTP:Connection} upgrade [NC]
 RewriteRule .* "ws://192.168.0.101:1234%{REQUEST_URI}" [P]

客户端连接时

ws://www.example.com/foo/whatever_arbitrary_random

这很好用,但结果是

ws://192.168.0.101:1234/foo/whatever_arbitrary_random

我怎样才能摆脱/foo/ 所以结果会是

ws://192.168.0.101:1234/whatever_arbitrary_random

客户端必须仍然需要连接到/foo/ 才能触发此操作

编辑:我找到了怎么做,用

替换最后一行
RewriteRule ([^/]+)/?$ ws://192.168.0.101:1234/$1 [P,L]

但请阅读第一个建议不要在某个位置执行此操作的答案

【问题讨论】:

  • "但结果是ws://192.168.0.101/foo...." - 端口号的遗漏大概只是疏忽吧?
  • 嗨,是的,你是对的。我将编辑问题

标签: mod-rewrite apache2.4 mod-proxy


【解决方案1】:

您不应在 &lt;Location&gt;(和 &lt;LocationMatch&gt;)容器内使用 mod_rewrite 指令。

更新:the Apache docs for the RewriteRule directive中所述:

尽管&lt;Location&gt;&lt;Files&gt; 部分(包括它们的正则表达式对应项)在语法上允许重写规则,但这绝不是必需的并且不受支持。在这些情况下可能会破坏的一个特征是相对替换。

&lt;Location&gt; 部分很晚才合并。在 &lt;Location&gt; 部分中使用时,RewriteRule 指令匹配绝对文件系统路径,而不是通常预期的 URL 路径。

如果 .htaccess 覆盖被禁用,那么您可以在适当的 &lt;Directory&gt; 容器中这样做:

<Directory /path/to/foo>
    # Disable .htaccess overrides if not already
    AllowOverride None

    ProxyPreserveHost On

    RewriteEngine on
    RewriteCond %{HTTP:Upgrade} websocket [NC]
    RewriteCond %{HTTP:Connection} upgrade [NC]
    RewriteRule .* ws://192.168.0.101:1234/$0 [P]
</Directory>

反向引用$0 自然排除了/foo/


更新:

RewriteRule ([^/]+)/?$ ws://192.168.0.101:1234/$1 [P,L]

这仅匹配最后一个路径段,它不严格匹配/foo/ 之后的所有内容。这可能会也可能不会,这取决于您的要求。例如。它将仅将对/foo/bar/baz 的请求重定向到/baz,而不是/bar/baz

正则表达式确实应该被锚定。但是,您可能已经这样写了,因为该指令位于 &lt;Location&gt; 部分内,并且匹配绝对文件路径,而不是请求的 URL 路径。

顺便说一句,与 P 一起使用时,您不需要 L 标志 - 这是隐含的。


上述的替代方案...您不需要在 directory 上下文中使用这些directvies(即在&lt;Directory&gt;&lt;Location&gt; 部分内)。您可以改为将这些规则直接放在 &lt;VirtualHost&gt; 容器(virtualhost 上下文)中,在这种情况下,它们应该改为这样编写:

ProxyPreserveHost On

RewriteEngine on
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule ^/foo/(.*) ws://192.168.0.101:1234/$1 [P]

【讨论】:

  • 嗨,你能详细说明一下为什么我不应该在&lt;Location&gt;(和&lt;LocationMatch&gt;)中这样做吗?
  • $0 对我来说返回文档路径/var/www/html/foo/random_stuff 可能是因为我在&lt;LocationMatch&gt; 内部使用了它?
  • @Tomari 我已经更新了我的答案,以包含有关为什么不应在 &lt;Location&gt; 部分中使用 mod_rewrite 指令的更多信息。当直接在&lt;VirtualHost&gt; 容器中使用时,我还包括了一个替代方案。是的,$0 将包含绝对文件系统路径,如果在 &lt;Location&gt; 部分中使用。如我的回答所述,所写的指令应在&lt;Directory&gt; 部分中使用,而不是&lt;Location&gt;。 (&lt;LocationMatch&gt; 也一样。)
  • 感谢您的澄清,我稍后会对此进行测试,使用 L 是因为正则表达式中的 ?,导致错误 500 too many requests。关于&lt;Location&gt; 这样做是否存在安全风险,还是只是“理智”的方式?与其他解决方案相比,负面影响是什么?只是想从这个机会中尽可能多地学习:)
猜你喜欢
  • 2015-04-28
  • 2013-07-13
  • 2014-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-18
相关资源
最近更新 更多