Discard RewriteRule in htaccess - .htaccess

There are 2 RewriteRules for permalink in php.
RewriteRule ^(.*).htm index.php [NC,QSA,L]
RewriteRule ^(.*).html index.php [NC,QSA,L]
I need to browse a static html file:
/uploads/themes/mail-signature/mail-signature.html
But when I enter http://example.com/uploads/themes/mail-signature/mail-signature.html it's showing index.php.
How can I discard these rules?

RewriteRule ^(.*).htm index.php [NC,QSA,L]
RewriteRule ^(.*).html index.php [NC,QSA,L]
Your 2nd rule isn't actually doing anything anyway, since any .html requests will be caught by the first rule. So, the second rule can be removed.
You then add a condition to the first rule that excludes the specific URL you are trying to access. For example:
RewriteCond %{REQUEST_URI} !^/uploads/themes/mail-signature/mail-signature\.html$
RewriteRule \.html?$ index.php [NC,L]
The QSA flag is not required here, as any query string will be passed through by default.
The ^(.*) prefix on your RewriteRule pattern is not required since you aren't using this backreference.
You should backslash escape any literal dots in the regex, eg. \.htm, otherwise you are matching any character, eg. "xhtm". And presumably you only want to match URLs that end in .htm or .html? Your original regex would match "htm" anywhere in the requested URL.

Related

htaccess root of url issue

Trying to achieve rewrites for 3-1 paths in the url, and then a rewrite for index. Can achieve the former with below:
RewriteCond %{HTTP_HOST} ^www.domain.com$ [NC]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)?$ /index.php?a=$1&b=$2&c=$3 [L,QSA,NC]
RewriteRule ^([^/]+)/([^/]+)?$ /index.php?a=$1&b=$2 [L,QSA,NC]
RewriteRule ^([^/]+)?$ /index.php?a=$1 [L,QSA,NC]
Want to add after this a rewrite from index (eg "www.domain.com") to /index.php?a=10 but cant get that work.
RewriteRule ^([^/]+)?$ /index.php?a=$1 [L,QSA,NC]
The "problem" is that the last rule also matches an empty URL-path so the request is rewritten to /index.php?a= and any later rule that matches the root is not processed.
Instead of writing the rule to match the root "after" the existing rules, you can add it before your existing rules to avoid conflict. For example:
RewriteRule ^$ /index.php?a=10 [QSA,L]
: other rules follow...
RewriteCond %{HTTP_HOST} ^www.domain.com$ [NC]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)?$ /index.php?a=$1&b=$2&c=$3 [L,QSA,NC]
RewriteRule ^([^/]+)/([^/]+)?$ /index.php?a=$1&b=$2 [L,QSA,NC]
RewriteRule ^([^/]+)?$ /index.php?a=$1 [L,QSA,NC]
Note that the RewriteCond directive only applies to the first RewriteRule directive. Do you need this at all?
Your rules are a little ambiguous since in each of the regex you are allowing the last path segment to be optional. This basically means the trailing slash is optional (eg. /foo/bar/ and /foo/bar are both valid URLs according to these rules). If you don't make the path segment optional in the last rule then you can place your rule to match the root last as you were wanting to do originally.
A request for /foo/bar/baz matches the first rule. /foo/bar/ (with a trailing slash) also matches the first rule, but /foo/bar (no trailing slash) matches the second rule. Likewise, /foo/ also matches the second rule, but /foo matches the third rule. And (following the same pattern) the third rule also matches / (hence your initial problem). My point is... should that last path segment on each rule be optional?

htaccess redirect if parameter exists not working

