Forum Moderators: phranque
I have multiple css files in different locations, these include duplicates.
Current request pattern
/first/app/folder/shared/one.css
/second/app/folder/shared/one.css
/third/some/two.css
/fourth/some/folder/two.css
I am consolidating these into a single folder, until the code that refers to these are fixed, with mod_rewrite to the following folder
/central/css/one.css
/central/css/two.css
With /central/css being the only folder where all .css files will be kept.
Here's what I have so far.
RewriteCond %{REQUEST_URI} !^/central
RewriteRule ^(([^/]+/)*[^.]+\.(css))$ central/css$1 [P]
This results in a 404 because rewriteengine creates following url
/central/css/first/app/folder/shared/one.css instead of my desired /central/css/one.css
1. I haven't been able to figureout how to strip out the path information from the request_uri and use only the basename in the rule.
2. I don't want the rewrite engine to evaluate requests that come for /central (and hence the rewritecond that I put in with a !^/central), but it doesn't seem to take effect.
Any help is much appreciated.
Thanks
But the basic problem is that you back-reference $1, and $1 is that part of the URL-path matching the pattern contained in the outermost set of parentheses. The third nested set of parentheses isn't even required. So, your regular-expressions pattern is wrong.
For use in your top-level .htaccess file, I'd suggest:
RewriteCond %{REQUEST_URI} !^/central/
RewriteRule ^([^/]+/)*([^.]+\.css)$ central/css/$2 [L]
Jim
I had the proxy in there, so the browser does not get redirected to the new URI. I wasn't sure L would achieve the same result.
Am not using the .htaccess, instead directly modifying http.conf file, as am testing this locally.
I tried what you have suggested and mod_rewrite seems to be behaving the same way as the first rule. $2 seems to have the same effect. I did try to look up what and how $1, $2 and backreferenceing worked; and obviously haven't been able to get it yet.
Based on what you say, each paranthesis refers to VAR so
(path)(filename.css) and $2 would refer to filename. I guess I need to work further on the regex. Following are the mod_rewrite debug log
127.0.0.1 - - [10/Jul/2009:17:50:11 --0400] [localhost/sid#583148][rid#632cd0/initial] (2) init rewrite engine with requested uri /firstapp/shared/one.css
127.0.0.1 - - [10/Jul/2009:17:50:11 --0400] [localhost/sid#583148][rid#632cd0/initial] (3) applying pattern 'old.html' to uri '/firstapp/shared/one.css'
127.0.0.1 - - [10/Jul/2009:17:50:11 --0400] [localhost/sid#583148][rid#632cd0/initial] (3) applying pattern '^([^/]+/)*([^.]+\.css)$' to uri '/firstapp/shared/one.css'
127.0.0.1 - - [10/Jul/2009:17:50:11 --0400] [localhost/sid#583148][rid#632cd0/initial] (2) rewrite '/firstapp/shared/one.css' -> 'central/css//firstapp/shared/one.css'
127.0.0.1 - - [10/Jul/2009:17:50:11 --0400] [localhost/sid#583148][rid#632cd0/initial] (2) local path result: central/css//firstapp/shared/one.css
On the browser I get a HTTP 400 Bad Request response code.
Thanks,
RewriteCond %{REQUEST_URI} !^/central/
RewriteRule [b]^/([/b][^/]+/)*([^.]+\.css)$ central/css/$2 [L]
Many thanks for this. I have the rewrite rule as the last entry in the httpd.conf. I did not move them into a <Directory>, yet the change you suggested resolved the issue. Is there a benefit to move it into a <Directory> section within the conf?
I had to make one minor update, to include a preceding /
Following is working code
RewriteCond %{REQUEST_URI} !^/central/
RewriteRule ^/([^/]+/)*([^.]+\.css)$ /central/css/$2 [L]
Thanks again.
I've landed a different problem now. I moved the rewrite config from my windows desktop webserver (apache2.2) to a Linux RH4 Apache2.0.55 and mod_rewrite wont load (writes nothing to the rewrite log).
I read through all the posts that I could find in the forum here and tried the load order (tried putting it at the top, at the bottom etc); nothing seems to turn on the rewrite module. following is my current loadmodules on linux
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule access_module modules/mod_access.so
LoadModule file_cache_module modules/mod_file_cache.so
LoadModule cache_module modules/mod_cache.so
LoadModule disk_cache_module modules/mod_disk_cache.so
LoadModule mem_cache_module modules/mod_mem_cache.so
LoadModule include_module modules/mod_include.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule mime_magic_module modules/mod_mime_magic.so
LoadModule expires_module modules/mod_expires.so
LoadModule headers_module modules/mod_headers.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule mime_module modules/mod_mime.so
LoadModule dir_module modules/mod_dir.so
LoadModule alias_module modules/mod_alias.so
LoadModule bscookie_module modules/mod_bscookie.so
#LoadModule cgi_module modules/mod_cgi.so
LoadModule deflate_module modules/mod_deflate.so
LoadModule ext_filter_module modules/mod_ext_filter.so
when I try any /any/folder/something.css file, apache keeps looking in the <document root>/any/folder/something.css for the file, instead of rewrite internally routing it /central/css/something.css.
I even tried moving the rewrite into a <Directory> entry and no help. 0 log entries in the rewrite log.
your help is much appreciated.
Thanks,
Sorry. I did not realize that the httpd.conf on the server was messy. There were multiple <Directory> entries. The very first one in the httpd.conf had the following
<Directory />
Options None
AllowOverride None
Allow from none
</Directory>
I changed this to the following and it started working. I am now getting detailed logs in my rewrite log.
<Directory />
# Options None
AllowOverride None
Allow from none
###### - Added for rewriting style sheets from a local folder
###### - Local folder is .. central/css/
Options +FollowSymLinks
Options +Indexes
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/central/
RewriteRule ^/([^/]+/)*([^.]+\.css)$ /central/css/$2 [L]
###### - End of rewrite
</Directory>
Thanks again for pointing out the options config. I'll ensure I post the URL and error log entry in future posts.
Am a newbie to mod_rewrite and have been resisting my tempation to call you God.
See the documentation on how Options are merged for more info.
I'm no god or guru -- I've just written far more bad code than you... ;)
Jim
The server move has created a new set of problems : ). New issue being, applications which are proxypassed (which are 90% of them) are not benefitting from this rewriterule.
/second/app/folder/shared/one.css
/third/some/two.css
/second and /third proxypassed to other hosts with the following entry
<IfModule mod_proxy.c>
ProxyRequests off
ProxyVia on
SSLProxyEngine on
<Directory proxy:*>
Order deny,allow
Deny from none
Allow from *
</Directory>
ProxyPass /second/ [secondapp.domain.com:2180...]
ProxyPassReverse /second/ [secondapp.domain.com:2180...]
ProxyPass /third/ [thirdapp.domain.com:2180...]
ProxyPassReverse /third/ [thirdapp.domain.com:2180...]
</ifModule>
I am guessing that if I can have mod_rewrite processing supercede mod_proxy, then *css would be picked up by mod_rewrite and wouldn't get to mod_proxy for those requests. Been unsuccessful in trying to do this so far.
Another option is I could use mod_rewrite for proxying requests to secondapp.domain.com and thirdapp.domain.com. But am not sure how to write this combination; will work on it and post the code.
Are there any other option, where I can exclusively proxypass non-css requests only. Thanks.
After much research into ProxyPassMatch, I gave up as I couldn't get the exclusion to work. Instead I got it to work with ProxyPass and mod_rewrite. Essentially removed all modules except mod_rewrite and mod_proxy, by placing the mod_rewrite directives before proxypass, I am able to get mod_rewrite to pickup the css processing, while mod_proxy handles everything else.
Here's the full config
Options +FollowSymLinks
Options +Indexes
RewriteEngine on
RewriteLog "logs/http-apache_rewrite.log"
RewriteLogLevel 3
RewriteCond %{REQUEST_URI} !^/central/
RewriteRule ^/([^/]+/)*([^.]+)(one\.css¦two\.css)$ /central/css/$3 [L]
<IfModule mod_proxy.c>
ProxyPass /second/ [secondapp.domain.com:2180...]
ProxyPassReverse /second/ [secondapp.domain.com:2180...]
ProxyPass /third/ [thirdapp.domain.com:2180...]
ProxyPassReverse /third/ [thirdapp.domain.com:2180...]
</IfModule>
Thanks,