htaccess root of url issue - linux

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?

Related

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.

Discard RewriteRule in 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.

Adding trailing slash - Specific rules

I've got this setup:
RewriteRule ^brands$ brands/ [R=301,L]
RewriteRule ^brands/$ /brands.php
RewriteRule ^brands/([A-ZÆØÅæøåa-z0-9-]+)-([0-9]+)/$ index.php?manufacturers_name=$1&manufacturers_id=$2 [L,QSA]
RewriteRule ^brands/([0-9]+)$ index.php?manufacturers_id=$1 [L]
How would I fix it so there's alway a trailing slash on this - Those specific urls?
xxx.com/brands/brand-id
So if I either went to xxx.com/brands/brand-id OR xxx.com/brands/brand-id/ - It'll work as having a trailing slash?
Replace your Rule with this
RewriteRule ^brands/([0-9]+)/?$ index.php?manufacturers_id=$1 [L]
/? means that the / is optional in uri. Your rule will match both uri strings ending with or without a traling slash.
And to add the traling slash to specific uris,put the following before your existing rules
RewriteRule ^brands/[0-9]+$ %{REQUEST_URI}/ [L,R]
This will redirect /brands/123 to /brands/123/ .

.htaccess rewrite and redirect two types of urls

I'm trying to create clean URL with .htacces rewrite. I have two types of urls:
site.com/page.php?page=something
site.com/something.php
I need them both to be just site.com/something, with redirect from ugly to pretty url. So now I have the following rules, which don't work together, and I totally stuck with the redirect.
Options -Multiviews
RewriteEngine On
RewriteBase /
# page.php?page=about to about
RewriteRule ^([^/.]+)?$ /page.php?page=$1 [NC,L]
# something.php to something
RewriteRule ^([^/.]+)?$ $1.php [NC,L]
Will appreciate any help. Thanks in advance.
There are a few things that are incorrect in your example:
You cannot inspect the query string in a RewriteRule, only in a RewriteCond
Your RewriteRule lines are backwards - the first part is a regular expression match of the URL and the second is what you want it to be.
You will need to have an [R] rule as part of the rewrite to perform a redirect, otherwise it will just "rewrite" the URL the server sees and not change the actual URL.
Here is an example of your first rewrite, redirecting /page.php?page=foo to /foo. You first need a RewriteCond to inspect the %{QUERY_STRING} variable to see if it has page=... in it. We can use the character match ([^&]*) to grab all of the characters that are not an ampersand and store in a matching group. Next we perform a RewriteRule for page.php (note that we don't need the leading / because of the RewriteBase and that the . is escaped). If there is a match here, you want to redirect to the matching group from the RewriteCond - it is referred to with a %1 rather than a $1 like it would if it were from the RewriteRule. You will also want to append a ? to the end of your redirect which tells Apache to drop the query string so you don't end up with /foo?page=foo. Finally you will need [R=301] to perform a redirect with an HTTP status code of 301. The [L] indicates that that this is the Last rule you want to process if there is a match.
RewriteEngine On
RewriteBase /
# page.php?page=about to about
RewriteCond %{QUERY_STRING} page=([^&]*) [NC]
RewriteRule page\.php /%1? [R=301,L]
Your second rewrite is closer, but as in the first the logic is backwards. You want the first part to match *.php and then the second to indicate the redirect to /$1. Again you will need the [R-301] for the redirect.
# something.php to something
RewriteRule (.*)\.php$ $1 [R=301,L]
You can test this out on http://htaccess.madewithlove.be/.
Using http://example.com/page.php?page=foo, redirects to http://example.com/foo
1 RewriteEngine On
2 RewriteBase /
3 # page.php?page=about to about
4 RewriteCond %{QUERY_STRING} page=([^&]*) [NC]
This condition was met
5 RewriteRule page\.php /%1? [R=301,L]
This rule was met, the new url is http://example.com/foo
Test are stopped, because of the R in your RewriteRule options.
A redirect will be made with status code 301
Using http://example.com/foo.php redirect to http://example.com/foo
1 RewriteEngine On
2 RewriteBase /
3 # page.php?page=about to about
4 RewriteCond %{QUERY_STRING} page=([^&]*) [NC]
This condition was not met
5 RewriteRule page\.php /%1? [R=301,L]
This rule was not met because one of the conditions was not met
6 # something.php to something
7 RewriteRule (.*)\.php$ /$1 [R=301,L]
This rule was met, the new url is http://example.com/foo
Test are stopped, because of the R in your RewriteRule options.
A redirect will be made with status code 301

Resources