Forum Moderators: phranque

Message Too Old, No Replies

mod rewrite help please!

Rewrite from top level to a subdirectory

         

wemail

7:49 pm on May 24, 2008 (gmt 0)

10+ Year Member



I have a site on a cPanel/WHM server structured so that URL

http://example.com/main/page.html

results in loading the page

/home/site/public_html/main/page.html

However the "main" directory has only recently been inserted into the structure to segregate the files in and below it from lots of other files in another area. The /main files are really top-level files, but must be kept separate for edit-access purposes.

So, to access .../main/page.html I need to rewrite all requests for the top-level URL (and any levels below it except main) from

http://example.com/page.html

to get the newly-situated file at

http://example.com/main/page.html

I have seen documentation describing "rewrite URL to subdirectory", but I can't get the suggested rule to work. It is probably due to me misunderstanding something cPanel has put somewhere, but I am not sure. I currently have my .htaccess file at

/home/site/public_html/.htaccess

I expected that I might have recursion problems, but that doesn't seem to happen.

Any ideas would be much appreciated.

Thanks

[edited by: jdMorgan at 11:29 pm (utc) on May 24, 2008]
[edit reason] use example.com, no sigs, please. [/edit]

jdMorgan

11:28 pm on May 24, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



> but I can't get the suggested rule to work.

Please post your best-effort [webmasterworld.com] code, and let us know where you're putting it -- httpd.conf, conf.d, .htaccess etc.

Thanks,
Jim

wemail

1:44 pm on May 26, 2008 (gmt 0)

10+ Year Member



Thanks. I currently have this - in .htaccess:

RewriteEngine on

# Force index if homepage
RewriteRule ^/$ http://example.com/main/index.html [R=302,L]

# Check for file at subdirectory level, if present exit:
RewriteCond main/%{REQUEST_FILENAME} -f
RewriteRule ^(.+) $1 [L]

# If it wasn't, rewrite to subdirectory
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+) http://example.com/main/$1 [R=302,L]

It seems to work if the URL includes an actual filename, but a request for the homepage does not load http://example.com/main/index.html as would be expected from the first rule. I presume this because the default filename is in some way conflicting with mod rewrite (or I misunderstood the "processing sequence" information). One gets the home directory listing.

If the file does not exist, it loops adding /main multiple times.

Also, it is rewriting the browser URL, which I want to avoid - I seem to have confusing documentation about rewrite as opposed to redirect!

I am still experimenting, but I had thought this was a pretty standard need.

jdMorgan

3:36 pm on May 26, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Yes, I believe you want internal rewrites, but your code implemented external redirects.

Your first rule: In .htaccess, the path to the current directory is stripped from the URL-path seen by RewriteRule. This is because .htaccess is a per-directory configuration, so all paths are "localized" to the current directory. In practical terms here, this means that the leading slash will not be present on URL-paths examined by RewriteRule in example.com/.htaccess

Your second rule: From what I can tell, this rule was redundant, since the "file exists" check is also done by your third rule. I removed your second rule, because "file exists" checks are CPU intensive, and may require an actual read of the file-directory information from the disk, which is *very* slow.

Your third rule: In .htaccess, you must explicitly prevent looping. I added a check to be sure we had not already rewritten the request to the /main subdirectory. Note that this check is done before the "file exists" check, to prevent that "exists" check from wasting time/CPU if it's not necessary (for the reasons stated above).


# Internally rewrite to index file if homepage URL-path requested
RewriteRule ^$ /main/index.html [L]
#
# If not already rewritten to subdirectory, and requested URL-path does not resolve
# to an existing file, internally rewrite the request to the /main subdirectory
RewriteCond $1 !^main/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ /main/$1 [L]

Jim

wemail

8:16 am on May 27, 2008 (gmt 0)

10+ Year Member



Many thanks, Jim. I now feel better equipped to do some more complex stuff, but I still find the official mod rewrite documentation a bit difficult to follow. As somebody said elsewhere on the forum, maybe it needs a book on it!

Cheers.

g1smd

9:48 am on May 27, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The 302 redirects were the worst possible things to do. I can see why you did them though.

A 301 redirect would have been better, but you really don't want or need for the user to see the "/main/" in the URL. That's internal implementation stuff that the user does not need to see.

The rewrite is the best thing. It silently connects an external URL request to a different internal filepath.