homepage Welcome to WebmasterWorld Guest from 23.22.194.120
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member

Visit PubCon.com
Home / Forums Index / Code, Content, and Presentation / Apache Web Server
Forum Library, Charter, Moderators: Ocean10000 & incrediBILL & phranque

Apache Web Server Forum

    
Don't understand RewriteBase /
Should I be using it?
Patrick Taylor




msg:4650299
 9:58 am on Mar 1, 2014 (gmt 0)

I am using a home grown CMS for websites that can run in the web root / or in a subfolder (eg: /blah/). The .htaccess file is located where the website is located, i.e. in / or /blah/ - and it is written according to where it is. Examples below.

My question:
-----------------------------

RewriteBase / is not currently used and everything is working okay - on my servers anyway - but I'm wondering if it should be included? It doesn't seem to make any difference either way but I'd like to understand which is technically correct (I have read and do not understand the Apache documentation, in my context at least).

-----------------------------

The context:

(1) In root folder /

The principles:

ADDRESS: example.com/
SERVER: example.com/cms/index.php

ADDRESS: example.com/string
SERVER: example.com/cms/string.php

ADDRESS: example.com/cms/admin/string.php
SERVER: example.com/cms/admin/string.php [no change]

ADDRESS: example.com/cms/admin/index.php?page=string
SERVER: example.com/cms/admin/index.php?page=string [no change]

.htaccess:
-----------------------------

AddDefaultCharset UTF-8

Options +FollowSymLinks
RewriteEngine on

ErrorDocument 404 /error404.php

RewriteCond %{REQUEST_URI} ^/cms/inc/menu\.php$ [OR]
RewriteCond %{REQUEST_URI} ^/cms/inc/inmenu\.txt$ [OR]
RewriteCond %{REQUEST_URI} ^/cms/admin/list\.php$ [OR]
RewriteCond %{REQUEST_URI} ^/cms/([A-Za-z0-9_-]+)\.txt$ [OR]
RewriteCond %{REQUEST_URI} ^/cms/comments/([A-Za-z0-9_-]+)\.txt$ [OR]
RewriteCond %{REQUEST_URI} ^/img/$
RewriteRule .* - [F]

RewriteCond %{REQUEST_URI} ^/cms/$
RewriteRule ^cms/$ / [R=301,L]

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /cms/([A-Za-z0-9_-]+)\.php\ HTTP/
RewriteRule ^cms/([A-Za-z0-9_-]+)\.php$ /$1 [R=301,L]

RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^$ /cms/index.php [L]

RewriteCond %{REQUEST_URI} !^/index$
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([A-Za-z0-9_-]+)\ HTTP/
RewriteRule ^([A-Za-z0-9_-]+)$ /cms/$1.php [L]

-----------------------------

(2) In subfolder /blah/

The principles:

ADDRESS: example.com/blah/
SERVER: example.com/blah/cms/index.php

ADDRESS: example.com/blah/string
SERVER: example.com/blah/cms/string.php

ADDRESS: example.com/blah/cms/admin/string.php
SERVER: example.com/blah/cms/admin/string.php [no change]

ADDRESS: example.com/blah/cms/admin/index.php?page=string
SERVER: example.com/blah/cms/admin/index.php?page=string [no change]

.htaccess:
-----------------------------

AddDefaultCharset UTF-8
ErrorDocument 404 /error404.php

Options +FollowSymLinks
RewriteEngine on

RewriteCond %{REQUEST_URI} ^/blah/cms/inc/menu\.php$ [OR]
RewriteCond %{REQUEST_URI} ^/blah/cms/inc/inmenu\.txt$ [OR]
RewriteCond %{REQUEST_URI} ^/blah/cms/admin/list\.php$ [OR]
RewriteCond %{REQUEST_URI} ^/blah/cms/([A-Za-z0-9_-]+)\.txt$ [OR]
RewriteCond %{REQUEST_URI} ^/blah/cms/comments/([A-Za-z0-9_-]+)\.txt$ [OR]
RewriteCond %{REQUEST_URI} ^/blah/img/$
RewriteRule .* - [F]

RewriteCond %{REQUEST_URI} ^/blah/cms/$
RewriteRule ^cms/$ /blah/ [R=301,L]

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /blah/cms/([A-Za-z0-9_-]+)\.php\ HTTP/
RewriteRule ^cms/([A-Za-z0-9_-]+)\.php$ /blah/$1 [R=301,L]

RewriteCond %{REQUEST_URI} ^/blah/$
RewriteRule ^$ /blah/cms/index.php [L]

RewriteCond %{REQUEST_URI} !^/blah/index$
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /blah/([A-Za-z0-9_-]+)\ HTTP/
RewriteRule ^([A-Za-z0-9_-]+)$ /blah/cms/$1.php [L]

-----------------------------

 

lucy24




msg:4650305
 11:06 am on Mar 1, 2014 (gmt 0)

You are doing fine.

#1. The default RewriteBase is / (root).

#2. The RewriteBase is only applied when the target of a rewrite begins* in a naked directory name-- no protocol-plus-domain, and no / slash meaning "root". If you are careful, this will never happen. Your own quoted rules illustrate the point :)

So you don't need it-- and if you did need it, the server default is the same thing you would have said yourself.

