RewriteRule - only two directories and a file - .htaccess

I am trying to rewrite URLs through .htaccess and what I want is that a rule be taken into account only if the URL is like "www.mysite.com/basedir/directory/file.htm".
I don't want "www.mysite.com/basedir/file.htm" or "www.mysite.com/basedir/directory/directory/file.htm", I want the exact described structure. At the moment I am trying to do it with this:
RewriteRule ^(basedir)/([^/\.]+)/(.*)\.(htm)$ /template.php?&page=$3 [L]
but it doesn't work. It accepts any number of directories after basedir.
Thanks for your help

Your second match area needs to have a character exclusion like the first:
RewriteRule ^(basedir)/([^/\.]+)/([^/]*)\.(htm)$ /template.php?&page=$3 [L]
That way you don't allow additional slashes to be matched, only the two explicit slashes earlier in the pattern.
Also, what exactly are you trying to match with $3? You only need to use parentheses around things that you need to match. If $3 is supposed to match file.htm, then you could instead write:
RewriteRule ^basedir/[^/\.]+/([^/]*\.htm)$ /template.php?&page=$1 [L]
or if it should just match "file" then:
RewriteRule ^basedir/[^/\.]+/([^/]*)\.htm$ /template.php?&page=$1 [L]

Related

Mirror a file in htaccess

I'm trying to work on making a new site and I want to be able to mirror a site. Below is an example:
User visits: https://example.com/items/{some child folder}
User sees this file mirrored: https://example.com/items/listing.php
I want user to be able to see that file, but, when doing so, it don't want it to redirect. Any ideas?
UPDATE
I found a solution to the above problem. However, I need another question fixed. How would I stop the file listing.php in the /products folder from following the redirect?
RewriteEngine On
RewriteRule ^products/(.*) index.php?name=$1 [NC,L]
How would I stop the file listing.php in the /products folder from following the redirect?
RewriteRule ^products/(.*) index.php?name=$1 [NC,L]
Be more specific in the regex. If your products don't contain dots in the URL-path then exclude dots in the regex. For example:
RewriteRule ^products/([^./]+)$ index.php?name=$1 [L]
The above assumes your product URLs are of the form /products/<something>. Where <something> cannot consist of dots or slashes (so naturally excludes listing.php) and must consist of "something", ie. not empty.
Unless you specifically need the NC flag then this potentially opens you up to duplicate content.
If you want to be explicit then include a condition (RewriteCond directive):
RewriteCond %{REQUEST_URI} !^/products/listing\.php$
RewriteRule ^products/([^/]+)$ index.php?name=$1 [L]
The REQUEST_URI server variable contains the root-relative URL-path, starting with a slash. The ! prefix on the CondPattern negates the regex.
Or, use a negative lookahead in the RewriteRule pattern, without using a condition. For example:
RewriteRule ^products/(?!listing\.php)([^/]+)$ index.php?name=$1 [L]
Reference:
https://httpd.apache.org/docs/current/rewrite/intro.html
https://httpd.apache.org/docs/current/mod/mod_rewrite.html

multiple url rewriting mod

I have two pages say
http://assistque.com/services.php?prod_id=35&prod_url=Operating%20System%20–%20Windows
and
http://assistque.com/sub_services.php?sp_id=13&sp_url=Technical%20Support%20For%20KASPERSKY
i wrote two rules for two different pages but the for the second page it uses first rule .
Please help
RewriteRule ^([^/]*)/([^/]*)\.html$ /services.php?prod_id=$1&prod_url=$2
RewriteRule ^([^/]*)/([^/]*)\.html$ /sub_services.php?sp_id=$1&sp_url=$2
This is because the patterns in the both rules are the same, try changing them into something unique:
RewriteRule ^services/([^/]*)/([^/]*)\.html$ /services.php?prod_id=$1&prod_url=$2 [L]
RewriteRule ^subservice/([^/]*)/([^/]*)\.html$ /sub_services.php?sp_id=$1&sp_url=$2 [L]
Then in your links you add something like:
operating systems windows
Note, that you should not use spaces inside an url, so in this case I assume those will be replaced with an - character.
It may also be better to narrow down allowed characters and numbers in your rewrite rule:
# will match services/<number>/<string>.html
# the NC flag states that the rule is case insensitive
RewriteRule services/([0-9]+)/([a-z-]+)\.html$ /services.php?prod_id=$1&prod_url=$2 [NC,L]

mod rewrite exclude all but php

Is it possible to edit htacces in such a way that only the following url is rewritten and the rest isn't?
http://www.example.com/index.php?x=foobar
to
http://www.example.com/foobar/
I want the pages not having x=... as a variable to behave normally
I got the following but that doesn't work
Options +FollowSymLinks
RewriteEngine on
RewriteRule (.*)/ index.php?x=$1
RewriteCond $1 !\.(js|ico|gif|jpg|png|css|html|swf|mp3|wav|txt)$
Who can help me?
First off, the RewriteCond must be put before the RewriteRule to which it belongs.
But I think that you need another approach for your case, something like this:
RewriteRule (.*)\.php - [PT,L]
RewriteRule ^(.*)/$ index.php?x=$1
The first rule Passes Through (PT) every PHP page, so the second rule is only applied to all non-PHP requests.
That second rule only applies to a "simple path", no matter if this path has a dot in it or not (e.g. hello.gif/ will match, too).
If this does not work for you, then you might consider one of these points to start further research:
the pattern ([^\.]*) matches everything that does not have a dot in it
see RewriteCond to skip rule if file or directory exists for RewriteConds where the following RewriteRule is only used if the request does not point to an existing file or directory
Hope this helps.

