Here are the rewriterules for .htaccess. But I am facing a problem.
Here is my .htaccess file.
RewriteEngine On
RewriteBase /dashboard/sample_proj/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule t([\d]+)/ threads/$1/ [R=301]
RewriteRule f([\d]+)/ forums/$1/ [R=301,L]
RewriteRule t([\d]+)-([\d]+)/ threads/$1/page-$2 [R=301,L]
RewriteRule t([\d]+)/#post([\d]+) threads/$1/#post-$2 [R=301,L]
But this is a problem because there is a priority conflict between the urls.
For Example
https://www.url.com/t3550/#post44859
redirects to https://www.url.com/threads/3550/#post44859 but should instead should redirect to https://www.url.com/threads/3550/#post-44859 (this is because there is a conflict between the first and the fourth rule).
Fragments, the things after #, are not sent to the server. They're purely local in the browser, and only evaluated by the browser. A rule matching on # can never match, because the server will never get to see a URL fragment.
Related
I've a problem with some rewrite rules for my URL, I'm using this rule to remove .php from the URL of my website
Options +SymLinksIfOwnerMatch
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
RewriteCond %{REQUEST_URI} ^(.*)//(.*)$
RewriteRule . %1/%2 [R=301,L]
The problem is that when added a trailing slash at the end, the website gives back an error.
Example:
example.com/test/ gives back an error
I do think that's because it rewrites it like example.com/test/.php, I do not know how to properly solve that
I do think that's because it rewrites it like example.com/test/.php
Yes, that is what's happening. But it will do this repeatedly (causing a rewrite-loop) until the server "breaks" with a 500 Internal Server Error.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
The "problem" with this is that you aren't necessarily testing the existence of the same file in the RewriteCond directive that you are rewriting to in the RewriteRule directive.
So, this will cause an error (rewrite-loop / 500 Internal Server Error) when appending a slash because REQUEST_FILENAME is /abs/path/to/test (the resolved filesystem path) and /abs/path/to/test.php exists, but it internally rewrites the request to test/.php because $1 is test/ (captured from the URL-path). It will do this repeatedly until the server aborts with an error.
You need to make sure you are always testing the same thing in the condition as you are rewriting to later.
See my answer to the following question on ServerFault with a detailed explanation of this behaviour: https://serverfault.com/questions/989333/using-apache-rewrite-rules-in-htaccess-to-remove-html-causing-a-500-error
Additional points...
You are missing the L flag, so processing continues on to the next rule.
The first condition that checks the request does not map to a directory is not required, since you are already checking that <whatever>.php exists as a file.
Minor point, but there is no need to backslash-escape a literal dot in the TestString (1st argument to the RewriteCond directive) - this is not a regex.
For example, use the following instead:
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule (.*) $1.php [L]
Now, %{DOCUMENT_ROOT}/$1.php in the RewriteCond directive refers to the same string/file as $1.php in the substitution string.
So, when you request /test/, it will now be testing /abs/path/to/test/.php in the RewriteCond directive, which doesn't exist, so nothing happens (results in a 404). /test and test/ are, after all, different URLs.
Aside:
RewriteCond %{REQUEST_URI} ^(.*)//(.*)$
RewriteRule . %1/%2 [R=301,L]
This redirect is in the wrong place. It should be the first rule, not the last.
I have a multilanguage website. I want the URL's to be like: http://example.com/en/blog_post/2 where blog_post is the name of the file blog_post.php and 2 is value of the parameter id.
I have this .htaccess code now
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^(bg|en)/(.*)$ /$2?lang=$1 [L]
RewriteRule ^(bg|en)/(.*)/([^/.]+)$ /$2?lang=$1&id=$3 [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) $1.php [L]
I tried with this line, but it doesn't work:
RewriteRule ^(bg|en)/(.*)/([^/\.]+)$ /$2?lang=$1&id=$3 [L]
Can you help me please :)
I did it. It works with these lines. Thanks to everyone :)
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^(bg|en)/post/([^/\.]+)$ blog_post.php?lang=$1&id=$2 [L]
RewriteRule ^(bg|en)/(.*)$ $2?lang=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) $1.php [L]
As mentioned above, the order of these directives is important. The more specific rules should come before the more general rules and this is a key problem with the above. However, the pattern also needs to be changed (made more specific) to prevent other malformed URLs triggering a 500 Internal Server Error and breaking your site. eg. /en/blog_post/2/3 (an additional - erroneous - /something) would still trigger a 500 error in the "fixed" code above.
So, this could be written as:
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^(bg|en)/([^/.]+)$ /$2?lang=$1
RewriteRule ^(bg|en)/([^/.]+)/([^/.]+)$ /$2?lang=$1&id=$3
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule (.*) /$1.php [L]
The generic (.*) pattern has been replaced with ([^/.]+) to only match path segments (excluding a slash). By doing this it also means that the order no longer matters and /en/blog_post/2/3 will simply result in a 404.
I've also removed the L flag on the initial RewriteRule directives, since you need to continue anyway to append the .php extension.
The RewriteRule substitutions should also be kept as root-relative, ie. starting with a slash. (Or you should include the RewriteBase directive.)
I've also added another RewriteCond directive to make sure that <file>.php actually exists before appending the file extension. If you don't do this and <file>.php does not exist then you will get another 500 error.
You could combine the two RewriteRules into one if you don't mind having an empty id= parameter (which presumably your script handles anyway):
RewriteRule ^(bg|en)/([^/.]+)(?:/([^/.]+))?$ /$2?lang=$1&id=$3
This handles both /en/blog_post and /en/blog_post/2 requests.
I am looking for some guidance when working with a maintenance mode system, utilised within a .htaccess file, via mod_rewrite and passing a $_GET along with it.
Passing a $_GET in mod_rewrite is perfectly fine under normal circumstances for me, but in this instance I am experiencing issues..
The code I have for the maintenance system is as follows:
RewriteCond %{REMOTE_HOST} !^XX\.XXX\.XXX\.XXX
RewriteCond %{REQUEST_URI} !/maintenance.php$
RewriteCond %{REQUEST_URI} !^/css/.*$
RewriteCond %{REQUEST_URI} !^/assets/.*$
RewriteRule ^$ maintenance.php [R=302,L]
So what I need is the ability to pass a $_GET along with the rewriteRule, thus when the site is viewed as normal by anyone using the allowed IP, I can define that the site is being viewed in maintenance mode.
Of course people not on the allowed IP get redirected to maintenance.php file and don't need this reminder anyway, as the page does that already.
Thank you in advance anyone that can help me in this issue.
EDIT::
# Start the mod re-write conditions #
RewriteRule ^([^/]+)\/$ ?cat=generic&page=$1 [L]
RewriteRule ^products\/([^/]+)\/([^/]+)\/$ ?cat=product&page=$2 [L]
RewriteRule ^theteam\/([^/]+)\/$ ?cat=staff&page=$1 [L]
Thats how I deal with the other links on my page, I hope that is all you needed to see.
Dan.
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !maintenance.php
RewriteCond %{REQUEST_URI} !(css|assets).*$
RewriteCond %{REMOTE_ADDR} !^XX\.XXX\.XXX\.XXX$
RewriteRule (.*) /maintenance.php [R=302,L]
RewriteCond %{REMOTE_ADDR} ^XX\.XXX\.XXX\.XXX$
RewriteRule (.*) $1?mode=maintenance [L,QSA]
This works for me, first you have the negation redirect so whoever tries to access without the allowed IP will go to maintenance.php.
Then you have the append internal redirect, the GET mode=maintenance will not be visible but will be there.
And you can retrieve it with $_GET['mode'].
If you want it to visually append to the query string and only to php files you can use:
RewriteCond %{REMOTE_ADDR} ^XX\.XXX\.XXX\.XXX$
RewriteCond %{REQUEST_FILENAME} \.php$
RewriteCond %{QUERY_STRING} !^mode=maintenance.*$
RewriteRule (.*) $1?mode=maintenance [R,L,QSA]
Update of visible rule for your sub directories format this rule should be placed before it like this:
RewriteCond %{REMOTE_ADDR} ^XX\.XXX\.XXX\.XXX$
RewriteCond %{QUERY_STRING} !.*mode=maintenance.*$
# for visible query string uncomment the below line and comment the next rule
#RewriteRule (.*) $1?mode=maintenance [R,L,QSA]
# for invisible query string
RewriteRule (.*) $1?mode=maintenance [L,QSA]
# Start the mod re-write conditions #
RewriteRule ^([^/]+)\/$ ?cat=generic&page=$1 [L,QSA]
RewriteRule ^products\/([^/]+)\/([^/]+)\/$ ?cat=product&page=$2 [L,QSA]
RewriteRule ^theteam\/([^/]+)\/$ ?cat=staff&page=$1 [L,QSA]
I have simple .htaccess with:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^(?!/static/).+ [NC]
RewriteCond %{REQUEST_URI} ^(?!/media/).+ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?query=$1 [L]
Everything works properly (page/edit, users/show ...), but when I open browser on URL index/something a will get empty $_GET.
Where can be problem please?
Your current rewrite rule doesn't take the case of /index/something into account. If you were to just use /something then it would be redirected to index.php?query=something. Try adding this rule:
RewriteRule ^index/(.*)$ index.php?query=$1 [L]
EDIT:
Based on the comments we're seeing that Apache is using /index as an alias for /index.php. As a temporary workaround until you figure out the needed changes for the Apache configuration you could probably do:
RewriteRule ^index/(.*)$ index.php?query=index/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?query=$1 [L]
Putting that first rule ahead of the RewriteCond lines will catch the /index case and the rest will be caught by your original rules.
It might be an issue with the Server config as "index" might be the default file. So the routing is being done due to the configuration and not due to the htaccess.
Try checking what file names are treated as valid default names by Apache. Also, what happens if you add /index(.*) as a separate RewriteRule?
I have a setup that sets variables for the index page, but it also does the same for directories and I don't want it to do that. Here's my .htaccess file:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/(login|images|favicon\.ico|home|about|sitemap|contactus|termsandconditions|privacypolicy|signup|search|careers|error|css|js) [NC]
RewriteRule ^([a-zA-Z0-9]+)$ index.php?name=$1
RewriteRule ^([a-zA-Z]+)/$ index.php?name=$1
RewriteRule ^([a-zA-Z]+)/([a-zA-Z0-9_]+)$ index.php?name=$1&page=$2
RewriteRule ^([a-zA-Z]+)/([a-zA-Z0-9_]+)/$ index.php?name=$1&page=$2
RewriteRule ^php/$ error/
Now, with this setup, if I type in mysite.com/login it will redirect to the index.php page and set login as the name variable. How do I make it to where it ignores the directories? This is frustrating me and I've looked through this site for over an hour for an answer and can't find a similar question (I might suck at that too, though. haha!).
Also, if you look at the last RewriteRule, you can see that I'm trying to redirect any attempt to access my php/ folder to my error/ folder. This is also not working.
RewriteCond only applies to the immediately following RewriteRule. Also, you can combine lines 3&4, and 5&6 respectively, by using /? on the end, which makes the / optional (regex).
Your file could be similar to this:
RewriteEngine On
#the following line will not rewrite to anything because of "-", & stop rewiting with [L]
RewriteRule ^(login|images|favicon\.ico|home|about|sitemap|contactus|termsandconditions|privacypolicy|signup|search|careers|error|css|js)/?(.*)$ - [L,NC]
RewriteRule ^php/?(.*)$ error/ [L,NC]
RewriteRule ^([^/]+)/?$ index.php?name=$1 [L]
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?name=$1&page=$2 [L]
You may be interested in the Apache Mod_Rewrite Documentation.
RewriteCond %{REQUEST_URI} !^/(login|images|favicon\.ico|home|about|sitemap|contactus|termsandconditions|privacypolicy|signup|search|careers|error|css|js) [NC] !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
to either not execute the rule on a directory or a file
More info on the mod_rewrite documentation pages, search for CondPattern