htaccess - rewritecond issue - apache

I have an htacess file for apache that isn't working properly.
I have a default cactch-all that grabs all requests however it's still catching the matched URL above it (ajax/*). I thought that condition to match urls not containing ajax would stop it but it isn't.
RewriteRule ^ajax/(.*)$ process_lite.php [QSA,L]
RewriteRule ^resources/(.*)$ resources/$1 [L]
RewriteCond %{REQUEST_URI} !\.(css|jpg|js|gif|png)$
RewriteCond %{REQUEST_URI} !^ajax
RewriteRule ^(.*)$ process.php [QSA,L]
Can someone help me out?

It's probably because the first rule matches /ajax/ requests and rewrites it to /process_lite.php, thus the RewriteCond %{REQUEST_URI} !^ajax doesn't match since the URI is now process_lite.php. The regular expression you use won't match anything anyways because REQUEST_URI variable will start with a leading slash. You can try changing the condition to:
RewriteCond %{REQUEST_URI} !^/process_lite.php
Additionally, the "resources" rule doesn't seem to do anything except end rewriting, you could change it to this if that's the goal:
RewriteRule ^resources/ - [L]

Related

How do I Redirect and Show Content with same urls?

I have a maybe simple Problem. I have serveral URLs that needed to be redirected in this way:
if the URL "/abc/" is called, it should show the content located under "xyz.html"
i can do that with
RewriteRule abc$ xyz.html
but "xyz.html" should be 301 redirecting to "/abc" if it is called.
This is my simple problem i am searching for an solution since hours.
it would be easy if its like "test.html" and /test/. i can do it like
RewriteRule ^(.+)\.html$ /$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule !.*\.html$ %{REQUEST_URI}.html [END]
But in my case i have a bunch of URLs with no pattern.
All i tried results to server misconfiguration.
Can you help me with that one sample?
thanks, kanuddel
Could you please try following.
RewriteEngine ON
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/abc/? [NC]
RewriteRule ^(.*) /xyz.html [L]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/xyz\.html/? [NC]
RewriteRule ^(.*) /abc/? [R=301,L]
Detailed Explanation:
Why there is redirection loop with normal rule writing: Question from OP is interesting and contradictory(kind of), why because lets say we write 1st rule to redirect(in backend) from abc url to xyz.html it will work fine. But then when we write our 2nd rule which is to rewrite url from xyz.html to abc/ which is exactly opposite of first rule. Hence it becomes a loop, ASAP 1st rules gets served it reaches out to 2nd rule and it serves it back to 1st rule thus a REDIRECTION INFINITE LOOP(till 50 cycles or so).
How to prevent redirection loop?
First since both rules are exactly opposite of each other so in a normal rule writing it will become a loop, now how could we prevent it to become a loop? Answer is using: RewriteCond(explained in next step)
I have used an ENVIRONMENT VARIABLE named ENV:REDIRECT_STATUS which will have any redirection status in its value. 2 things we need to understand about this variable.
1- Without any request redirection its default value is NULL.
2- Whenever we do a successful redirection its value becomes 200(NON ZERO), which we can make use of in our conditions part.
Detailed explanation of htaccess Rules:
Now coming to the condition explanation part: In RewriteRuleRewriteRule ^(.*) /xyz.html [L] I have NOT done any rewriting of url on browser why because of the THUMB RULE that we always want to show USER FRIENDLY URLs to users, so environment variable ENV:REDIRECT_STATUS will always be ZERO here.
Coming to 2nd RewriteRule now RewriteRule ^(.*) /abc/? [R=301,L] where user already using a user NON-friendly URL so first thing is I need to rewrite URL in browser to user friendly url hence R=301(redirection with permanent flag is used here). Once Redirection happens through this condition, 1st condition will start failing now why because that checks if REDIRECT_STATUS variable is NULL which is NOT after serving redirection from 2nd condition. Hence this is how it prevents loop by this small trick :)
Thanks for the great Explanation!
I tried it with a second URL, where "/xxx/" should show "zzz.html" But this gave me an Misonfiguration. I tried to shorten it like this:
RewriteEngine ON
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/abc/? [NC]
RewriteRule ^(.*) /xyz.html [L]
RewriteCond %{REQUEST_URI} ^/xxx/? [NC]
RewriteRule ^(.*) /zzz.html [L]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/xyz\.html/? [NC]
RewriteRule ^(.*) /abc/? [R=301,L]
RewriteCond %{REQUEST_URI} ^/zzz\.html/? [NC]
RewriteRule ^(.*) /xxx/? [R=301,L]

