Forum Moderators: phranque

Message Too Old, No Replies

Rewriting requests to a specific folder

rewrite css requests to common folder

         

flycatcher

8:21 pm on Jul 10, 2009 (gmt 0)

10+ Year Member



Hi,

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

jdMorgan

8:36 pm on Jul 10, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



It's not clear why you're using a proxy through-put on this rule -- that shouldn't be necessary.

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]

For more information about constructing regex patterns, see the concise tutorial cited in our Apache Forum Charter.

Jim

flycatcher

10:16 pm on Jul 10, 2009 (gmt 0)

10+ Year Member



Hi 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,

jdMorgan

2:05 am on Jul 11, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Note the double slash in the filepath. You'll need to modify the code for use in httpd.conf, unless it's enclosed in an appropriate <Directory> section, which is why I was specific about code location:

RewriteCond %{REQUEST_URI} !^/central/
RewriteRule [b]^/([/b][^/]+/)*([^.]+\.css)$ central/css/$2 [L]

Jim

flycatcher

1:57 pm on Jul 15, 2009 (gmt 0)

10+ Year Member



Hi Jim,

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.

jdMorgan

2:58 pm on Jul 15, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



My note above simply means that if you move the code into a <Directory> section in httpd.conf, you'll have to take the slashes back off.

Jim

flycatcher

9:37 pm on Jul 16, 2009 (gmt 0)

10+ Year Member



Hi Jim,

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,

jdMorgan

10:06 pm on Jul 16, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Any errors or warnings in the server error log?

You'll need RewriteEngine on and either the FollowSymLinks or SymLinksIfOwnerMatch Option in order to use mod_rewrite.

Jim

flycatcher

10:11 pm on Jul 16, 2009 (gmt 0)

10+ Year Member



Only error I see is in the error log is File does not exist
[Thu Jul 16 17:35:26 2009] [error] [client 10.27.108.98] File does not exist: /home/web/apache2/htdocs/http-dev/test.css

I have the following before the rewritecond and rewriterule
Options +FollowSymLinks
Options +Indexes

RewriteEngine on

jdMorgan

10:25 pm on Jul 16, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



When you got that error logged above, what was the URL that you requested?
(Please post the URL every time, and the filename, if an error results and an error log entry is created.)

This looks like a basic config problem so far...

Jim

flycatcher

10:45 pm on Jul 16, 2009 (gmt 0)

10+ Year Member



Hi Jim,

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.

jdMorgan

10:52 pm on Jul 16, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



In the server config, it's better to state the Options explicitly at the server level. That is, don't use Option +this -that +theother
but rather
Options this that theother

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

flycatcher

11:33 pm on Jul 16, 2009 (gmt 0)

10+ Year Member



Hi 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.

jdMorgan

4:41 am on Jul 17, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



ProxyPassMatch has a negative-match option on Apache2.x

Jim

flycatcher

6:10 pm on Jul 20, 2009 (gmt 0)

10+ Year Member



Hi Jim,

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,

jdMorgan

7:10 pm on Jul 20, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hey, that's great! I was a bit 'lost' on this, and as I'm sure you can now appreciate, it's a bit difficult to 'debug' some problems with the limited communication and 'visibilty' provided by a discussion forum environment.

Glad you got it working!

Jim