Trying to exclude a single file from a rewrite rule that otherwise forces all requests to https. The rule itself works, but I cannot seem to find the correct syntax for the exception.
I am trying to exclude GET requests that look like:
http://savepostage.com/cgi-bin/version.pl
or the same with ?[somestring] appended
Here's what I am using:
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI}!.\version.pl
RewriteRule ^(.)$ https://savepostage.com/$1 [R,L]
It forces all requests to https, regardless of whether I include or delete the second line.
I must be missing some syntax here.
Thanks for any help.
Try this '/' for a sub-directory
RewriteCond %{REQUEST_URI} !^/version\.pl$
The rule will be skipped if file is version.pl where '^' matches the exact 'version' file name
Related
I am new to .htaccess and I don't understand it well. Recently I have built the following code:
RewriteEngine On
RewriteCond %{HTTP_HOST} (.*)
RewriteCond %{REQUEST_URI} /api/v2/
RewriteRule ^api/v2(.*) /api/v2/api.php?input=$1
This was in the root public folder (example.com/.htaccess). But now I have to create second Rewrite and I want to make .htaccess file in example.com/api/v2/ folder. I tried to remove /api/v2/ part in each Rewrite Rule, but only thing I got was error 500.
What I want to achieve:
If someone uses this link: https://example.com/api/v2/test/test/123, I'd like to make it into https://example.com/api/v2/api?input=test/test/123 with .htaccess located in example.com/api/v2 folder.
Addressing your existing rule first:
RewriteCond %{HTTP_HOST} (.*)
RewriteCond %{REQUEST_URI} /api/v2/
RewriteRule ^api/v2(.*) /api/v2/api.php?input=$1
The first RewriteCond (condition) is entirely superfluous and can simply be removed. The second condition simply asserts that there is a slash after the v2 and this can be merged with the RewritRule pattern. So, the above is equivalent to a single RewriteRule directive as follows:
RewriteRule ^api/v2(/.*) /api/v2/api.php?input=$1 [L]
This would internally rewrite the request from /api/v2/test/test/123 to /api/v2/api.php?input=/test/test/123 - note the slash prefix on the input URL parameter value.
However, unless you have another .htaccess file in a subdirectory that also contains mod_rewrite directives then this will create a rewrite loop (500 error).
Also note that you should probably include the L flag here to prevent the request being further rewritten (if you have other directives).
If someone uses this link: https://example.com/api/v2/test/test/123, I'd like to make it into https://example.com/api/v2/api?input=test/test/123 with .htaccess located in example.com/api/v2 folder.
I assume /api? is a typo and this should be /api.php?. Note also that the slash is omitted from the start of the URL parameter value (different to the rule above).
I tried to remove /api/v2/ part in each Rewrite Rule, but only thing I got was error 500.
This is the right idea, however, you need to be careful of rewrite loops (ie. 500 error response) since the rewritten URL is likely matching the regex you are trying to rewrite.
Try the following instead in the /api/v2/.htaccess file:
RewriteEngine On
RewriteCond %{REQUEST_URI} !api\.php$
RewriteRule (.*) api.php?input=$1 [L]
The preceding RewriteCond directive checks that the request is not already for api.php, thus avoiding a rewrite loop, since the pattern .* will naturally match anything, including api.php itself.
You could avoid the additional condition by making the regex more specific. For example, if the requested URL-path cannot contain a dot then the above RewriteCond and RewriteRule directives can be written as a single directive:
RewriteRule ^([^.]*)$ api.php?input=$1 [L]
The regex [^.]* matches anything except a dot, so avoids matching api.php.
Alternatively, only match the characters that are permitted. For example, lowercase a-z, digits and slashes (which naturally excludes the dot), which covers your test string test/test/123:
RewriteRule ^([a-z0-9/]*)$ api.php?input=$1 [L]
Or, if there should always be 3 path segments, /<letters>/<letters>/<digits>, then be specific:
RewriteRule ^([a-z]+/[a-z]+/\d+)$ api.php?input=$1 [L]
I've zeroed my problem and I've specific question.
With only the following code in the .httaccess why index2.php gets called if I type in my URL as www.mysite.com/url2 ?
RewriteEngine On
RewriteCond %{REQUEST_URI} (.html|.htm|.feed|.pdf|.raw)$ [NC]
RewriteRule (.*) index2.php [L]
I've also tested it at http://www.regextester.com and should not replace it with index2.php:
In the end I want this rule to skip any URL starting with /url2 or /url2/*.
EDIT: I've made screen recording of this problem: http://screenr.com/BBBN
You have this in your .htaccess:
RewriteEngine On
RewriteCond %{REQUEST_URI} (.html|.htm|.feed|.pdf|.raw)$ [NC]
RewriteRule (.*) index2.php [L]
What it does? it rewrites anything that ends with html, htm, feed , pdf , raw to index2.php. So, if you are getting results as your URL is ends with those extensions, then there are two possible answers:
There is another rewrite rule in an .htaccess in upper directories (or in server config files) that causes the URL to be rewritten.
Your URL actually ends with those extensions. have in mind, what you enter in your address bar, will be edited and rewritten. For example, if you enter www.mysite.com/url2 in your address bar and that file doesn't exist on server, your server will try to load the proper error document. So, if your error document is /404.html, it will be rewritten to index2.php at the end.
Update:
I think it's the case. create a file named 404.php in your document root. Inside your main .htaccess (in your document root), put this:
ErrorDocument 404 /404.php
delete all other ErrorDocument directives.
inside 404.php , put this:
<?php
echo 'From 404.php file';
?>
Logic behind it:
When you have a weird behavior in mod_rewrite, the best solution in my experience is using rewrite log. to enable rewrite log put this in your virtualhost or other server config directives you may choose:
RewriteLogLevel 9
RewriteLog "logs/RewriteLog.log"
be careful: the code above will enable rewrite log and start logging at highest level possible (logging everything). It will decrease your server speed and the log file will become huge very quickly. Do this only on your dev server.
Explanation: When you try to access www.mysite.com/url2, Apache gives your URL to rewrite module. Rewrite module checks if any of RewriteRules applies to your URL. Because you have one rule and it doesn't apply to your URL, it tries to load the normal file. But this file does not exit. So, Apache will do the next step which is showing the proper error message. When you set a custom error file, Apache will run the test against the new address. For example if error document is /404.html, Apache checks whether your rule applies to /404.html or not. Since it does, it will rewrite it.
The point to remember is apache will do this every time there is change in URL, whether the change is made by rewrite module or not!
The rule you list should work as you expect if this is the only rule. Fact is that theory is fun, but apparently it doesn't work as expected. Please note that . will match ANY CHARACTER. If you want to match the full stop/period character, you'll need to escape it. That's why I use \.(html|htm|feed|pdf|raw)$ instead of (.html|.htm|.feed|.pdf|.raw)$ below.
You can add another RewriteCond that simply doesn't match if the url starts with /url2, like below. This might not be a viable solution if there are lots of urls that shouldn't be matched.
RewriteCond %{REQUEST_URI} !^/url2
RewriteCond %{REQUEST_URI} \.(html|htm|feed|pdf|raw)$ [NC]
RewriteRule (.*) index2.php [L]
To get a better understanding of what is happening you can alter the rule to something like this. Now simply enter the urls you dont want to be matched in the url bar and inspect the url bar after the redirect happens. In the url-parameter you now see what url actually triggered this rule to match. This screencast shows you a similar version working with a sneaky rewriterule that is working away on the url.
#A way of finding out what is -actually- matched
RewriteCond %{REQUEST_URI} \.(html|htm|feed|pdf|raw)$ [NC]
RewriteCond %{REQUEST_URI} !/foo
RewriteRule (.*) /foo?url=$1 [R,L]
You can decide to match the %{THE_REQUEST} variable instead. This will always contain the request itself. If something else is rewriting the url, this variable doesn't change, meaning you can use this to overwrite any changes. Make sure the url won't be matching itself. You would get something like below. An example screencast can be found here.
#If it doesn't end on .html/htm/feed etc, this one won't match
RewriteCond %{THE_REQUEST} ^(GET|POST)\ /.*\.(html|htm|feed|pdf|raw)\ HTTP [NC]
RewriteCond %{REQUEST_URI} !^/index2\.php$
RewriteRule (.*) /index2.php [L]
i have a little issue that some of you may be able to sort please
in my htaccess i have
RewriteRule apply /index.php?option=com_loans&view=apply&Itemid=102 [R=301,L,QSA]
basically meaning any get requests to apply will be sent on
however i have a page apply.html which with the above is no longer accessible as it creates a redirect loop
anyone know how to change the htaccess declaration so as only apply (and not apply.html) forwards on ?
tnx
Try to add a rewrite condition as well as limiting the matching pattern in the regex:
The condition will make sure that the rule will only be applied if the request isn't for an existing file.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^apply$ /index.php?option=com_loans&view=apply&Itemid=102 [R=301,L,QSA]
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.
We've just finished a major re-structuring our website and I'm trying to write a set of redirect rules of varying specificity. The redirects are half working:
They correctly re-route old URLs
They incorrectly also allow and re-route URLs that include text not specified in the
ReWriteCond statements (when instead I would expect to see a "Not Found" error message displayed in the browser.)
Statements in the .htaccess file (located in the root of the web site) include:
RewriteBase /
RewriteCond %{REQUEST_URI} /company/company-history.html
RewriteRule (.*)$ http://www.technofrolics.com/about/index.html
RewriteCond %{REQUEST_URI} /press
RewriteRule (.*)$ http://www.technofrolics.com/gallery/index.html
The above correctly executes the desired redirect
but also works when I enter the following after the domain name:
/youcanenteranytext/hereatall/anditstillworks/press
In other words, any text following the domain and preceding the conditional string seems to be allowed/ignored. Any advise on how to restrict the condition or rewrite rule to prevent this would be much appreciated!
Thanks, Margarita
You need to including bounds in your regular expressions when you try to match against %{REQUEST_URI}, the ^ indicates the beginning of the match.
RewriteCond %{REQUEST_URI} ^/company/company-history\.html
Will make it so requests for /garbage/stuff/comapny/company-history.html won't match. And likewise:
RewriteCond %{REQUEST_URI} ^/press
Will make it so requests for /youcanenteranytext/hereatall/anditstillworks/press won't match. You can additionally employ the $ in your regular expression to indicate the end of the match, so something like this:
RewriteCond %{REQUEST_URI} ^/press$
Will ONLY match requests for /press and not /something/press or /press/somethingelse or /press/.