The / in the target always means root, no matter where the htaccess file is located. The part that makes a difference is the pattern, because that's relative to the current directory.

As long as we're here...
RewriteCond %{REQUEST_URI} ^/cms/inc/menu\.php$ [OR]
RewriteCond %{REQUEST_URI} ^/cms/inc/inmenu\.txt$

Or, as it were,
RewriteCond %{REQUEST_URI} ^/cms/inc/(menu\.php|inmenu\.txt$)
But I suspect you could apply some subdirectory-wide lockouts here.

Do you have two concurrent htaccess files along the same path, both with mod_rewrite? Or are those just the two hypothetical forms? Overall it looks very clean, but don't quote me, because it's late and I'm tired :(


* Every single time I say this, I have to hastily edit because my brain insists on saying "ends" instead.

Patrick Taylor




msg:4650308
 11:43 am on Mar 1, 2014 (gmt 0)

Thanks.

Do you have two concurrent htaccess files along the same path... ?


I think that is yes. An .htaccess can be in / and /blah/ at the same time, but they are different (as in the examples) and working independently I hope. It all seems to work.

I've got a leading slash on RewriteCond ^/blah/ (eg):


RewriteCond %{REQUEST_URI} ^/blah/cms/$
RewriteRule ^cms/$ /blah/ [R=301,L]


So I don't need RewriteBase / - is that what you are saying? Otherwise I would?

eg (no leading slash on RewriteCond ^blah/):


RewriteBase /

RewriteCond %{REQUEST_URI} ^blah/cms/$
RewriteRule ^cms/$ /blah/ [R=301,L]

g1smd




msg:4650312
 12:05 pm on Mar 1, 2014 (gmt 0)

You have the rules in the right order: blocks [F], then redirects [R=301,L], then rewrites [L]. This is good. The rules that redirect should include protocol and hostname in the rule target.

If you are ever tempted to split code such that some is in the root htaccess and some is in a folder htaccess, beware that for every subfolder URL request, the root htaccess is evaluated first, then the folder htaccess. This can sometimes lead to weird operation and clashes. It is often better to put all of the rules in the root htaccess taking great care with rule order.

The RegEx pattern in each rule matches the requested URL, localised on a "per-directory" basis. The rule target points either to an external reference in the form of a URL that the browser will be suggested to make a new request for, or it points to an internally rewritten location in the server filesystem, one that is different to that suggested by the path and file part of the initial URL request.

I cannot remember the last time I used RewriteBase. It is possible that I have never used it. I prefer to spell things out in full in each rule.

Patrick Taylor




msg:4650318
 12:21 pm on Mar 1, 2014 (gmt 0)

You have the rules in the right order: blocks [F], then redirects [R=301,L], then rewrites [L]. This is good.

That is because I followed your advice a couple of years ago on this same subject/project. It being a couple of years ago I've forgotten some of the logic but it's good to know.

It is often better to put all of the rules in the root htaccess taking great care with rule order.

I can't do that unfortunately because other users may not install in the root.

lucy24




msg:4650404
 8:58 pm on Mar 1, 2014 (gmt 0)

In a RewriteCond, always start with / slash. It's only in the body of the rule that you don't start with / slash. So you've got it right and don't change anything

If you are ever tempted to split code such that some is in the root htaccess and some is in a folder htaccess, beware that for every subfolder URL request, the root htaccess is evaluated first, then the folder htaccess. This can sometimes lead to weird operation and clashes. It is often better to put all of the rules in the root htaccess taking great care with rule order.

Also and far more important: mod_rewrite is not inherited unless you expressly say
RewriteOptions inherit
every time you deploy mod_rewrite. No, this directive itself is not inherited ;)

By default, if you have two specimens of mod_rewrite along the same path, anything in the outer scope will be discarded as if it had never existed. It says so in the Apache docs somewhere; I've also personally tested it. The same applies if you have mod_rewrite inside a Files(Match) envelope even within the same htaccess. (You probably don't, because the docs tell you not to. I didn't know you're not supposed to until well after I'd got into the habit. It's convenient for some things.)

In short: If a user puts an htaccess in a non-root location, you can expect all RewriteRules in the root htaccess to be ignored for requests for the subdirectory. Requests for other subdirectories-- ones that don't contain a fresh htaccess with fresh RewriteRules-- are unaffected. This applies only to mod_rewrite.

Edit:
htaccess doesn't have to be in the subdirectory where the CMS is located. It can always be in the root. You just have to make sure it's coded appropriately, using
RewriteRule ^subdirectory/blahblah
anywhere that you currently have
RewriteRule ^blahblah
so the CMS-specific material only kicks in when it's supposed to.

Patrick Taylor




msg:4650442
 10:44 pm on Mar 1, 2014 (gmt 0)

... expect all RewriteRules in the root htaccess to be ignored for requests for the subdirectory.

That's helpful.

I have installed the cms in both the root and a subfolder and they each work independently of the other. That's what I want. Depending on where it's installed the system setup creates the .htaccess file to suit - see examples (1) and (2) in my first message.

If a user installs the cms in a subfolder and they have a completely different application and .htaccess file in the root, the subfolder cms must still work (regardless of anything else in the root or other folders).

I hope I explained that clearly. It works and I don't need to bother with RewriteBase /

I'm happy. Thanks for helping with this.

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / Apache Web Server
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved