apache根据是否存在多个文件之一重定向到不同的目标

时间:2015-04-20 21:15:24

标签: apache .htaccess mod-rewrite redirect

我有一个静态网站(由Apache提供),可以下载软件包。这些包首先出现在网站的“开发”部分,然后在某些时候它们也可以在“发布”部分中找到。这些包可以存在于几个“存储库”中的一个中,但每个包保证在所有存储库中具有唯一的名称。假设我的存储库名称是repos1,repos2和repos3。

所以目前我有这样的网址:

/packages/release/repos1/html/mypkg.html
/packages/devel/repos1/html/mypkg.html

我想设置重定向,以便用户可以访问:

/packages/mypkg/

...并且重写规则将尝试以下所有URL并重定向到存在的第一个URL(如果没有,则重定向到404页面)。因此对于请求/packages/mypkg/

/packages/release/repos1/html/mypkg.html
/packages/release/repos2/html/mypkg.html
/packages/release/repos3/html/mypkg.html
/packages/devel/repos1/html/mypkg.html
/packages/devel/repos2/html/mypkg.html
/packages/devel/repos3/html/mypkg.html

我不清楚如何使用mod_rewrite执行此操作。我知道有一个特殊的RewriteCond模式-f,但在我可以使用它之前,我必须以这样的方式处理REQUEST_FILENAME,以便我可以用反向引用解析包名。

只是为了让事情变得更复杂,如果用户知道他们是否正在寻找我想要尊重的版本或开发包,那么/packages/devel/mypkg/应该重定向到/packages/devel/X/html/mypkg.html X是Apache找到该文件的第一个存储库。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

使用 mod_rewrite 进行此操作并不优雅。

无论如何,您可以将此代码放在/packages/.htaccess

Options -Indexes

RewriteEngine On
RewriteBase /packages/

################################################################################
# /packages/release/xxx or /packages/devel/xxx are internally rewritten to
# /packages/release/reposX/html/xxx.html or /packages/devel/reposX/html/xxx.html
# Note: (reposX) X is the first repos where xxx is found
################################################################################
RewriteCond %{DOCUMENT_ROOT}/packages/$1/repos1/html/$2\.html -f
RewriteRule ^(release|devel)/([^/]+)/$ $1/repos1/html/$2.html [L]

RewriteCond %{DOCUMENT_ROOT}/packages/$1/repos2/html/$2\.html -f
RewriteRule ^(release|devel)/([^/]+)/$ $1/repos2/html/$2.html [L]

RewriteCond %{DOCUMENT_ROOT}/packages/$1/repos3/html/$2\.html -f
RewriteRule ^(release|devel)/([^/]+)/$ $1/repos3/html/$2.html [L]

################################################################################
# /packages/xxx is internally rewritten to
# /packages/release/reposX/html/xxx.html or /packages/devel/reposX/html/xxx.html
# Note: all release repos are fetch first, then devel ones
#      (reposX) X is the first repos where xxx is found
################################################################################
RewriteCond %{DOCUMENT_ROOT}/packages/release/repos1/html/$1\.html -f
RewriteRule ^([^/]+)/$ release/repos1/html/$1.html [L]

RewriteCond %{DOCUMENT_ROOT}/packages/release/repos2/html/$1\.html -f
RewriteRule ^([^/]+)/$ release/repos2/html/$1.html [L]

RewriteCond %{DOCUMENT_ROOT}/packages/release/repos3/html/$1\.html -f
RewriteRule ^([^/]+)/$ release/repos3/html/$1.html [L]

RewriteCond %{DOCUMENT_ROOT}/packages/devel/repos1/html/$1\.html -f
RewriteRule ^([^/]+)/$ devel/repos1/html/$1.html [L]

RewriteCond %{DOCUMENT_ROOT}/packages/devel/repos2/html/$1\.html -f
RewriteRule ^([^/]+)/$ devel/repos2/html/$1.html [L]

RewriteCond %{DOCUMENT_ROOT}/packages/devel/repos3/html/$1\.html -f
RewriteRule ^([^/]+)/$ devel/repos3/html/$1.html [L]