I have rewrite rules in a htaccess file working perfectly except for one weird issue that is not redirecting to the index.php like it should.
apache2 running on Debian
site.com/abc/xyz processes through site.com/index.php like it should
site.com/somethingelse/folderx/1234 processes through site.com/index.php like it should
site.com/accounts/ processes through site.com/index.php like it should
BUT
site.com/accounts/orders/1234 processes straight to site.com/accounts/orders.php without going to root/index.php like it is supposed to.
rewrite rules in htaccess:
RewriteRule \. - [L]
RewriteRule (.*)$ index.php [L]
Is there a simple reason that I am not seeing?
It looks as if you have Multiviews turned on. It's part of content negotiation and can cause apache to do unexpected stuff like what you're describing with /orders/ -> /orders.php. Try turning it off:
Options -Multiviews
RewriteRule \. - [L]
RewriteRule (.*)$ index.php [L]
Related
Since we migrated to a new server, some of our pages are broken (404). Reason is we have 2 broken rewrite rules.
What's really strange is that they work if I change folder's name.
For example this work:
RewriteRule ^anything/([a-zA-Z0-9-]+)/$ page.php?var=$1 [L]
This doesn't:
RewriteRule ^myfolder/([a-zA-Z0-9-]+)/$ page.php?var=$1 [L]
I can't even find a trick to make 301 redirects, because my original "myfolder/" virtual folder never matches.
Any ideas what's going on? I was thinking it could be a rule override or something like that (as it's hosted on a multidom solution), but i don't have such rules in my main site at the root. It drives me crazy.
Thx!
In practice you probably want to do 2 things. Disable multiviews and also bypass rules if the request is a real directory.
Options -MultiViews #turn off automatic URI matching, can cause weirdness
RewriteEngine on
#stop here if the request is a real file or directory
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^myfolder/([a-zA-Z0-9-]+)/?$ /page.php?var=$1 [L]
Server is Apache 2.4.18, PHP ver 7.0...
Intro:
On php side I rawurlencode($name) when creating html link.
REQUEST_URI looks like this:
/lang/cat1/cat2/product with bla (this/that) -- works
/lang/cat1/cat2/product with bla (this/ that) -- infinite internal redirect
The difference is only in one space this/ that vs. this/that
VirtualHost:
# I have tried different combinations of
AllowEncodedSlashes On
AllowEncodedSlashes NoDecode.
htaccess:
<IfModule mod_rewrite.c>
Options +FollowSymLinks -MultiViews #different combinations
RewriteEngine On
# tried different combinations
#RewriteCond %{REQUEST_URI} !^/?file\.php$
#RewriteCond %{ENV:REDIRECT_STATUS} ^$
#RewriteCond %{ENV:REDIRECT_STATUS} !200
RewriteRule .? file.php [L] # END
</IfModule>
All I want is standard front controller, ALL requests should go to file.php That works in 99.99% of cases. But ruri with bla/ in it goes to infinite recursions.
Questions:
Why is this happening?
How to solve it?
You need to uncomment your last rewrite condition.
Try :
<IfModule mod_rewrite.c>
Options +FollowSymLinks -MultiViews #different combinations
RewriteEngine On
# tried different combinations
#RewriteCond %{REQUEST_URI} !^/?file\.php$
#RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{ENV:REDIRECT_STATUS} !200
# END
</IfModule>
Otherwise your rule will redirect /file.php to itself.
On apache 2.4 you can simply use END flag to terminate the rewrite processing :
RewriteEngine on
RewriteRule .? file.php [END]
I have found a solution on another forum.
Solution was painfully simple. But might help someone.
One guy sad: Be brave, understand that there is nothing wrong with your htaccess! But you still have recursions. So bug is somewhere in php code.
That destroyed my htaccess fixation allowing me to dive into business and fw code. Bug was found few hours later. One of url functions had premature rawurldecode(). Cool for lazy programin, not so cool if you have products with encoded / in names.
But the answer to question "Did this work before?" was misleading also. "Yes, sure. It must be because of resent migration."
Riiight ;)
I'm facing a strange issue with mod_rewrite RewriteRule in .htaccess.
Here's my minimal .htaccess file:
RewriteEngine On
RewriteRule ^phpinfo phpinfo.php [L]
The above Rewrite results in 404 Not Found. However, suffixing anything to ^phpinfo works which is unintended and undesired.
RewriteEngine On
RewriteRule ^phpinfophp phpinfo.php [L]
Please help me with making the actual RewriteRule work.
Thanks,
Shyam Singh
RewriteRule ^phpinfo phpinfo.php [L]
MultiViews often causes problems in instances likes this, because its job is to detected slightly misspelled URLs, multiple possible file matches (different extensions, etc.) and correct them – and it interferes here, because it sees a request for phpinfo and finds a corresponding file phpinfo.php
Deactivate it using Options -MultiViews, that should fix the problem.
I have recently moved to a new server for my website, and i activated mod_rewrite with success, but some files still not working !
Like this one:
RewriteRule ^activate\/(.*)\/(.*)$ activate.php?Email=$1&hash=$2
I have made all necessary changes on my VPS (Ubuntu) !
Any idea ?
Like this lines work well:
RewriteRule ^search\/(.*)\/([a-zA-Z0-9_-]+)$ search.php?view=$1&p=$2
RewriteRule ^search$ searchResults.php
RewriteRule ^term$ term.php
RewriteRule ^faq$ faq.php
# Non-working line...
RewriteRule ^activate\/(.*)\/(.*)$ activate.php?Email=$1&hash=$2
Note that mod_rewrite are enabled and all other lines work well only this one !
First thing, you must define a RewriteBase because of your two rules (first and last) that create both virtual directories.
Then, you should disable MultiViews option to make term or faq rule work without problem.
Finally, you can rewrite your patterns in a more generic way (or at least in a better way, more precise). Also, don't forget L flag ([L]) after each rule, otherwise mod_rewrite continues to evaluate next rules.
You can replace your current code in your htaccess by this one (assuming your htaccess is in root folder)
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteRule ^search/([^/]+)/([^/]+)$ search.php?view=$1&p=$2 [L]
RewriteRule ^search$ searchResults.php [L]
RewriteRule ^term$ term.php [L]
RewriteRule ^faq$ faq.php [L]
RewriteRule ^activate/([^/]+)/([^/]+)$ activate.php?Email=$1&hash=$2 [L]
I've tried every single example I could find, they all produce an internal server error. I have these rules set up (this works, no error):
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}/index.php !-f
RewriteRule ^((/?[^/]+)+)/?$ ?q=$1 [L]
So if it's not an existing file or an existing directory with an index.php we redirect. For instance, http://domain.com/foo/bar becomes http://domain.com/?q=foo/bar
Thing is, I want the trailing slash stripped. So take off the /? at the end of the rule. How do I make it so that http://domain.com/foo/bar/ becomes http://domain.com/foo/bar with a visible redirect first (fixing the client's URL), and only then the real, silent redirection to ?q=?
Everywhere I look I see this:
RewriteRule (.*)/$ $1 [R,L]
But it gives me a 500 error if I insert it before my rule.
If foo/bar exists as a real directory, then the server will be redirecting the client to foo/bar/ (with the trailing slash). It has to do that in order for relative URLs to work correctly on the client. If you put in a rule to rewrite that back to foo/bar with a redirect then there will be a loop. An easy way to test if that's happening is to specify a path that doesn't exist at all (I assume from your index.php detection that the directory tree actually exists). The nonexistent path won't trigger the built-in redirect.
If I setup a similar set of rules to yours (plus the suggested slash-removal rule) I can see the difference between a directory that exists and one that doesn't. The ones that don't work as expected, the ones that do cause Firefox to say This page isn't redirecting properly. IE8 says something similar. Perhaps the Apache setup you're using can detect it and turns it into the 500 error?
It looks like the simpler rewrite rule you mention at the end of your question should work. The problem is, the 500 error isn't really helpful in figuring out why it's not working. One way I've found useful in helping debug mod_rewrite errors is to enable it's logging. Add the following to your httpd.conf:
RewriteLog "/usr/local/var/apache/logs/rewrite.log"
RewriteLogLevel 3
Then try again, and look in the log to see what's going on. Once you're done, you can disable the log be setting the rewriteloglevel 0. See the mod_rewrite docs for details.
Try this rule in front of your current rule:
RewriteRule (.*)/$ /$1 [R,L]
Try these rules:
#prevent mod_dir from adding slash
DirectorySlash Off
#redirect /folder/ to /folder
RewriteCond %{THE_REQUEST} ^GET\s\S+/(\?\S+)?\s [NC]
RewriteRule ^(.*)/$ /$1 [R=301,L,QSA]
#internal redirect for directories
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^(.*)$ /$1/ [L]