I'm trying to rewrite any URL if a special parameter exists.
So that this happens:
From: www.example.com/somepage/someother/?entryValue=somevalue
To: www.example.com/somepage/someother/?product=test&special=12345ls&linkSource=website
I tried to following, but it doesnt work as expected:
This code adds var/www/* instead of the link
www.example.com/var/www/web6/htdocs/example.com/index.php/*
RewriteCond %{QUERY_STRING} (^|&)entryValue=somevalue
RewriteRule ^(.*)$ $1/?product=test&special=12345ls&linkSource=website [L,R]
This code removes the path:
RewriteCond %{QUERY_STRING} (^|&)entryValue=somevalue
RewriteRule ^(.*)$ /?product=test&special=12345ls&linkSource=website [L,R]
How can I make it work?
RewriteCond %{QUERY_STRING} (^|&)entryValue=somevalue
RewriteRule ^(.*)$ $1/?product=test&special=12345ls&linkSource=website [L,R]
You need to include a slash prefix at the start of the substitution string. Like this:
RewriteRule ^(.*)$ /$1/?product=test&special=12345ls&linkSource=website [L,R]
Without the slash prefix (the URL-path matched by the RewriteRule pattern does not include a slash prefix) it is seen as relative and the directory-prefix (ie. /var/www/...) will be added back and result in the malformed redirect you are seeing.
UPDATE:
but this ends up with "index.php" and the path is lost
You've put the directive in the wrong place and have a conflict. The order of the mod_rewrite directives is important.
Generally, external redirects like this need to go near the top of the .htaccess file, before any internal rewrites (like a front-controller).

htaccess 3 parameters rewrite rule

I know this problem is asked before, but i don't find anything
i try to pass 3 variable in htaccess the url change normaly but i cant't get the third variable
this is my htaccess file
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-z]+)\/?$ index.php?r=$1 [NC]
RewriteRule ^([a-z]+)/([a-z]+) index.php?r=$1&s=$2 [L]
RewriteRule ^([a-z]+)/([0-9]+) index.php?r=$1&id=$2 [L]
RewriteRule ^([a-z]+)/([0-9]+)/([a-z]+) index.php?r=$1&id=$2&s=$3 [L]
RewriteRule ^([a-z]+)/([0-9]+) index.php?r=$1&id=$2 [L]
RewriteRule ^([a-z]+)/([0-9]+)/([a-z]+) index.php?r=$1&id=$2&s=$3 [L]
These 2 rules conflict. A URL of the form /abc/123/def is also matched by the first rule, so the second rule is never processed.
You could either:
Include an end-of-string anchor ($) on the first rule pattern, so that it only matches /abc/123 and not /abc/123/def. For example:
RewriteRule ^([a-z]+)/([0-9]+)$ index.php?r=$1&id=$2 [L]
OR, reverse these two directives, so the rule for 3 parameters takes priority:
RewriteRule ^([a-z]+)/([0-9]+)/([a-z]+) index.php?r=$1&id=$2&s=$3 [L]
RewriteRule ^([a-z]+)/([0-9]+) index.php?r=$1&id=$2 [L]
You should probably include end-of-string anchors on all your patterns, otherwise, they are likely to match too much. eg. /abc/123/def/for/bar/baz.jpg is matched by the 3rd and 4th rule without an end-of-string anchor. If you add end-of-string anchors then the filesystem conditions could probably be removed altogether.
As #IMSoP noted in comments, those two conditions (ie. RewriteCond directives) only apply to the first RewriteRule that follows. The first rule is unlikely to match a real file anyway, so the conditions aren't really doing anything currently.

Loosening .htaccess file's RewriteRule(s) to also access URL without a trailing slash

My .htaccess file always requires URL with trailing slash such as:
http://localhost/menjaraz/webroot/about/
http://localhost/menjaraz/webroot/2013/03/21/you-are-my-heart-you-are-my-soul/
to work, otherwise a 404 error is fired.
I wish to loosen the rule(s) so that an URL without an ending slash will also do as well.
Excerpt
RewriteBase /menjaraz/webroot
RewriteRule ^([^/]*)/$ index.php?page=$1
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)/$ index.php?a=$1&b=$2&c=$3&page=$4
How should I do that ? I'm not very comfortable neither with regex nor with mod_rewrite.
Thanx in advance.
You need to make the last slash optional using the ?:
RewriteBase /menjaraz/webroot
RewriteCond %{REQUEST_URI} !index.php
RewriteRule ^([^/]*)/?$ index.php?page=$1
RewriteCond %{REQUEST_URI} !index.php
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)/?$ index.php?a=$1&b=$2&c=$3&page=$4
The ? makes the character or group right before it optional. Because there's no trailing slash, you need to add a condition to make sure index.php doesn't get rewritten.

SEO Url for Profiles

Preface
I'm trying to re-write a URL for a profile page. All of my application pages have a .html extension, so I'm trying to match just letters, numbers, -, and ..
So these would be valid
site.com/steve
site.com/steve-robbins
site.com/steve.robbins
But these wouldn't be
site.com/steve.html
site.com/steve-robbins.php
Assume I have a check in place so that custom URLs don't have .html or .php on the end.
Problem
I'm currently using this but it's not working
RewriteRule ^([a-zA-Z0-9\.-]+)$ profile.php?url=$1 [L]
It should set url to steve, but it's setting it to profile.php
What am I doing wrong?
My complete .htaccess
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^[^.]+\.[^.]+$
RewriteRule ^(.*) http://www.%{HTTP_HOST}/$1 [R=301]
#
# LOGIN
#
RewriteRule ^([a-z0-9]{255})/activate\.html$ login.php?activate=$1 [L]
RewriteRule ^logout\.html$ login.php?logout [L]
#
# SETTINGS
#
RewriteRule ^change-([a-z]+)\.html$ account-settings.php?$1 [L]
RewriteRule ^([a-zA-Z0-9\.-]+)$ profile.php?url=$1 [L]
# SEO friendly URLs
RewriteRule ^([a-zA-Z0-9-_.]+)\.html$ $1.php [L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([a-zA-Z0-9-_.]+)\.php
RewriteRule ^([a-zA-Z0-9-_.]+)\.php$ $1.html [R=301]
Add this to the top of your rules (under the RewriteBase / directive):
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
That should stop it from looping. The rewrite engine will keep re-applying all the rules until the URI going in (sans query string) is the same as the URI that comes out of the rules. That's why the value of url is profile.php.
I'm kind of a beginner in interpreting mod_rewrite rules but if I understand it correctly your rule is matched and than matched again, either add something to the url matching scheme like /profile/user or add a condition to not redirect if already redirected
Try adding a leading slash to the redirect like this:
RewriteRule ^([a-zA-Z0-9.-]+)$ /profile.php?url=$1 [L]
The reason you're getting a url value of profile.php is because the [L] flag is kinda misleading when it comes to the .htaccess file. In the server config files it does exactly what you'd think, but in the .htaccess file it stops reading rules at that rule, but then goes through the rules again until path is unchanged by any of the rules. By adding the leading /, your rule will not match the second time around as you exclude / from the regex. I spent a while struggling with this feature myself.

Resources