mod_rewrite - check for string

I want to check if a URL contains the sting "-EN.htm", if so apply the rewrite.
That should be done with ^-EN.htm as follows, but the rule is not working:
RewriteCond %{REQUEST_URI} ^/(.*?)/([-_0-9a-zA-Z./=]*)^-EN.htm
RewriteRule ^(.*)$ /indexEN.php?folder=%1&follow=%2 [L]
What am I doing wrong?
Thank you for every help,
Scott
Your regular expression doesn't look right. You can also lose the condition and just move the pattern to the rewrite rule instead. Something along the lines of
RewriteRule ^/?(.*?)/([-_0-9a-zA-Z./=]*)^-EN.htm /indexEN.php?folder=$1&follow=$2 [L]
You need to make the leading slash optional (in htaccess this is stripped off) and instead of using % backreferences, use the $ ones.
Now on to your pattern, it's not valid. The ^ matches the beginning of the string (the URI), so if you have two of them and you're not trying to literally match the ^ character (which you'd need to escape), then the expression will never match anything. Without any examples of URLs that you're having to deal with, I assume you probably just want to ditch the second ^:
RewriteRule ^/?(.*?)/([-_0-9a-zA-Z./=]*)-EN.htm /indexEN.php?folder=$1&follow=$2 [L]

Variable in htaccess, RewriteRule question

How could i use a RewriteRule accesing a variable?
If i have:
SetEnv MY_VAR (a|b|c)
RewriteRule ^%{ENV:MY_VAR}$ index.php?s=$1 [L,QSA]
RewriteRule ^%{ENV:MY_VAR}-some-one$ index.php?s=$1 [L,QSA]
I have these examples but doesn`t work.
Later edit
Ok Tim, thank you for the answer. Let say that i have:
RewriteRule ^(skoda|bmw|mercedes)-([0-9]+)-([0-9]+)-some-think$ index.php?a=$1 [L,QSA]
RewriteRule ^some-one-(skoda|bmw|mercedes)/pag-([0-9]+)$ index.php?a=$1 [L,QSA]
RewriteRule ^a-z-(skoda|bmw|mercedes)$ index.php?a=$1 [L,QSA]
(forget second part of RewriteRule) .. I don-t want to put everywhere (skoda|bmw|mercedes) this list. Is more quickly to make a variable then to use it in rule...
You can't do that, because mod_rewrite doesn't expand variables in the regular expression clauses.
You can only use variables in the input argument to a RewriteCond, and as the result argument to a RewriteRule. There's overhead in compiling the regular expressions (especially if you're forced to do it per-request as with .htaccess files), so if you allowed variable content in them, they'd have to be recompiled for every comparison to ensure accuracy at the cost of performance. It seems the solution therefore was to not let you do that.
What exactly did you want to do that for, anyway?
I`ve received another answer on a mod_rewrite forum from jdMorgan:
Mod_rewrite cannot use a variable in a regex pattern. The .htaccess directives are not a scripting language...
I'd recommend:
RewriteCond $1<>$3 ^<>-([0-9]+)-([0-9]+)-some-think$ [OR]
RewriteCond $1<>$3 ^some-one-<>/pag-([0-9]+)$ [OR]
RewriteCond $1<>$3 ^a-z+-<>$
RewriteRule ^([^\-/]+[\-/])*(skoda|bmw|mercedes)([\-/].+)?$ index.php?a=$2 [QSA,L]
Here, the RewriteRule pattern is evaluated first (See Apache mod_rewrite documentation "Rule Processing").
If the pattern matches, then whatever comes before "(skoda|bmw|mercedes)" in the requested URL-path is placed into local variable "$1".
Whatever follows "(skoda|bmw|mercedes)" is placed into local variable $3.
The value of the requested URL-path matching "(skoda|bmw|mercedes)" is placed into $2.
Then each of the RewriteConds is processed to check that the format of the requested URL without the "(skoda|bmw|mercedes)" part is one of the formats to be accepted.
Note that the "<>" characters are used only as a separator to assist correct and unambiguous parsing, and have no special meaning as used here. They simply "take the place of" the variable-string that you do not want to include in each line. You can use any character or characters that you are sure will never appear in one of your URLs without first being URL-encoded. I prefer to use any of > or < or ~ myself.
Note also that the RewriteRule assumes that the "(skoda|bmw|mercedes)" substring will always be delimited by either a hyphen or a slash if any other substring precedes or follows it. I am referring to the two RewriteRule sub-patterns containing "[^-/]" ("NOT a hyphen or a slash") and "[-/]" ("Match a hyphen or a slash"). This greatly improves efficiency of regular-expressions pattern matching, so use this method if possible instead of using an ambiguous and inefficient sub-pattern like ".*" (Match anything, everything, or nothing").

Resources