mod rewrite - Apache redirects based on symlinks -


in 1 app, public image resources symlinked alternative names historic reasons. example, might have

a.png b.png -> a.png 

google's pagespeed insight identical content should served consistent url applies assets content. rather reorganising assets have in place, have apache perform external redirect b.png a.png.

with mod_rewrite can make rewritecond narrow in on symbolic links:

'-l' (is symbolic link) treats teststring pathname , tests whether or not exists, , symbolic link.

but how can expanded path of symlink? need partly ensure target in web scope, , partly perform redirect.

(first post here)

i've been looking solution similar problem. it's possible, there no easy answer. had mix info multiple google searches make work.

first of all, note symlinks (wiki):

symbolic links automatically resolved file system. software program, upon accessing symbolic link, see target instead, whether program aware of symbolic links or not.

so, unless apache devs add specific options deal symlinks (like -l mentionned), have rely on mean resolve them.

mod_rewrite has rewritemap configuration option. it, can use different types of external resources perform rewriting, such text files or db queries. can call external programs, such ... symlink resolver example :)

so, here go. run following commands root , adapt system settings (this debian).


first, if use rewritemap option, need rewritelock option prevent race conditions. rewritelock option can't in <virtualhost> or <directory> context. has in global context, added in new rewrite.conf , reloaded module. run 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 

next, create /usr/local/bin/resolve-symlink , add following code:

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

make executable , test apache:

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

the script should wait input, either return blank line or target of given symlink. use ctrl+c exit. example (> stdin, < stdout):

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

test doesn't exist, blank line returned. /bin/sh symlink , script resolved bash. finally, /bin/bash file , not link, blank line.

now, in <virtualhost> configuration, add following lines:

rewriteengine on rewritemap symlink prg:/usr/local/bin/resolve-symlink rewritelog /var/log/apache2/rewrite.log rewriteloglevel 9 

rewritemap can't in <directory> context, , won't active unless rewriteengine set on in <virtualhost> context, if later set on in <directory> contest!!! pay attention peculiarities , read log files or may lose few hours banging head on wall wondering why says "map lookup failed".

finally, rewriting, in whatever context prefer:

rewritecond %{request_filename} -l rewritecond ${symlink:%{request_filename}} ^(.+)$ rewriterule $ ${request_scheme}://${http_host}/%1 [r,l] 

first line detects symlinks, second 1 performs resolution , checks results not empty, third line rewrites url (%1 result of mapping) , sends 302 redirection browser. may need end flag instead of l flag.

now restart apache...

service apache2 restart 

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

when done, don't forget remove rewritelog , rewriteloglevel directives configuration because slow apache down lot.


important note. in case, symlinks points files within same folder, url rewriting little easier. if symlinks point sub-directories, or somewhere else on filesystem, have modify script , configuration account it, might not work expected, apache won't able figure out correct url send browser. example, if have symlink to, let say, /usr/share/apache2/icons/apache_pb.png, apache might redirect http://example.com/usr/share/apache2/icons/apache_pb.png which, of course, not exists...

also, have added few informative links i'm limited 2... anyway, happy debugging!


Comments

Popular posts from this blog

php - Why I am getting the Error "Commands out of sync; you can't run this command now" -

linux - Does gcc have any options to add version info in ELF binary file? -

java - Are there any classes that implement javax.persistence.Parameter<T>? -