Apache的重定向基于符号链接 [英] Apache redirects based on symlinks

查看:120
本文介绍了Apache的重定向基于符号链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个应用程序,一些公众形象资源符号链接,为历史原因替代名称。例如,我们可能有

In one app, some public image resources are symlinked to alternative names for historic reasons. For example, we might have

a.png
b.png -> a.png

谷歌的的PageSpeed​​洞察了相同的内容应该一致的URL送达适用于这样的资产,以及内容。而不是重新组织我们已有的资产,我想有阿帕奇从b.png到a.png执行外部重定向。

Google's PageSpeed Insight that identical content should be served from a consistent URL applies to assets like this as well as content. Rather than reorganising the assets we have in place, I would like to have Apache perform an external redirect from b.png to a.png.

使用mod_rewrite的,我可以做的RewriteCond缩小在符号链接:

With mod_rewrite I can make a RewriteCond to narrow in on symbolic links:

- L'(是符号链接)
  将TestString视为一个路径名,以及是否存在的测试,并且是一个符号链接。

'-l' (is symbolic link) Treats the TestString as a pathname and tests whether or not it exists, and is a symbolic link.

但我怎么能得到符号链接的扩张路径?我需要它部分地,以确保目标是在网络范围,部分原因是为了执行重定向。

But how can I get the expanded path of the symlink? I need it partly to ensure that the target is in web scope, and partly to perform the redirect.

推荐答案

(第张贴在这里)

我一直在寻找一个解决类似的问题。这是可能的,但没有简单的答案。我不得不混合来自多个谷歌搜索,使其工作信息。

I've been looking for a solution to a similar problem. It's possible, but there is no easy answer. I had to mix info from multiple Google searches to make it work.

首先,关于符号链接说明(维基):

First of all, a note about symlinks (wiki):

符号链接由文件系统自动解决。任何
  软件程序,在访问一个符号链接,将会看到目标
  相反,程序是否意识到符号链接与否。

Symbolic links are automatically resolved by the file system. Any software program, upon accessing a symbolic link, will see the target instead, whether the program is aware of symbolic links or not.

所以,除非开发者阿帕奇添加特定的选项来处理符号链接(如 -l <​​/ code>你mentionned),我们不得不依靠其他的意思是妥善解决这些问题。

So, unless the apache devs add specific options to deal with symlinks (like the -l you mentionned), we have to rely on another mean to properly resolve them.

的mod_rewrite 具有的 RewriteMap指令 配置选项。有了它,你可以使用不同类型的外部资源来进行重写,如文本文件或数据库查询。它也可以调用外部程序,如...一个符号链接解析器例如:)

mod_rewrite has the RewriteMap configuration option. With it, you can use different types of external resources to perform the rewriting, such as text files or DB queries. It can also call external programs, such as ... a symlink resolver for example :)

所以,在这里我们去。所有运行下面的命令为根,适应你的系统设置(这是Debian)。



首先,如果我们使用 RewriteMap指令选项,我们还需要的 RewriteLock 选项,以prevent竞争条件。在 RewriteLock 选项不能在一个&LT;虚拟主机&GT; &LT;目录&GT; 上下文。它是在全球范围内,所以我增加了它在一个新的 rewrite.conf 并重新加载的模块。
运行以下命令:

So, here we go. Run all the following commands as root and adapt to your system settings (this is for Debian).


First, if we use the RewriteMap option, we also need the RewriteLock option to prevent race conditions. The RewriteLock option can't be in a <VirtualHost> or <Directory> context. It has to be in the global context, so I added it in a new rewrite.conf and reloaded the module. Run the following:

lock=/var/lock/apache2/rewrite_lock
touch $lock
chown www-data:www-data $lock
echo "RewriteLock $lock" >> /etc/apache2/mods-available/rewrite.conf
a2dismod rewrite
a2enmod rewrite

接下来,创建的/ usr / local / bin目录/决心,符号链接并添加下列code:

#!/bin/sh
while read line
do
    echo `readlink "$line"`
done

使其可执行文件,并测试它作为Apache的:

Make it executable and test it as apache:

chmod +x /usr/local/bin/resolve-symlink
su - www-data
/usr/local/bin/resolve-symlink