Apache Redirect // to no //

An email went out with the wrong link (https://www.digitalmarketer.com/digital-marketing/content-marketing-strategy//) and we need to redirect the // to (https://www.digitalmarketer.com/digital-marketing/content-marketing-strategy/) but no matter what I try, the redirect isn't working.
They also want it to be redirected to always have https:///www at the beginning and to never have index.html at the end, so already in the .htaccess file I have:
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteRule ^content\-marketing\-strategy/index\.html$ /digital-marketing/content-marketing-strategy/? [L,R=301]
I've tried adding a new RewriteRule, but this won't work:
RewriteRule ^content\-marketing\-strategy//$ /digital-marketing/content-marketing-strategy/? [L,R=301]
I'm very new to Apache and redirects so any help is much appreciated! Thank you!
Edit: Of note, this is in an .htaccess file inside of the digital-marketing folder (https://www.digitalmarketer.com/digital-marketing/.htaccess) which was done so all the above rules would only apply to the digital-marketing folder.
You can use insert rule at the end of your other rules to strip multiple // into /:
RewriteCond %{THE_REQUEST} //
RewriteRule ^.*$ /digital-marketing/$0 [R=301,L,NE]
Apache automatically strips down multiple // into one inside the pattern for RewriteRule thus captured value $0 will have all // converted into /
You can write a wildcard expression to remove trailing slashes. The below will match any HTTP or HTTPS URL that trails in a forward slash, and remove all trailing forward slashes from that URL:
RewriteRule ^(.*)/+$ $1 [R=301,L]
And more using 301 redirects, see more here: Best Practice: 301 Redirect HTTP to HTTPS (Standard Domain)
Good luck!
I see nothing in the way that the rule is written that would make it not rewrite. However you have multiple rules with the L flag that might stop processing on the rewrite at an earlier point than you are looking for. From the documentation
The [L] flag causes mod_rewrite to stop processing the rule set. In most contexts, this means that if the rule matches, no further rules will be processed.
(https://httpd.apache.org/docs/current/rewrite/flags.html).
You can try this page out http://htaccess.mwl.be/ to test all your rules together. You might have to rewrite them a bit to work with that page, it's not aware of the level your .htaccess file is at so you will have to rewrite all your rules to trigger from the root for example: RewriteRule ^digital\-marketing/content\-marketing\-strategy//$ /digital-marketing/content-marketing-strategy/? [L,R=301]

what is this htaccess rule actually doing

I have this condition and rule and want to know what actually is going on here
RewriteCond %{REQUEST_URI} ^/sitepages/newversion/
RewriteCond %{QUERY_STRING} ^(.*[?|&])page=dynamicpage
RewriteRule ^sitepages/newversion/(.*)$ /pages/oldversion/$1 [L]
Also very interested in a detail explaination of this line
RewriteRule ^sitepages/newversion/(.*)$ /pages/oldversion/$1 [L]
thanks
RewriteCond %{REQUEST_URI} ^/sitepages/newversion/
If the request URL starts with "/sitepages/newversion/",
RewriteCond %{QUERY_STRING} ^(.*[?|&])page=dynamicpage
and the query string contains "page=dynamicpage",
RewriteRule ^sitepages/newversion/(.*)$ /pages/oldversion/$1 [L]
then take the part of the URL after "sitepages/newversion/" and redirect the request to "/pages/oldversion/(the rest of the url)".
For example:
http://domain.com/sitepages/newversion/someleaf?page=dynamicpage
will get redirected to
http://domain.com/pages/oldversion/someleaf?page=dynamicpage
First of all your rule can be rewritten better as this:
RewriteCond %{QUERY_STRING} (?:^|&)page=dynamicpage(?:&|$) [NC]
RewriteRule ^sitepages/newversion/(.*)$ /pages/oldversion/$1 [L,NC]
Now for explanation part.
RewriteCond is matching a URI with query parameter page=dynamicpage
RewriteRule is matching a URI with pattern sitepages/newversion/(.*)$ which will match /sitepages/newversion/abc123 or /sitepages/newversion/foobar
(.*) is capturing group to populate $1 with the value abc123 in my first example.
In target we use /pages/oldversion/$1 that will become /pages/oldversion/abc123 for same example.
NC flag is for no case comparison.
L flag is for Last that makes mod_rewrite run the rewrite loop again.
Reference: Apache mod_rewrite Introduction
Apache mod_rewrite Technical Details

Using .htcaccess to redirect to www. AND add trailing forward slash

I have searched around for a while and had a go at tweaking this file myself and I'm almost there but there is one case which I can't figure out...
How to get both a www. AND a forward slash at the same time
If I type in spectrl.com, it redirects to www.spectrl.com CORRECT - Adds www.
If I type in www.spectrl.com/ebaycalculator it redirects to www.spectrl.com/ebaycalculator/ CORRECT - Adds /
But if I type in spectrl.com/ebaycalculator I get a 404 error when it should go to www.spectrl.com/ebaycalculator/
Here's my .htcaccess file, kept at the root:
RewriteBase /
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://spectrl.com/$1/ [L,R=301]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Thanks
#Kavi
Try this:
RewriteEngine On
RewriteCond "%{HTTP_HOST}" "^(?:www\.)?(.*)" [NC]
RewriteCond "%{REQUEST_URI}" "!/$"
RewriteRule "(.*)" "http://www.%1%/$1/" [R=301,L]
RewriteCond "%{HTTP_HOST}" "!^www\." [NC]
RewriteRule "(.*)" "http://www.%1/$1" [R=301,L]
The first RewriteCond captures the hostname (without any leading www.) in the reference %1. That condition will always succeed.
The second RewriteCond checks for the trailing slash; if not found, the next RewriteRule will be triggered.
That first RewriteRule uses the captured www.-less host name to construct a redirect that includes www. and the training /.
The second stanza will be triggered if the request falls through because it does have a trailing /. It checks for a leading www., and does the same sort of redirect (only without appending a slash, since there's already one there) as the first stanza.
At least, that's how is should work; I haven't tested it. :-)
After removing and re-uploading .htaccess and then clearing the cache, everything seems to be working as intended using my original code in the question.
Hope this will be helpful for someone else.

Apache Redirect problem in .htaccess

I am having problems getring a simple redirect statement to take effect on my Godaddy account. I have the following statements in my .htaccess file:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.mydomain.net$ [NC]
RewriteRule ^(.*)$ http://mydomain.net/$1 [R=301,L]
RewriteCond %{HTTP_HOST} ^mydomain.net$ [NC]
RewriteRule ^/lists/$ / [R=301]
RewriteCond %{HTTP_HOST} ^mydomain.net$ [NC]
RewriteRule ^/blog/$ http://myotherdomain.net/ [R=301]
The 1st redirect ALWAYS work. The 2nd and 3rd ones however, NEVER work. I just get a 404 from the server. The Apache logs do not reveal any useful infomation - just a 404.
Any ideas, anybody?
Your help will be greatly appreciated.
Thanks
Per-directory Rewrites
When using the rewrite engine in .htaccess files the per-directory prefix (which always is the same for a specific directory) is automatically removed for the pattern matching and automatically added after the substitution has been done.
– http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewriterule
So just leave the leading slash out of the pattern.
For simple redirects like that, better use the simple RedirectMatch directives:
RedirectMatch 301 ^/lists/$ http://mydomain.net/
RedirectMatch 301 ^/blog/$ http://myotherdomain.net/
If you insist on using rewriting make sure you add the L flag to your rules.
Apache mod_rewrite Flags says :
You will almost always want to use [R] in conjunction with [L] (that is, use [R,L]) because on its own, the [R] flag prepends http://thishost[:thisport] to the URI, but then passes this on to the next rule in the ruleset, which can often result in 'Invalid URI in request' warnings.
Simply remove the slashs at the beginning. It also might be useful to make the slashs at the end optional.
RewriteCond %{HTTP_HOST} ^mydomain.net$ [NC]
RewriteRule ^lists/{0,1}$ / [R=301]
RewriteCond %{HTTP_HOST} ^mydomain.net$ [NC]
RewriteRule ^blog/{0,1}$ http://myotherdomain.net/ [R=301]
Put the first one last. Once it encounters a redirect match, it runs it and ignores the rest.