Chaining multiple required rewrites in .htaccess - apache

I have at present 2 rewrites that are supposed to occur on any given url,
The first redirects any url matching the pattern %DOMAIN%/mcc-* to show.php?id=mcc-*
The second redirects any url without the .php extension to the page as if it had one.
The first rewrite gets called and works, but the second does not.
I have tried swapping the places of the rewrites, but the result is the same, the 'Add Extension' rewrite is never called, even on pages that don't redirect to show.php
ErrorDocument 404 /error/404.php
Options All -Indexes -MultiViews
RewriteEngine On
# Silent Redirect from any url ending with mcc-* to show.php?id=mcc-*
# This works as intended.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(mcc-[\d]+)/?$ show.php?id=$1 [QSA,NC]
# Allow urls to not include the .php extension
# This is not not being called.
RewriteBase /
RewriteCond %{REQUEST_URI}/$1.php -f [NC]
RewriteRule ^(.+?)/?$ $1.php [L]
Is there someway to get both of these conditionals to run, or at the very least run the second if the first doesn't match?

With your shown samples please try following .htaccess rules file. Please make sure to clear your browser cache before testing your URLs.
ErrorDocument 404 /error/404.php
Options All -Indexes -MultiViews
RewriteEngine ON
# Allow urls to not include the .php extension
# This is not not being called.
RewriteBase /
RewriteCond %{DOCUMENT_ROOT}/$1.php -f [NC]
RewriteRule ^(.+?)/?$ $1.php [L]
# Silent Redirect from any url ending with mcc-* to show.php?id=mcc-*
# This works as intended.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(mcc-[\d]+)/?$ show.php?id=$1 [QSA,NC]

Related

htaccess RewriteRule with a variable not working

This rule takes us to the error page
RewriteRule ^latest/([A-Za-z0-9]+)$ latest?auth=$1 [NC,L]
I have the following in my .htaccess file
<IfModule mod_rewrite.c>
RewriteRule ^sucuri-(.*)\.php$ - [L]
</IfModule>
# END - Allow Sucuri Services
<Files 403.shtml>
order allow,deny
allow from all
</Files>
ErrorDocument 404 /404.php
Options +FollowSymLinks
Options +MultiViews
RewriteEngine on
RewriteCond %{HTTPS} !=on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
RewriteCond %{HTTP_HOST} !^www.xxxxx.com$ [NC]
RewriteRule ^(.*)$ https://www.xxxxx.com/$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ci_index.php?/$1 [L]
## Remove php extension
RewriteCond %{REQUEST_URI} !^/index.php$
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteRule ^latest/([A-Za-z0-9]+)$ latest?auth=$1 [NC,L]```
With the following rule
```RewriteRule ^latest/([A-Za-z0-9]+)$ latest?auth=$1 [NC,L]```
Trying to achieve the following -
```https://www.xxxxx.com/latest?auth=US-mobile-county
to
https://www.xxxxx.com/latest/US-mobile-county```
This rule takes us to the error page RewriteRule ^latest/([A-Za-z0-9]+)$ latest?auth=$1 [NC,L]
You've not stated precisely what "error page" you are referring to? Or what is expected to handle this request. This directive is not correct by itself, so it's not immediately clear what it is you are trying to do. I'm assuming the intention is to rewrite to latest.php (not latest as suggested by this rule, and mentioned later in the question) - since this would seem to be the only reason to implement such a rule (and your question is tagged php). By rewriting to latest only you are dependent on other directives appending the .php extension - and therein lies a conflict.
There are a number of issues with the directives as posted that is preventing this from working. Notably, the rules are in the wrong order and the use of MultiViews (probably in an attempt to get extensionless URLs working) is compounding matters. In fact, it doesn't look like the rule in question is actually being processed at all.
Without MultiViews, and due to the order of the directives, a request of the form /latest/something would be rewritten to /ci_index.php?/latest/something (presumably a CodeIgniter front-controller) which I would guess would result in a CI generated 404 response. However, since MultiViews has been enabled mod_negotiation first "rewrites" the request to /latest.php/something, which doesn't match any of your rules so either results in a 404 (depending on your server config) or calls latest.php but without any URL parameter, which presumably causes your script to fail?
https://www.xxxxx.com/latest/US-mobile-county
Also, note that your example URL contains hyphens (-), but the regex in your directive (ie. ^latest/([A-Za-z0-9]+)$) does not permit hyphens so it wouldn't have matched anyway.
Try the following instead, replacing everything after the ErrorDocument directive:
# Disable MultiViews
Options +FollowSymLinks -MultiViews
RewriteEngine on
# Redirect HTTP to HTTPS
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Redirect non-www to www
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L]
# Rewrite "/latest/something" to "/latest.php?auth=something"
RewriteRule ^latest/([A-Za-z0-9-]+)$ latest.php?auth=$1 [L]
# Allow extensionless PHP URLs to work
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^.]+)$ $1.php [L]
# Front-controller
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ci_index.php?/$1 [L]
Note that I've reversed the order of the directives so that the rule in question is now first and the CI front-controller is now last. The order of the directives in .htaccess is important.
Since you had enabled MultiViews (now disabled in the above), your rule to enable PHP extensionless URLs (that you had labelled "Remove php extension") was not actually being used at all (unless you had directories or files that contained dots, other than that used to delimit the file extension).

MultiViews is *too* tolerant of bad URLs

