apache rewriterule for tilda ~user folder - apache

I'm trying to get domain.com/~userX folders working without using userdir.
It works fine when the ~userX folders are in the server doc root doc folder, but there's too many and need to put them in a sub folder, ie /homepages so the best I've gotten is in .htaccess:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^~ "/homepages/%{REQUEST_URI}"
</IfModule>
Options -Indexes
With the trailing slash it works fine:
domain.com/~userX/
Without the trailing slash it automatically redirects to:
http://ddomain.com/homepages/~userX/
Which I don't want, so I thought I would turn directory slash off:
<Directory /var/www/domain/public_html>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
DirectorySlash Off
</Directory>
The trailing slash still works but without the trailing slash I now get:
Forbidden
You don't have permission to access this resource.
error log:
Cannot serve directory /var/www/domain/public_html/homepages/~userX
This is over my head, I've search for a few days and I'm really stuck :/
Any help much appreciated thanks.

1st Method:
Try:
RewriteRule ^(~[^\/]+)(?:\/(.*)|$) /homepages/$1/$2 [L]
The trailing slash is present or not, it internally redirects with the trailing slash.
Issues:
I think, if the user enters an URL with a slash in a sub-directory of the /homepage directory, it is probably not going to work.
2nd Method:
Try:
RewriteRule ^(~[^\/]+)$ /$1/ [R=302,L]
RewriteRule ^~ /homepages/%{REQUEST_URI} [L]
3rd Method:
This might work better than the first and the second solution
RewriteRule ^(~[^\/]+)(?:\/(.*)|$) /homepages/$1/$2 [PT,L]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*[^\/])$ /$1/ [L]

Related

Page 403 Forbidden for root directory for Deny from all in .htaccess

I have next .htaccess in root directory
RewriteEngine on
RewriteRule ^$ index.php [L]
Order Deny,Allow
Deny from all
<Files index.php>
Allow from all
</Files>
And get Page 403 Forbidden for www.example.com instead of www.example.com/index.php.
URL www.example.com/index.php is available.
Access to all files in the root directory is closed. These files are generated by scripts, the file names are unknown.
How to fix it?
<Files index.php>
Allow from all
</Files>
Try the following instead:
<FilesMatch "^(index\.php)?$">
Allow from all
</FilesMatch>
UPDATE: Added missed anchors!
(Although I would assume you are on Apache 2.4, so you should be using the corresponding Require directives instead of Order, Deny and Allow.)
Alternatively, replace all you existing directives with the following:
DirectoryIndex index.php
RewriteEngine On
RewriteRule !^(index\.php)?$ - [F]
This allows access to both example.com/ and example.com/index.php. To block direct access to index.php then try the following instead:
RewriteRule ^[^/]+$ - [F]
mod_dir (ie. "DirectoryIndex") is processed after mod_rewrite.
RewriteRule ^$ index.php [L]
This rule is redundant, it should be handled by DirectoryIndex instead.
UPDATE:
RewriteRule !^(index.php)?$ - [F] works, but I add RewriteRule !^(index2.php)?$ - [F] for second file index2.php and It dont work... I am getting 403 error for www.example.com/index2.php... I need access to several files
By adding another rule it would end up blocking both URLs. Since one or other rule will always be successful.
You can use regex alternation in a single rule. For example:
RewriteRule !^(index\.php|index2\.php)?$ - [F]
The same regex could be used in the <FilesMatch> container above.
Or, if you have many such exceptions, it might be more readable to have multiple conditions. For example:
RewriteCond %{REQUEST_URI} !=index.php
RewriteCond %{REQUEST_URI} !=index2.php
RewriteCond %{REQUEST_URI} !=index3.php
RewriteRule !^$ - [F]
Note, however, like your original rule, this also blocks URLs in "subdirectories", not just the root directory.

How do I get mod_rewrite to both remove file extensions and redirect certain URLs?

