Forum Moderators: phranque

Message Too Old, No Replies

Rewrite rules problem: cookies, subdirectories

almost working, 1 exact URL fails :-(

         

nnmiller

12:47 am on Dec 29, 2007 (gmt 0)

10+ Year Member



First off, thanks for this great resource. Reading jdMorgan's and other regular poster's answers has helped me not feel entirely stumped by mod_rewrite. Unfortunately I've hit a snag which exceeds my learning thus far.

I have a typical cPanel setup with several domains, one of which has a blog that needs to be restricted due to the content. A script drops a cookie if the requirements are met, then the user can see the content. My rewrite rules a) check for the restricted cookie and b) check for the admin user cookie, allowing access the blog in either case. If neither of these cookies exist, then it redirects to the script.

What I have *almost* works. Going directly to the blog URL (e.g. http://restricted.com/blog/) avoids the cookie script redirection, but going to any other URL (e.g. http://restricted.com/blog/post1) under the blog gets redirected. I am at a loss as to how to further modify the rules to fix the problem.

Directory structure:
/www/example
/www/exampletwo
/www/restricted
/www/restricted/blog <--restricted content
/www/restricted/cookie <--contains scripts for cookie generation

/www/.htaccess:


# strip off the ^www, but not ^subdomain
RewriteCond %{HTTP_HOST} ^www\.(([a-z0-9_]+\.)?example\.com)$ [NC]
RewriteRule .? http://%1%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTP_HOST} ^www\.(([a-z0-9_]+\.)?exampletwo\.com)$ [NC]
RewriteRule .? http://%1%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTP_HOST} ^www\.(([a-z0-9_]+\.)?restricted\.com)$ [NC]
RewriteRule .? http://%1%{REQUEST_URI} [R=301,L]
# hot-linking discouragement
^http://([a-z0-9_]+)\.(example¦example2¦restricted)\.com/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://([a-z0-9_]+)\.(example¦example2¦restricted)\.com$ [NC]
RewriteRule .*\.(jpg¦jpeg¦gif¦png¦bmp)$ - [F,NC]
# restriction check
RewriteCond %{HTTP_HOST} ^.*$
# don't rewrite if the request is for the admin dir, login.php or
# the script directory
RewriteCond %{REQUEST_URI} !/admin/ [NC]
RewriteCond %{REQUEST_URI} !(.*)\/login\.php [NC]
RewriteCond %{REQUEST_URI} !/restricted/ [NC]
# If the restricted cookie doesn't exist
RewriteCond %{HTTP_COOKIE} !access=true [NC] [OR]
# or they're not logged in -- cookie only exists if logged in
RewriteCond %{HTTP_COOKIE} !admin_ [NC]
RewriteRule ^restricted/(.*)$ http://restricted.com/cookie/index.php [R=301,L]

/www/restricted/blog/.htaccess (cribbed from jdMorgan's postings on improving efficiency of blog rewrite rules):


RewriteBase /blog/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !..+$
RewriteCond %{REQUEST_URI} !/$
RewriteRule (.*) $1/
RewriteCond %{REQUEST_URI} !^/([^.]+.)*[^./]+$

I've tried removing the blog's .htaccess entirely (404 on anything but http://restricted.com/blog/) and relocating them to the root .htaccess (ditto).

Unfortunately, I don't have a way to get rewrite logs turned on. I tested on my local LAMP box and these rules worked, but my httpd.conf is IP based not name based.

Could someone please offer a clue for the mod_rewrite challenged?

Thanks in advance.

[edited by: jdMorgan at 1:08 am (utc) on Dec. 29, 2007]
[edit reason] de-linked example URLs [/edit]

jdMorgan

1:04 am on Dec 29, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I don't see how the code can work at all, since the highlighted parts of the ruleset require both that the requested URL does not start with "/restricted" and does start with "/restricted". Since these conditions are mutually-exclusive and both are required, the rule will never be invoked.

# restriction check
RewriteCond %{HTTP_HOST} ^.*$
# don't rewrite if the request is for the admin dir, login.php or
# the script directory
RewriteCond %{REQUEST_URI} !/admin/ [NC]
RewriteCond %{REQUEST_URI} !(.*)\/login\.php [NC]
[b]RewriteCond %{REQUEST_URI} !/restricted/ [NC][/b]
# If the restricted cookie doesn't exist
RewriteCond %{HTTP_COOKIE} !access=true [NC] [OR]
# or they're not logged in -- cookie only exists if logged in
RewriteCond %{HTTP_COOKIE} !admin_ [NC]
[b]RewriteRule ^restricted/[/b](.*)$ http://restricted.com/cookie/index.php [R=301,L]

There are several other minor problems with the code, but I cannot understand the intent of the method with such a glaring contradiction in place.

Jim

[edited by: jdMorgan at 1:04 am (utc) on Dec. 29, 2007]

nnmiller

1:34 am on Dec 29, 2007 (gmt 0)

10+ Year Member



Oops. That was an error caused by my trying to "genericize" the directories/domains.

It should read:


# restriction check
RewriteCond %{HTTP_HOST} ^.*$
# don't rewrite if the request is for the admin dir, login.php or
# the script directory
RewriteCond %{REQUEST_URI}!/admin/ [NC]
RewriteCond %{REQUEST_URI}!(.*)\/login\.php [NC]
RewriteCond %{REQUEST_URI}!/cookie/ [NC]
# If the restricted cookie doesn't exist
RewriteCond %{HTTP_COOKIE}!access=true [NC] [OR]
# or they're not logged in -- cookie only exists if logged in
RewriteCond %{HTTP_COOKIE}!admin_ [NC]
RewriteRule ^restricted/(.*)$ http://restricted.com/cookie/index.php [R=301,L]

I'm all ears for whatever advice you can offer on the minor errors as well--anything to learn more, please.

Thanks again.
=N=

jdMorgan

5:06 am on Dec 29, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



If you've used cPanel to map blog.example.com/ to /blog/, then this code would need to be located in /blog/.htaccess

Jim

nnmiller

6:53 am on Dec 29, 2007 (gmt 0)

10+ Year Member



That's an interaction that I hadn't thought of. However, there are no redirects within cPanel, other than those of the secondary domains (exampletwo.com and restricted.com) being "subdomains" of example.com. I.e, within the cPanel Subdomain control panel:

exampletwo.example.com (www/exampletwo)
restricted.example.com (www/restricted)

I've done some further experiments with relocating the rewrites for the restricted stuff lower than root, as well as adding a redirect via cPanel (which just seems to insert this into the root .htaccess:


RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^restricted/?$ http://restricted.com/ [R=301,L]

).

Moving the cookie checking rules down to /www/restricted/.htaccess results in access still being allowed to the direct blog url, single pages redirected properly, and the domain root with an index listing.

Unfortunately, I also discovered that if I set the cookie, posts were returning 404. I reverted the /www/restricted/blog/.htaccess to the "stock" blog rewrite rules:


RewriteBase /blog/
RewriteCond %{REQUEST_FILENAME}!-f
RewriteCond %{REQUEST_FILENAME}!-d
RewriteRule . /blog/index.php [L]

Any other suggestions?

Thanks again--
=N=

p.s. How do you prevent the "http" from identification by the post parser and being linked?

nnmiller

8:17 pm on Dec 29, 2007 (gmt 0)

10+ Year Member



In doing some more experimenting, I have found that there appears to be some kind of interaction coming from either global .htaccess rules or the global httpd.conf. I was able to cipher this out by using FFx + Live HTTP headers to see what redirects were happening.

I'm doing some more research in my host's support forums, so for the moment I think my thread is dead unless there are some cPanel guru's out there who are willing to weigh in.

I cannot wait until I get enough revenue coming in so I can pony up for a VPS with root access. :-/ Better to be hoisted by one's own sys admin petard than dangling by an ankle due to someone else's.

Thanks again--
=N=

jdMorgan

9:36 pm on Dec 29, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



OK, well here's a clean-up of the code posted above. I used regex pattern-anchoring changes to eliminate the need for several ".*" patterns, and corrected your usage of the [NC,OR] flag.

# restriction check
# don't rewrite if the request is for the admin dir, login.php or the script directory
RewriteCond %{REQUEST_URI} !^/admin/ [NC]
RewriteCond %{REQUEST_URI} !/login\.php$ [NC]
RewriteCond %{REQUEST_URI} !^/cookie/ [NC]
# If the restricted cookie doesn't exist or they're not logged in (cookie only exists if logged in)
RewriteCond %{HTTP_COOKIE} !access=true [NC,OR]
RewriteCond %{HTTP_COOKIE} !admin_ [NC]
RewriteRule ^restricted/ http://restricted.com/cookie/index.php [R=301,L]

Jim