该脚本应等待你的输入,那么要么返回一个空行或指定的符号链接的目标。使用 CTRL + C 退出。示例(&GT; 是STDIN,&LT; 是STDOUT):

The script should wait for your input, then either return a blank line or the target of the given symlink. Use CTRL+C to exit. Example (> is STDIN, < is STDOUT):

> test
<
> /bin/sh
< bash
> /bin/bash
<

测试不存在,所以会返回一个空行。 / bin / sh的是一个符号链接和脚本它解析为庆典。最后, /斌/庆典是一个文件,而不是一个链接,从而另一个空行。

test doesn't exist, so a blank line is returned. /bin/sh is a symlink and the script resolved it to bash. Finally, /bin/bash is a file and not a link, thus another blank line.

现在,在你的&LT;虚拟主机&GT; 配置,加上下面几行:

Now, in your <VirtualHost> configuration, add the following lines:

RewriteEngine On
RewriteMap symlink prg:/usr/local/bin/resolve-symlink
RewriteLog /var/log/apache2/rewrite.log
RewriteLogLevel 9

RewriteMap指令不能在&LT;目录&GT; 的背景下,并不会被激活,除非 RewriteEngine叙述也被设置为 &LT;虚拟主机&GT; 背景,即使你后来在&LT将其设置为;目录&GT; 大赛!注意所有这些特点,并仔细阅读你的日志文件,或者你可能会失去几个小时就敲打墙壁你的头不知道为什么它说:地图查找失败。

RewriteMap can't be in a <Directory> context, and won't be active unless RewriteEngine is also set to on in the <VirtualHost> context, even if you later set it to on in a <Directory> contest!!! Pay attention to all those peculiarities and read your log files carefully or you may lose a few hours banging your head on the wall wondering why it says "map lookup FAILED".

最后,重写,在任何情况下,你preFER:

Finally, the rewriting, in whatever context you prefer:

RewriteCond %{REQUEST_FILENAME} -l
RewriteCond ${symlink:%{REQUEST_FILENAME}} ^(.+)$
RewriteRule $ ${REQUEST_SCHEME}://${HTTP_HOST}/%1 [R,L]

第一行检测符号链接,第二个执行该决议,并检查结果不是空的,第三行重写URL(%1 是映射的结果)并发送302重定向到浏览器。您可能需要 END 标记而不是标记。

First line detects symlinks, second one performs the resolution and checks that the results is not empty, third line rewrites the URL (%1 is the result of the mapping) and sends a 302 redirection to the browser. You may need the END flag instead of the L flag.

现在重新启动Apache ...

Now restart apache...

service apache2 restart

...测试,检查你的日志文件,调整,冲洗和重复...

... test, check your log files, tweak, rinse and repeat...

当您完成后,不要忘了删除 RewriteLog RewriteLogLevel 从你的配置指令,因为他们阿帕奇慢了很多。



重要提示即可。就我而言,符号链接都是指向同一个文件夹中的文件,所以URL重写是更容易一些。如果你的符号链接指向子目录,甚至其他地方上的文件系统,你将不得不修改脚本和配置考虑到了,但即使如此,预期可能无法正常工作,因为Apache将并不总是能够找出正确的URL发送到浏览器。例如,如果你有一个符号连接,让说, /usr/share/apache2/icons/apache_pb.png ,阿帕奇可能会重定向到 HTTP ://example.com/usr/share/apache2/icons/apache_pb.png 其中,当然,不存在...

When your are done, don't forget to remove the RewriteLog and RewriteLogLevel directives from your configuration because they slow apache down a lot.


Important note. In my case, the symlinks all points to files within the same folder, so the URL rewriting is a little easier. If your symlinks point to sub-directories, or even somewhere else on the filesystem, you will have to modify the script and the configuration to account for it, but even then it might not work as expected, as apache won't always be able to figure out the correct URL to send to the browser. For example, if you have a symlink to, let say, /usr/share/apache2/icons/apache_pb.png, apache might redirect to http://example.com/usr/share/apache2/icons/apache_pb.png which, of course, does not exists...

另外,我会添加了一些信息的链接,但我限制为2 ...无论如何,快乐调试!

Also, I would have added a few informative links but I'm limited to 2... Anyway, happy debugging!

这篇关于Apache的重定向基于符号链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