url rewrite removing index page - apache

I'm trying to write an .htaccess file that will
a) when navigating to mysite.com/myusername (which is non existent) it will show the contents of mysite.com/dmp/temp/myusername
b) hide .php from the URL's
When going to mysite.com it however it shows me the contents of mysite.com/dmp/temp folder. If I add /index in front then it will work.
Everything is working as intended except that. How can I make sure users that simply navigate to mysite.com are served index.php (without actually writing /index/ or /index.php) and also not redirected to the /dmp/temp folder?
Code:
Options +FollowSymLinks
Options +Indexes
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %(REQUEST_URI) !^temp
RewriteRule ^(.*) dmp/temp/$1 [L]

Let's look at your two regular expressions:
^([^\.]+)$
and
^(.*)
First one: Match every query which do not contain . with length 1 or more.
Second: Match everything from length 0 or more.
So if you open http://mysite.com/ you have an empty query, and it's matched by the second regex. This means it tries to open dmp/temp/.
Try changing the second regex from ^(.*) to ^(.+). That means it will match only if you have a query of length 1 or more, and it will not match http://mysite.com/. Hopefully, you then will go to standard behaviour, showing the index.* file according to server settings (in your case index.php)

Related

Why my htaccess is not working when i upload it to ionos webspace?

I've tried in in my localhost at it worked fine but after I upload it to my ionos webspace the website index is working but after I click the content it is not directing to anywhere and there is an error message:
Error 404 not foound, Your browser can't find the document corresponding to the URL you typed in.
Here is my .htaccess:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteRule ^news/([0-9a-zA-Z_-]+) news.php?url=$1 [NC,L]
RewriteRule ^seksikateg/([0-9a-zA-Z_-]+) seksikateg.php?kategori=$1 [NC,L]
and i placed he file in the same place as the index.php, news.php, and seksikateg.php
It's possible that MultiViews is enabled at your host and this will break your rules since this will append the .php extension before mod_rewrite processes the request.
However, your directives are also in the wrong order. The generic rewrite to append the .php extension should appear after the other rules.
Your rewrite to append the .php extension is not strictly correct as it could result in a rewrite loop (500 error) under certain circumstances.
Try it like this instead:
# Ensure that MutliViews is disabled
Options -MultiViews
RewriteEngine on
RewriteRule ^news/([0-9a-zA-Z_-]+)$ news.php?url=$1 [NC,L]
RewriteRule ^seksikateg/([0-9a-zA-Z_-]+)$ seksikateg.php?kategori=$1 [NC,L]
# Append ".php" extension on other URLs
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^.]+)$ $1.php [L]
I've also added the end-of-string anchor to the regex of your existing rewrites, otherwise you are potentially matching too much. eg. /news/foo/bar/baz would have also been rewritten to news.php?url=foo - potentially creating duplicate content and opening up your site to abuse.
I would also question the use of the NC flag on these rewrites. If this is required then you potentially have a duplicate content issue.
No need to backslash-escape literal dots in a regex character class and the NC flag is certainly redundant on the last rule.

Mod Rewrite & CheckSpelling/CheckCase redirect solution

I have a number of pages setup, to be accessed by clients' guests. The problem being, case sensitive URLs.
Currently I have in my htaccess file (to remove the .php)
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) $1.php [L]
for example: (the target file is ClientName.php)
website.com/rsvp/ClientName <-this works, and the file is ClientName.php
website.com/rsvp/clientname <-this serves a Internal Server Error
-- edit/update --
Adding both CheckSpelling on & CheckCaseOnly on does not work, unless the .php is in the url. No combination of the two [mod_spelling & mod_rewrite] would work. I also found out, I do not have RewriteMap
based on this thread/post can I redirect to a php file rather than the 500 error page if the file does not exist? (or edit my 500 error page?)
from the post;
RewriteCond %{REQUEST_URI} !^([a-z0-9/]*)\.html
RewriteRule ^(.*)\.html$ redir.php?p=$1 [L]
Will examine the {REQUEST_URI} string and EXCLUDE (!) everything that's lowercase (or directory -- see the "/"?) .html then rewrite EVERYTHING.html to the redir script. Ahhhhh! I just added the "0-9" in there to handle your digits, too. Remember, these "excluded" strings are the ones you want to PASS through to your pages and NOT rewrite.

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.

.htaccess rule to strip script extension and process virtual directories to variables

