对子域使用子路径内部代理,但如果外部客户端要求该子路径,则重定向?

对子域使用子路径内部代理,但如果外部客户端要求该子路径,则重定向?

我有一个 VirtualHost,我想在上面设置几个子域。 (为了清楚起见,假设我的域名是示例.com我只是想开始做foo.example.com工作并从那里开始构建。

我发现,让子域名与我所拥有的框架非侵入式地协同工作的最简单的方法是通过 mod_rewrite 代理到子路径。因此,路径将在客户端的 URL 栏中显示为http://foo.example.com/(无论如何)而他们实际上已经得到了服务http://foo.example.com/foo/(无论如何)在引擎盖下。

我已经设法在我的 VirtualHost 配置文件中做到这一点,如下所示:

ServerAlias *.example.com

RewriteEngine on

RewriteCond %{HTTP_HOST} ^foo\.example\.com [NC]   # <---
RewriteCond %{REQUEST_URI} !^/foo/.*$ [NC]         # AND is implicit with above
RewriteRule ^/(.*)$ /foo/$1 [PT]

(注:要找到那个特定的有效组合真是太难了。具体来说,[PT] 似乎是 RewriteRule 上的必需项。我无法让它与我在其他地方看到的示例(如 [L] 或仅尝试 [P])一起工作。它要么不显示任何内容,要么陷入循环。此外,有些浏览器似乎会在遇到坏循环后缓存响应页面……修复后重新加载页面不会显示它正在工作!如果这部分可以做得更好,欢迎提供反馈——无论如何。)

现在我想做什么http://foo.example.com/foo/(无论如何)提供取决于谁提出请求。如果请求来自外部,我希望客户端被 Apache 永久重定向,以便他们获得 URLhttp://foo.example.com/(无论如何)在他们的浏览器中。如果它来自 mod_rewrite 内部,我希望请求由 Web 框架处理……该框架不知道子域。

这样的事可能吗?

答案1

看起来你已经快到了,不是吗?

使用基于 REMOTE_ADDR 的 RewriteCond,例如:

#
# Provide HTTP redirect "[R]" for network-external requests
# For permanent redirects, use [R=301], but note cache concerns:
# http://getluky.net/2010/12/14/301-redirects-cannot-be-undon/
#
RewriteCond %{REMOTE_ADDR} !^10\.2\.
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteCond %{REQUEST_URI} ^/foo/.*$ [NC]
RewriteRule ^/foo/(.*)$ http://foo.example.com/$1 [R]

#
# Pass-Through "[PT]" to subpath URL for subdomain requests
# (Assumes that foo.example.com/foo would serve the same
# content as example.com/foo, if not for the above rule)
#
RewriteCond %{HTTP_HOST} ^foo\.example\.com [NC]
RewriteRule ^/(.*)$ /foo/$1 [PT]

使用 REMOTE_ADDR 与 10.2.xx 地址匹配的示例来自 http://httpd.apache.org/docs/2.2/rewrite/intro.html

答案2

我怀疑您必须使用“PT”,因为您的配置中其他地方有一个别名。或者非直接的 VirtualHost DocumentRoot。

无论如何,这似乎在我的测试中起到了作用:

<VirtualHost _default_:80>
    DocumentRoot /var/www/html
        RewriteEngine on

        RewriteCond %{HTTP_HOST} ^foo\.localhost [NC]
        RewriteCond %{REQUEST_URI} ^/foo/.*$ [NC]
        RewriteRule ^/foo/(.*)$ /$1 [R]

        RewriteCond %{HTTP_HOST} ^foo\.localhost [NC]   # <---
        RewriteCond %{REQUEST_URI} !^/foo/.*$ [NC]         # AND is implicit with above
        RewriteRule ^/(.*)$ /foo/index.php?q=$1 [PT]

</VirtualHost>

输出如下:

$ curl -D - foo.localhost/index.php

HTTP/1.1 200 OK
Date: Wed, 06 Nov 2013 13:46:45 GMT
Server: Apache/2.2.17 (Fedora)
Vary: Host
X-Powered-By: PHP/5.3.6
Content-Length: 55
Connection: close
Content-Type: text/html; charset=UTF-8

Host: foo.localhost
URI: /index.php
Query: q=index.php

$ curl -D - foo.localhost/foo/index.php

HTTP/1.1 302 Found
Date: Wed, 06 Nov 2013 13:46:51 GMT
Server: Apache/2.2.17 (Fedora)
Location: http://foo.localhost/index.php
Content-Length: 293
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href="http://foo.localhost/index.php">here</a>.</p>
<hr>
<address>Apache/2.2.17 (Fedora) Server at foo.localhost Port 80</address>
</body></html>

$ curl -D - foo.localhost/anything

HTTP/1.1 200 OK
Date: Wed, 06 Nov 2013 13:46:59 GMT
Server: Apache/2.2.17 (Fedora)
Vary: Host
X-Powered-By: PHP/5.3.6
Content-Length: 53
Connection: close
Content-Type: text/html; charset=UTF-8

Host: foo.localhost
URI: /anything
Query: q=anything

$ curl -D - foo.localhost/foo/anything

HTTP/1.1 302 Found
Date: Wed, 06 Nov 2013 13:47:04 GMT
Server: Apache/2.2.17 (Fedora)
Location: http://foo.localhost/anything
Content-Length: 292
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href="http://foo.localhost/anything">here</a>.</p>
<hr>
<address>Apache/2.2.17 (Fedora) Server at foo.localhost Port 80</address>
</body></html>

相关内容