So I'm trying to get mod_rewrite to do a few different things, and I'm not quite there with it. I'd like to:
Remove file extensions from the URLs (in this case, .shtml)
Rewrite certain URLs like so:
/dashboard -> /ui/dashboard/index.shtml
/dashboard/ -> /ui/dashboard/index.shtml
/dashboard/list -> /ui/dashboard/list.shtml
/dashboard/list/ -> /ui/dashboard/list.shtml
/workspace -> /ui/workspace/index.shtml
/workspace/ -> /ui/workspace/index.shtml
/account/manage -> /ui/account/manage.shtml
/account/manage/ -> /ui/account/manage.shtml
Either add or remove a trailing slash ( I don't care which, as long as it's consistent)
What I currently have gets me about 90% of the way there. In my .htaccess file, I've got the following:
DirectoryIndex index.shtml index.html index.htm
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine On
RewriteBase /
# Get rid of the /ui/ in the URLs
RewriteRule ^(account|workspace|dashboard)([a-zA-Z0-9\-_\.\/]+)?$ /ui/$1$2 [NC,L]
# Add the trailing slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/|#(.*))$
RewriteRule ^(.*)$ $1/ [R=301,L]
# Remove the shtml extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.shtml -f
RewriteRule ^([^\.]+)/$ $1\.shtml
</IfModule>
Now the issues I'm running into are twofold:
First, if I try to access one of the index pages outlined in the directories listed in step 2 above, as long as I do it with a trailing slash, it's fine, but if I omit the trailing slash, the URL rewrites incorrectly (the page still loads, however). For example
/dashboard/ remains /dashboard/ in the address bar.
/dashboard rewrites to /ui/dashboard/ in the address bar.
How can I get these index.shtml pages to keep the address bar consistent?
Second, when I try to access a page other than the directory index in one of the rewritten directories, and I include a trailing slash, it gives me a 404 error. For instance:
/dashboard/list/
throws the 404 error:
The requested URL /ui/dashboard/list.shtml/ was not found on this server.
Any help to get this working properly that you can offer is much appreciated.
So I've figured out an approach that works for what I need. Here's the .htaccess I came up with, commented inline:
# Match URLs that aren't a file
RewriteCond %{REQUEST_FILENAME} !-f
# nor a directory
RewriteCond %{REQUEST_FILENAME} !-d
# if it's the index page of the directory we want, show that and go no further
RewriteRule ^(account|workspace|dashboard)/?$ /ui/$1/index.shtml [L]
# If we've gotten here, we're dealing with something other than the directory index.
# Let's remove the trailing slash internally
# This takes care of my second issue in my original question
RewriteRule ^(.*)/$ $1 [L]
# Do the rewrite for the the non-directory-index files.
RewriteRule ^(account|workspace|dashboard)([a-zA-Z0-9\-_\.\/]+)?$ /ui/$1$2 [L]
Not sure if this is the most efficient way to do this, but it's working for my needs. Thought I'd share it here in case it helps anyone else.

apache RewriteRule requires trailing slash at the end of url to work

Ok so i have a url like
domain.com/item/item_id/item_description/page
when i type the link without
/page
on the url it throws a 404 error and i have to type the trailing slash on the url to make it work..
this is my htaccess code
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^item/([0-9]+)/(.*)/(.*)/?$ item.php?action=item&id=$1&desc=$2&page=$3
i have found this after searching:
# add trailing slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^.*[^/]$ /$0/ [L,R=301]
which kinda solves my problem but how can i make the trailing slash to be optional by the user if the user wants to add it or not so it wont redirect everytime a slash is not found
You can handle the request using one rewriterule.
RewriteRule ^item(?:\.php)/([0-9]+)/([^/]+)?/?([^/]+)?/?$ item.php?action=item&id=$1&desc=$2&page=$3 [L]
Please note I have added (?:\.php) before ^item, just to be sure this rewriterule works, if your webserver for some reason convert request
domain.com/item/...
into
domain.com/item.php/...
Tip: you can see your current rewriterule behavior enabling RewriteLog:
RewriteLogLevel 9
RewriteLog "/var/log/apache2/dummy-host.example.com-rewrite_log"
Be careful do not use this in production.
Use two rewrite rules (one with and one without "page"):
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^item/([0-9]+)/(.*)/?$ item.php?action=item&id=$1&desc=$2
RewriteRule ^item/([0-9]+)/(.*)/(.*)/?$ item.php?action=item&id=$1&desc=$2&page=$3

.htaccess RewriteRule adds drive path to URL

