Forum Moderators: phranque

Message Too Old, No Replies

2 re-write rules based on filename

         

digighost

1:16 pm on May 14, 2010 (gmt 0)

10+ Year Member



Hi all,

I would like to rewrite based on filenames, I am having a problem finding the correct info for this and have been trying numerous different setups - not too mention specs changing too, naturally :)

- I would like to redirect everything through admin.php
- Thus not having admin.php necessary in my url.
- However, if a user explicitly types in admin_dev.php in the url - then direct everything thru that file. (For debugging)

note: I will handle users I don't want accessing admin_dev.php within my app and redirect them back to admin.php with a filter in PHP (Only allow users I want to run thru this file)

What I have that is semi - working so far is but only allowing initial (once) access thru admin_dev.php and then all rewritten again to admin.php is:


RewriteCond %{HTTP_HOST} app.trunk
RewriteCond %{REQUEST_FILENAME} !\.(css|js|swf)$
RewriteCond %{REQUEST_URI} !images/(.*)\.
RewriteCond %{REQUEST_URI} !js/(.*)\.
RewriteCond %{REQUEST_FILENAME} !admin_dev.php$
#RewriteCond %{HTTP_REFERER} ! admin_dev.php$
RewriteRule ^(.*)$ web/admin.php [QSA,L]


If any body could assist - it would be much appreciated! Thanks!

jdMorgan

1:56 pm on May 14, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



...only once...

HTTP is a stateless protocol; The server has no "memory" of previous requests, and each request is handled as if it is the first (and only) request the server has ever handled.

So the concept that caused you to write "What I have that is semi - working so far is but only allowing initial (once) access thru admin_dev.php and then all rewritten again to admin.php" is flawed.

The usual solution is to "create" a "memory mechanism" by setting and testing a client-side cookie. Once set, the cookie is sent to your server with every subsequent client request, thus allowing the server to "know" that "this user has been here before."

Therefore, you'll need to set the cookie based on some definitive "start" condition, and possibly reset it (overwrite it) based on some definitive "end" condition. This is the same concept as "session cookies," if that helps you understand it a bit better.

You can set and read cookies in mod_rewrite on Apache 2.x, and read cookies only in Apache 1.x. You can also set and read cookies in scripts regardless of server version.

[added] Once you set a cookie you should test it immediately, and serve an error notice if it is not set. This will prevent massive confusion among the (admittedly-few) visitors who have cookies disabled in their browsers. [/added]

Jim

digighost

2:22 pm on May 14, 2010 (gmt 0)

10+ Year Member



Thanks for your reply here Jim...

Sure the server has no memory so I was making a reference to perceived behavior from a human perspective - and to what I am trying to accomplish.

The reason I say it is semi-working is that my page (template) loads fine with admin_dev.php in the request but any ajax (note* the link[s] source has admin_dev.php in the url) calls are then going thru admin.php - giving the perception of allowing the initial request (thru admin_dev.php), but then rewriting thru admin.php again for the subsequent ajax calls - here i suspect my rules to be incorrect.

The application has a routing system as well, perhaps my issues are coming from that - but I suspect it to be the .htaccess. I am investigating the the local routing as we speak.

However;

Can anybody help me setting up a rule(s) that will rewrite everything through admin.php
EXCEPT
If the filename admin_dev.php exists in the request, if so rewrite thru admin_dev.php

This will make my testing a lot easier to know that at least my rewriting rules are correct (which I am uncertain of at the moment) - thanks again..!

Thanks

jdMorgan

7:27 pm on May 14, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Cleaning that up a bit, we get:

RewriteCond %{HTTP_HOST} ^([^.]+\.)*app\.trunk\.?(:[0-9]+)?$
RewriteCond $1 !^(images|js)/[^.]*\.
RewriteCond $1 !\.(css|js|swf)$
RewriteCond $1 !^admin_dev\.php$
RewriteRule ^(.*)$ admin.php [L]

Note that I made the references to "admin_dev.php" and "admin.php" consistent. If either or both are in "/web", then this may not be correct. If this .htaccess code is in /web/.htaccess, then this code is not correct.

I made your HTTP_Host pattern much more specific, so it that cannot be 'spoofed' by using a subdomain like app.trunk.<anything-else>.example.com, for example. You may or may not want to make it case-insensitive by adding an [NC] flag. (Actually, you should have rules already in place ahead of this internal rewrite rule that externally redirect all non-canonical hostname requests to their respective canonical hostnames. If so, then you can use an exact match here, instead leaving the pattern un-anchored as in your original.

I combined and moved the "exclude directory" RewriteConds above the "exclude filetypes" RewriteCond, on the assumption that if most images and JS files are in those two directories, then there no need to check the filetype, and so a small gain in efficiency can be realized.

I also anchored all of these RewriteCond patterns as possible and escaped the literal periods, again for efficiency.

I removed your HTTP_REFERER RewriteCond. This is likely the crux of the problem, in that the HTTP Referer header is utterly unreliable. It will not be sent if the URL is typed in directly, accessed from a bookmark, accessed by a search engine robot, or accessed through any type of corporate or network proxy (e.g. AOL, EarthLink, etc.), and it will not be sent if the access is invoked by JavaScript. Therefore, it may be blank just when you need it the most...

Aside from my assumptions about the current and root directory loactions as implied by the start-anchors I added and the paths I adjusted, this code should work.

If not, then the whole concept fails, and you will need to do something else. For example, add something/anything to the URLs requested by your AJAX so that they can be identified and disposed properly. This could be an alternate directory-path, a modified "filename" or "filetype," or a query string appended to the URL in order to identify it as a "not-to-be-rewritten" request.

Note the space between "!" and "admin_dev.php$" in the code you posted. If that was not a typo or copy-and-paste error, then it was a syntax error in the code and it should have caused a 500-Server Error. But if it didn't, then perhaps that's why your exclusion failed...

The [QSA] flag (Query String Append) is only needed if you want to *add* something to an existing query string. Otherwise, it's a waste of time and bytes.

Jim