I am looking for an .htaccess rule for the following situation. I have found fragments of what I am looking for on this site, but I don't have the experience to put them together correctly. The .htaccess rule would process the following scenarios.
The first two examples already work by default with DirectoryIndex, but I included them to make sure they would still work.
/
-> /index.php
/home
-> /home/index.php
/home/hello
-> /home/hello.php
/home/hello/there
-> /home/hello.php?var1=there
/home/hello/there/again
-> /home/hello.php?var1=there&var2=again
Additionally, a trailing / must be optional for each scenario.
Lastly, requests for images or other files should still process correctly. If required, I could put everything that doesn't follow this rule in a folder such as /assets.
So far,
RewriteRule ^([^/]+)/([^/]+)/? /$1/$2.php [NC]
works for /home/hello -> /home/hello.php
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/? /$1/$2.php?var1=$3 [NC]
works for /home/hello/there -> /home/hello.php?var1=there and
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/? /$1/$2.php?var1=$3&var2=$4 [NC]
works for /home/hello/there/again -> /home/hello.php?var1=there&var2=again
but I have yet to get them to play well together and to also omit a directory for images and other assets.
Thank you very much for any recommendations.
Options -MultiViews
RewriteEngine On
RewriteBase /
DirectoryIndex index.php
RewriteCond %{SCRIPT_FILENAME} -f [OR]
RewriteCond %{SCRIPT_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^(.*?)/(\w+)/(.*?)/(.*?)/? $1/$2.php?var1=$3&var2=$4 [L,QSA]
RewriteRule ^(.*?)/(\w+)/(.*?)/? $1/$2.php?var1=$3 [L,QSA]
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*?)/(\w+)/? $1/$2.php [L]
Per Directory evaluation is iterative so you need a stop criteria. This is what rule 1 does.
The Directory index directive handles the index.php additions.
Rule 2-4 do your SEO to Get mapping. Note that I've changed parameter 2 to match any word string.
.+? is a non-greedy match. It will stop at the first /
I think I would create different rules myself. In inverse order of what you have listed to capture. So if you can capture 2 vars do that first, then try 1 var, then just the page etc.
Here is something that may be of more help http://martinmelin.se/rewrite-rule-tester/

Why is Apache mod_rewrite not behaving as expected

I want to redirect URLs from an old site that used raw URL requests to my new site which I have implemented in CodeIgniter. I simply want to redirect them to my index page. I also would like to get rid of "index.php" in my URLs so that my URLs can be as simple as example.com/this/that. So, this is the .htaccess file I have created:
RewriteEngine on
Options FollowSymLinks
RewriteBase /
RewriteCond $1 ^assets
RewriteRule ^(.*)$ example/production/$1
RewriteCond %{QUERY_STRING} .+
RewriteRule ^(.*)$ index.php? [R=301]
RewriteCond $1 !^(index\.php|example|robots\.txt)
RewriteRule ^(.*)$ index.php/$1
It should also be noted that my index.php is actually a symlink to example/production/index.php.
Now, the first rule works as expected - all my styles and images show up just fine, it's the second two rules I'm having trouble with. The second rule is basically to destroy the query string and redirect to my index page (externally). So, I found this in the Apache manual:
Note: Query String
The Pattern will not be matched against the query string. Instead, you must use a RewriteCond with the %{QUERY_STRING} variable. You can, however, create URLs in the substitution string, containing a query string part. Simply use a question mark inside the substitution string, to indicate that the following text should be re-injected into the query string. When you want to erase an existing query string, end the substitution string with just a question mark. To combine a new query string with an old one, use the [QSA] flag.
However, when I try to access one of the old pages, instead of redirecting to my index page, I get a 404 page not found error. I have figured out a workaround by making it an internal redirect, but I would really like it to be external.
The next problem, and the one that has been baffling me the most is with the third rule. I would expect this to do something like the following. If I type in:
http://example.com/this/thing
I would expect it to re-route to
http://example.com/index.php/this/thing
Unfortunately, this does not work. Instead, no matter what I type in, it always routes to my index page as if nothing else was in the URL (it just goes to http://example.com/).
Furthermore, and even more confusing to me, if I replace that rule with the following:
RewriteCond $1 !^(index\.php|example|robots\.txt)
RewriteRule ^(.*)$ index.php/this/thing
If I type in a URL such as http://example.com/other/thing, then it will go to http://example.com/index.php/this/thing as expected, BUT if I type in http://example.com/this/thing it goes to http://example.com/ (my index page). I can't make heads or tails out of it. Any help would be greatly appreciated.
This should solve your index.php problem and it will simply detect if a robots.txt is available:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
hmmm - this doesn't seem to work either. The problem is my URLs aren't really asking for a filename or directory anyway. For example: example.com/index.php/this/thing should call the 'thing' method of the 'this' controller. – Steven Oxley
The condition is: If request is NOT a file and NOT a directory, so that was right, what you should have done is combine the appending of the request string:
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]