Exclude a directory from being redirected in .htaccess - apache

OK, so we were working in the wrong directory, meh!
We have a .htaccess file that is setup to redirect some files to a PHP script. Now we are adding some hard files which we want to bypass this redirect. So far this does not seem to be working and we are stumped.
Below is our initial .htaccess file contents after starting the engine which is working for another app already:
RewriteCond $1 !^(index\.php|robots\.txt|favicon\.ico)
RewriteRule ^(.*)$ /index.php/$1 [L]
We are trying to load files now from /directory/ So we have tried adding each of these to the RewriteCond section:
RewriteCond %{REQUEST_URI} !directory
RewriteCond $1 !^(index\.php|i/|robots\.txt|favicon\.ico|directory)
Neither seems to be working. Any ideas on how to get this to load?
Examples:
Should redirect
http://example.com/thisredirects/
Should not redirect
http://example.com/directory
http://example.com/directory/
http://example.com/directory/index.php
etc.

have you tried making a second .htaccess file in the /directory dir and doing a NoRewrite in it?

Try this:
Wont redirect
RewriteRule directory/.* - [L]
Redirects
RewriteRule ^$ thisredirects/ [L]
RewriteRule (.*) thisredirects/$1 [L]

It seems you want to redirect anything that isn't actually an existing file in your docroot to your index.php. This little bit of rewrite should handle that:
RewriteCond %{REQUEST_FILENAME} -s [OR] # file with size
RewriteCond %{REQUEST_FILENAME} -l [OR] # file is a link
RewriteCond %{REQUEST_FILENAME} -d # file is a directory
RewriteRule ^.*$ - [NC,L] # don't rewrite [last rule]
RewriteRule ^(.*)$ /index.php/$1 [NC,L] # everything else gets sent to index.php
The [OR] operator may be what you are looking for on the RewriteCond as well.
Also if you just want to whitelist the /directory portion you could put a Rule before your redirects that is marked [L] for "last rule"
RewriteRule ^/directory.*$ - [NC,L]

Related

htaccess rewrite not working for multiple files in main directory