I am using Zend Server CE (v.5.1.0) installed on C: on a Win7 machine. I have added one project to httpd.conf by adding:
Alias /project "D:\Homepages\project"
<Directory "D:\Homepages\project">
Options Indexes FollowSymLinks
AllowOverride all
Order allow,deny
Allow from all
</Directory>
My .htaccess file in the project directory contains the following:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_URI} ^/\w*\.(css|js) [NC]
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
Now to the problem; if I go to
http://localhost/project/index.php
everything seems to be working fine. I reach the index.php file and get my contents.
However, if I go to any other page that would trigger the RewriteRule, it seems to be adding the directory path. FireFox outputs the following Not Found message:
The requested URL /Homepages/project/index.php was not found on this server.
I tried to find a similar question/answer here, but failed. Any idea?
Ps. Me accepting of an answer might be delayed as I will be out for a while on an errand.
You need to set the RewriteBase directive; otherwise, mod_rewrite automatically, and by default, prepends the file path to the resulting rewrite rule.
From: http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html
When a substitution occurs for a new URL, this module has to re-inject the URL into the server processing. To be able to do this it needs to know what the corresponding URL-prefix or URL-base is. By default this prefix is the corresponding filepath itself. However, for most websites, URLs are NOT directly related to physical filename paths, so this assumption will often be wrong! Therefore, you can use the RewriteBase directive to specify the correct URL-prefix.
If your webserver's URLs are not directly related to physical file paths, you will need to use RewriteBase in every .htaccess file where you want to use RewriteRule directives.
Have your last line like this:
RewriteRule ^.*$ /index.php [NC,L]
However I think this is infinite loop so I would suggest this rule instead:
RewriteCond %{THE_REQUEST} !\s/index.php [NC]
RewriteCond %{REQUEST_URI} !^/index.php [NC]
RewriteRule . /index.php [L]
which prevents going to index.php if it is already /index.php.

Trailing slashes problem

When I type this "http://example.com/Hello%20There/" , it displays the
index page wich is : "http://example.com/Hello%20There/index.html" .
Well, what I want to do is when the user types "http://example.com/Hello%20There"
(so like the first one except it doesn't have a trailing slash).
I tried many things and specially regular expressions, but nothing works because I think
that the server stops the reg exp process when he finds a space ("%20" in the URL).
I tried this reg exp:
Options +FollowSymLinks
rewriteEngine On rewriteCond %{REQUEST_URI} ^(.*)\ (.*html)$
rewriteRule ^.*$ %1-%2 [E=space_replacer:%1-%2]
rewriteCond %{ENV:space_replacer}!^$
rewriteCond %{ENV:space_replacer}!^.*\ .*$
rewriteRule ^.*$ %{ENV:space_replacer} [R=301,L]
and also put:
DirectorySlash On
in the "mod_dir" module of Apache.
So, my question is:
- How to tell to the server to add a trailing slash when the user types an url
without a trailing slash;$
You can make a character optional by appending the ? quantifier to it like this:
RewriteRule ^([^/]+)/?$ $1/index.html
Now both /foobar and /foobar/ would be rewritten to /foobar/index.html.
But it would be better if you use just one spelling, with or without the trailing slash, and redirect the other one:
# remove trailing slash
RewriteRule (.+)/$ /$1 [L,R=301]
# add trailing slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .*[^/]$ /$1/ [L,R=301]
These rules either remove or add a missing trailing slash and do a permanent redirect.
I had the same problem, but I was using mod_alias to set up a subsite. Turns out, I needed to make a second alias without the trailing slash so that it would work correctly. Looked something like this:
Alias /forum/ "/var/www/forum"
Alias /forum "/var/www/forum"
<Directory "/var/www/forum">
Options FollowSymlinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
In Ubuntu, I had to edit the /etc/apache2/mods-enabled/alias.conf file with these lines, then restart apache. Couldn't find this answer anywhere on the web; I just stumbled onto it myself as mod_rewrite wasn't working and the DirectorySlash command didn't help either. I was appending a non-Drupal program as a subsite under a Drupal installation, which is what kicked off all this madness in the first place...
Don't use trailing slash to define an alias.
Both URLs http://example.com/myalias1 and http://example.com/myalias1/ would work fine.
Example:
sudo vi /etc/apache2/apache2.conf
Alias /myalias1 "/path/to/folder1"