When I enable MultiViews, if I visit bad URLs, the my page (index.php) is still reached, when I want the user to get a 404 error instead. I'm trying to figure out how to fix this without creating rules in my .htaccess.
For example, "www.mydomain.com/index/blah/blah", visits index.php, but I want it to fail due to the extraneous trailing garbage URL components. Similarly for "/contact/blah/awuihda/hiu", which shows the content of contact.php, should give a 404 error, because "/blah/awuihda/hiu" doesn't exist.
If I disable MultiViews it works fine, but then I can't abbreviate the URL as much as I want to (for example, can't type "/contact" to bring up "contact.php").
You could just use the following so the .php extension is not required, which is the usual approach:
RewriteEngine on
# Remove .php if it's present with a 301 redirect
RewriteRule ^(.+)\.php$ $1 [R=301,L]
# If a request doesn't exist as a directory, file or symlink
# and it does exist with .php appended, rewrite to that
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+)$ $1.php [L]
I know it's adding a rule to .htaccess but it's a one off that works for everything and also means you're not hitting potential duplicate content allowing the same thing to be served with or without .php (or indeed with anything at all trailing after it as in your examples). Hope it's useful.
It could go in main server config but would need altering.
I found a solution which works for me.
Options -Indexes SymLinksIfOwnerMatch -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
Source: link

Symfony2: simple rewrite rule in vhost to strip .html extention out

Since I migrated my project on Symfony2, I also avoided to use .html extensions previously used for my generated urls.
So, after looking at some examples, I'am trying to execute this in my /etc/apache2/sites-available/mysite:
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)\.html$ $1 [NC,L]
#this is the standard rewrite rule to redirect every request to /web/app.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ app.php [QSA,L]
</IfModule>
I have tried many combinations but no one seems to work. Any Help? Thanks

htaccess rewrite clean url for multiple parameters

This is my .htaccess code for clean url rewriting.
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^[a-zA-Z]{3,}\s/+index\.php\?bank=([^\s&]+) [NC]
RewriteRule ^ %1%2%3%4? [R=301,L]
RewriteRule ^([^/]+)/?$ index.php?bank=$1$2$3$4 [L,QSA]
This code works fine for single parameter in url. For example it rewrites
http://example.com/example-path/ to
http://example.com/index.php?bank=example-path/
But when I tried to pass multiple parameters in url, all I got are errors.
I need a url like
http://example.com/example-path instead of http://example.com/index.php?bank=example-path
How can I alter My code to pass multiple urls.
Your redirect logic can be greatly simplified to just:
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
#If a request does not match an existing directory
RewriteCond %{REQUEST_FILENAME} !-d
#And does not match an existing file
RewriteCond %{REQUEST_FILENAME} !-f
#then rewrite all requests to index.php
RewriteRule ^(.*)/?$ index.php?bank=$1 [L,QSA]

.htaccess rewrite rule to make longer url work

I have a rewrite rule that allows me to be able to have a url like this..
http://example.com/randyt
and convert it to
http://example.com/?aff=randyt
It's working however, I also have other links that need to be used such as....
example.com/members/aff/go/randyt
example.com/members
example.com/members/signup
and so on. The rewrite rule I have ignores those urls and just goes to
example.com
Please help me add something to this so it will not ignore any url with the /members or /members/.... in it.
Here is the code I am using now...
RewriteEngine On
RewriteBase /
# If the request is not for a valid directory
RewriteCond %{REQUEST_FILENAME} !-d
# If the request is not for a valid file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.+) ?aff=$1 [L,QSA]
Sorry about the comments section I am new here lol.
So here is the above code with the added code that someone suggested
RewriteEngine On
RewriteBase /
# If the request is not for a valid directory
RewriteCond %{REQUEST_FILENAME} !-d
# If the request is not for a valid file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.+) ?aff=$1 [L,QSA]
RewriteCond %{REQUEST_URI} ^/members
RewriteRule . - [L]
When I try to use the extended url it still goes back to the base url showing only index.php from the root directory.
When someone uses a url like this....
example.com/members/aff/go/randyt
I need it to stay in the members directory using that affiliate code. The current program should take care of that.
Here is the .htaccess code in the members directory
<IfModule mod_rewrite.c>
RewriteEngine on
# RewriteBase /members
RewriteRule ^public public.php [L]
RewriteRule ^js.php js.php [L]
RewriteRule !\.(js|ico|gif|jpg|png|css|swf|csv|html)$ index.php
</IfModule>
<IfModule mod_php5.c>
# php_flag magic_quotes_gpc off
</IfModule>
That code was pre-written by the company I purchased the program from.
So to sum this up, I need 2 different things to happen...
If someone uses:
example.com/randyt (randyt can be any username)
it needs to stay on example.com showing that page (index.php file)
If someone uses:
example.com/members/aff/go/randyt (again randyt can be any username)
it needs to stay in the members directory and use the purchased script.
Try this rule in /members/.htaccess:
DirectoryIndex index.php
RewriteEngine on
RewriteBase /members/
RewriteRule ^public/?$ public.php [L,NC]
# If the request is not for a valid directory
RewriteCond %{REQUEST_FILENAME} !-d
# If the request is not for a valid file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
You can add a condition to your .htaccess
RewriteCond %{REQUEST_URI} ^/members
RewriteRule . - [L]
This condition will check if the Requested URI contains a string starting with /member then it will be passed unchanged to its destination.