The title does not fully describe the issue, but I have rewrite rules setup to go to three different files which exist in the main directory: api.php, admin.php, and index.php
Here is my .htaccess
RewriteEngine on
RewriteCond $1 ^(api)
RewriteRule ^(.*)$ /api.php/$1 [L]
RewriteCond $1 ^(admin)
RewriteRule ^(.*)$ /admin.php/$1 [L]
RewriteCond $1 !^(index\.php|admin\.php|api\.php|admin|api|_|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
For /admin and /api I get a 500 Internal Server Error. I am not sure why that happens, yet if I put those php files within a folder like /_ and edit the .htaccess to match it then it rewrites without an error. Am I limited on the number of main directory file redirects I can do? Or did I am I missing something?
My main goal is:
Redirect all /api requests to /api.php/whatever/is/after/here
Redirect all /admin requests to /admin.php/whatever/is/after/here
Redirect all other requests apart from the exceptions to /index.php/whatever/is/here
Try with:
RewriteEngine on
# skip all files and directories from rewrite rules below
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^(api.*)$ /api.php/$1 [L]
RewriteRule ^(admin.*)$ /admin.php/$1 [L]
RewriteCond $1 !^(index\.php|admin\.php|api\.php|admin|api|_|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
I found that I simply had to be more specific in my regex match. Previously I was matching anything that started with "admin" or "api" (eg. admins-at-the-new-school) which actually I was unaware of and would cause problems in the future anyways. I changed my regex and now it only matches if it's the end of a line, a pound sign, slash, or question mark. (based on testing)
Here is my final code:
RewriteEngine on
RewriteRule ^(api(?=$|[/?#]).*)$ /api.php/$1 [L]
RewriteRule ^(admin(?=$|[/?#]).*)$ /admin.php/$1 [L]
RewriteCond $1 !^(index\.php|admin\.php|api\.php|_|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
I appreciate Croises answer, and it did help give me an idea of what might be going wrong that his solution would work. However, this is what I was looking for as I did not want to open up access to files and directories simply because they existed.

How can I redirect existing *.phps with this mod_rewrite, too?

I use the following mod_rewrite to redirect everything to the index.php, but it seems like that if an .php file exists it is opened instead of redirected to the index.php. What should I change to solve this ?
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^(data/|js/|styles/|robots\.txt) - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
PS: I know there are plenty of examples to redirect .php to something else, but I would like to do it without creating a new RewriteRule if possible.
Not sure what you are trying to achieve with the first 4 lines (they look to be doing what apache would do by default). They are probably what are causing the problem.
Whole block should be
RewriteRule ^(data/|js/|styles/|robots\.txt) - [NC,L]
RewriteRule ^/(.*)$ index.php [NC,L]
That will send every except your asset dirs to index.php
If you want an actual http redirect, you need
RewriteRule ^/(.*)$ /index.php [R]
The following is specific to php, if that's all you're interested in
RewriteRule ^(.*)\.php index.php [NC,L]

Removing .html extensions in .htaccess file

I am trying to configure my site with an htaccess file so that any request ending in .html will be rewritten so that the new URL is identical except that ".html" is not present at the end. This should work regardless of how many directories deep the request might be.
So for example,
http://site.com/page1.html -> http://site.com/page1
http://site.com/dir1/dir2/page2.html -> http://site.com/dir1/dir2/page2
http://site.com/~bob/dir3/page3.html -> http://site.com/~bob/dir3/page3
I would prefer a solution where I don't need to hardcode the domain name, but it would be acceptable if necessary.
My current .htaccess file is a standard Zend Framework .htaccess file, and it is working correctly. I am aware that I will need to change the rewrite base if I move the site elsewhere.
SetEnv APPLICATION_ENV development
RewriteEngine On
#Send all requests for non-existant files to index.php
RewriteBase /~rburk/refactor
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
Try adding these rules to the htaccess file in your document root:
RewriteEngine On
RewriteCond %{THE_REQUEST} \ /(.*)\.html($|\ )
RewriteRule ^ /%1 [L,R=301]
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.*)$ /$1.html [L]

.htaccess Rewrite Within Directory - Hide PHP extension and force trailing slash

I'm trying to hide the .php extension from my files as well as force a trailing slash on the resulting URLs.
Example: A request to /about.php would become /about/ and requests to /about would go to /about/.
The following rewrite code worked perfectly when I was in the root of my hostdomain:
RewriteEngine On
RewriteRule ^(.*)/$ /$1.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://edit.mydomain.org/$1/ [R=301,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.*)\.php\ HTTP/ [NC]
RewriteRule .+ http://edit.mydomain.org/%1 [R=301,QSA]
However, I need to move my files into a directory of this host name. Adding a directory name to the rules and having the .htaccess in the directory itself didn't work at all and seems to cause a endless redirect.
I looked around StackOverflow and other websites and tried numerous examples and ended up with many different errors with the most common being:
Everything is an endless redirect.
Everything except the directory home page is a 500 Error.
about.php redirects to /about but there's no redirect to /about/ and /about/ displays a 500 Error.
Everything working, but the home page (of the directory) index.php when accessed without a filename goes into an endless redirect.
Things redirect to edit.mydomain.org/home/username/public_html/mydomain.org/edit/pagename.php which obviously doesn't exist.
Thanks for any help! I really need to keep these files in a directory although the .htaccess could go into the host name root if its needed.
The directory for this would be edit.mydomain.org/dave/
Save this as a .htaccess and put it in the 'dave' directory
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !\..+$
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^(.*)$ http://edit.mydomain.org/dave/$1/ [R=301,L]
RewriteRule ^(.*)/$ $1.php [L]
This works for me
RewriteBase /
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html

.htaccess rewrite to default language folder?

I have my site broken down into several folders by language:
/
/en/
index.php
about-us.php
faq.php
...
/fr/
index.php
about-us.php
faq.php
...
...
etc.
I'd like to have a rewrite rule that automatically rewrites to the en folder if somebody tried to enter mydomain.com/about-us.php.
FYI, I also already have a rewrite rule in place that removes the extension, so really I want to make sure that mydomain.com/about-us rewrites to mydomain.com/en/about-us. Here's my existing rewrite rule that does this:
# allows for extension-agnostic urls
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php
That make sense? Anyone help me out here?
EDIT:
#Gumbo -
Here's what my .htaccess file looks like (this is all that's in it):
RewriteEngine On
# defaults to the english site
RewriteRule !^[a-z]{2}/ /en%{REQUEST_URI} [L,R=301]
# allows for extension-agnostic urls
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php
This file is in the root of my website (not in a language folder). I've reloaded my webserver, just to be on the safe side, and I still get this error message when I try to go to mydomain.com/about-us:
Not Found
The requested URL /about-us was not found on this server.
... where mydomain.com/en/about-us works just fine.
Any other thoughts?
Put this rule before your rule:
RewriteRule !^(fr|en)/ /en%{REQUEST_URI} [L,R=301]
Or more general:
RewriteRule !^[a-z]{2}/ /en%{REQUEST_URI} [L,R=301]