Options -Indexes
RewriteEngine on
Options +FollowSymLinks
RewriteRule ^$ 2012/index.php [L]
RewriteCond %{DOCUMENT_ROOT}/2012%{REQUEST_URI} -f
RewriteRule .* 2012/$0 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* 2012/index.php$0 [QSA] #<-- this is wrong here, and gives 500 error
I am trying to server all my urls from the 2012 subfolder.
I tried the above script, and it fails for urls like:
index.php/admin/controller/action?id=123
which should be resolved from the subfolder
2012/index.php/admin/controller/action?id=123
what is wrong?
I'm going to guess that the URI /index.php/admin/controller/action?id=123 fails the -f test for %{DOCUMENT_ROOT}/2012%{REQUEST_URI}, and is instead getting rounded up by the last rule: RewriteRule .* 2012/index.php?q=$0 [QSA], turning the URI into /2012/index.php?q=index.php/admin/controller/action&id=123. You'll have to add a special case for this because the first condition/rule allows the existing files to be rewritten as-is, and the last condition/rule acts as a "catch-all" (and the very first rule is simply for the special case when the request URI is /). Try something like this:
RewriteRule ^$ 2012/index.php [L]
RewriteCond %{REQUEST_URI} ^/index\.php [OR]
RewriteCond %{DOCUMENT_ROOT}/2012%{REQUEST_URI} -f
RewriteRule .* 2012/$0 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* 2012/index.php?q=$0 [QSA]
The new condition RewriteCond %{REQUEST_URI} ^/index\.php [OR] will be satisfied if a request is made starting with /index.php and the URI gets rewritten as-is into the /2012/ directory. The [OR] ensures the previous condition of a direct access be honored.
Related
I need help with .htaccess Rewrite rules.
I have a API which can be accessed over http://api.my.domain/products/all which is working fine and is returning result.
I would like to redirect users coming to http://api.my.domain/admin to admin folder.But it is not working with current rules.
I have added this to .htaccess but it is not working correctly for admin folder.
RewriteEngine On
RewriteCond %{Request_Filename} !-F
RewriteCond %{Request_Filename} !-d
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^admin admin/index.php [QSD,L]
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^ public/index.php [QSD,L]
This is the result I get when I enter http://api.my.domain/admin and is breaking all my php redirects:
http://api.drezga.hr/admin/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/admin/admin/checklogin.php
Can someone, please, tell me what I'm doing wrong? I have spent hours and I can't see it.
Aside: If /admin is a physical directory then you should be requesting /admin/ (with a trailing slash) to begin with, otherwise Apache/mod_dir will issue a 301 redirect to append the trailing slash.
RewriteCond %{Request_Filename} !-F
RewriteCond %{Request_Filename} !-d
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^admin admin/index.php [QSD,L]
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^ public/index.php [QSD,L]
The first two conditions (RewriteCond directives) are being applied incorrectly to the first rule only. They need to apply to the last rule (the rewrite to public/index.php) then the rewrite to admin/index.php is not necessary (this should be handled by the DirectoryIndex).
There's no need for the QSD flag since you are checking that the query string is already empty - there is no query string to discard!
You should probably be using the -f operator on the condition, not -F (which uses subrequests and is consequently less efficient).
Try the following instead:
DirectoryIndex index.php
RewriteEngine On
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Optimisation (prevent additional filesystem check)
RewriteRule ^public/index\.php$ - [L]
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . public/index.php [L]
RewriteRule ^$ public/index.php [L]
The RewriteCond %{REQUEST_FILENAME} !-d directive prevents requests for /admin/ being passed to public/index.php.
The additional RewriteRule at the end is to rewrite requests for the root directory, which would otherwise be omitted because of the condition mentioned above. This could be avoided by extending the DirectoryIndex directive instead, although this could change the behaviour if you have other directories that need to be accessible (or should not be routed to public/index.php). For example:
DirectoryIndex index.php /public/index.php
I have made sure that rewrite engine is enabled and removing .php extensions is working so I know that isn't the issue.
what I'm trying to do is simply remove the ?id=value aspect of the URL, so basically making the URL look like such:
folder/medias/value
Instead of
folder/medias?id=value
My current .htaccess looks like this:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [NC,L]
RewriteRule ^404/?$ /404.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^ 404.php [L,R]
With your shown samples/attempts, please try following htaccess Rules. Please make sure to clear your browser cache before testing your URLs.
RewriteEngine ON
##Rules for external rewrite.
RewriteCond %{THE_REQUEST} \s/([^.]*)\.php\?id=(\S+)\s [NC]
RewriteRule ^ /%1/%2? [R=301,L]
##Rule for internal rewrite.
RewriteRule ^([^/]*)/([^/]*)/?$ $1?id=$3 [L]
You may try this code inside the /folder/.htaccess (create this file if it doesn't exist):
RewriteEngine On
# External redirect from /folder/media?id=val to /folder/media/val
RewriteCond %{THE_REQUEST} /(\S+?)\.php\?id=([^&\s]+)\s [NC]
RewriteRule ^ /folder/%1/%2? [R=301,L,NE]
# Internal rewrite from /folder/media/val to /folder/media?id=val
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([\w-]+)/([\w-]+)/?$ $1.php?id=$2 [L,QSA]
Trailing ? in first rule is to remove query string from original URL.
%{REQUEST_FILENAME} !-f and %{REQUEST_FILENAME} !-d is to skip existing files and directories from rewrite in 2nd rule.
I have an .htaccess file like this:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^foo.*$ /cgi/foo.cgi [L]
RewriteRule ^.*$ /cgi/fallback.cgi [L]
but when I go to a URL starting with foo in that folder, the browser still gets redirected to the fallback.cgi script. If I remove the second rule, the 'foo' line works OK.
According to my understanding, the first rule should take precedence, and the [L] should prevent any other rules from happening.
You are right, the 1st rule should be applied first and I think it is. The problem might be the 2nd rule is also being applied, so the code should be like this:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^foo.*$ /cgi/foo.cgi [L,NC]
RewriteCond %{REQUEST_URI} !/cgi/(foo|fallback)\.cgi [NC]
RewriteCond %{REQUEST_URI} !/foo [NC]
RewriteRule ^.*$ /cgi/fallback.cgi [L]
The ^ means beginning of string.
RewriteRule ^foo.*$ /cgi/foo.cgi [L]
So that rules ONLY matches /foo followed by zero or more characters.
To match a file beginning with "foo" use this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (^|/)foo.*$ /cgi/foo.cgi [L]
It matches:
/foo
/foo.php
/food.php
/foolish/dog
It does not match:
/kung-foo.cat
/FOO.php
Update
Remember that some browsers do redirect caching. I was testing this on my own server and had performed a redirect that was cached. Made me confused for a bit when my new rules weren't working.
It is applying 2nd rule because;
In 2nd rule your are matching .* (means everything)
RewriteCond lines are only being applied to 1st rule only
Correct code would be:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
# don't do anything for a file, dir or symlnk
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} !-d [OR]
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^ - [L]
RewriteRule (^|/)foo /cgi/foo.cgi [L,NC]
RewriteRule ^ /cgi/fallback.cgi [L]
I'm sure this has been answered, I've been reading for a few hours now and am getting nowhere. I need this to work tonight and my brain is hurting, so I'm asking the the wonderful internet for help.
I'm trying to run all my pages through index_new.php (it all made sense when I decided to do that, I swear). I have two types of pages, static and dynamic. The dynamic pages are all the same kind of page, but with different data based on the database (MySQL). I'm trying to make these rewrites
/about => index_new.php?page=about
/installations => index_new.php?page=about
/installations/{site_id} => index_new.php?page=site&siteID={site_id}
(I'd love if about could be generic, but I don't want to push my luck) My .htaccess file is:
# enable rewrite
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
# rewrite all physical existing file or folder
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} !-d
# allow things that are certainly necessary
RewriteCond %{REQUEST_URI} "/statics/" [OR]
RewriteCond ${REQUEST_URI} "/ajax/"
# rewrite rules
RewriteRule ^about index_new.php?page=about
RewriteRule ^/installations index_new.php?page=list
RewriteRule ^/installations/(.*) index_new.php?page=site&id=$1
When I try to go to /about or any other page, I get HTTP 404. As a note, my root is http://localhost/~user/public_html/new and the .htaccess file is there.
Provided:
The conditions in the question have to be met for each rule. (They are repeated as they are valid only for the next rewrite rule).
The .htaccess file is located at root.
You may try this instead of the rule-set in your question:
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /about/?$ [NC]
RewriteRule .* /index_new.php?page=about [NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /installations/?$ [NC]
RewriteRule .* /index_new.php?page=list [NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /installations/([^/]+)/? [NC]
RewriteRule .* /index_new.php?page=site&id=%1 [NC,L]
Maps silently:
http://example.com/about to
http://example.com/index_new.php?page=about
http://example.com/installations to
http://example.com/index_new.php?page=about
http://example.com/installations/Anything to
http://example.com/index_new.php?page=site&Anything
For permanent and visible redirection, replace [NC,L] with [R=301,NC,L].
NOTE:
These conditions in the question were not used as their purpose is not clear:
RewriteCond %{REQUEST_URI} "/statics/" [OR]
RewriteCond ${REQUEST_URI} "/ajax/"
To include them for one or several rules, try this:
# For NOT condition, include the next line before the corresponding rewrite rule:
RewriteCond %{REQUEST_URI} !(statics|ajax) [NC]
# For positive condition, include the next line before the corresponding rewrite rule:
RewriteCond %{REQUEST_URI} (statics|ajax) [NC]
I have a strange problem with mod_rewrite in combination with ColdFusion:
I'm using the following rewrite rules in my virtualhost-configuration:
RewriteEngine On
RewriteRule ^$ index.cfm [L]
# Add trailing slash if missing
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(?i)^[\\/]CFFileServlet
RewriteCond %{REQUEST_URI} !index.cfm
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ $1/ [L,R=301]
# Clean up multiple slashes in URL
RewriteCond %{HTTP_HOST} !=""
RewriteCond %{THE_REQUEST} ^[A-Z]+\s//+(.*)\sHTTP/[0-9.]+$ [OR]
RewriteCond %{THE_REQUEST} ^[A-Z]+\s(.*/)/+\sHTTP/[0-9.]+$
RewriteRule .* http://%{HTTP_HOST}/%1 [R=301,L]
# Pass all non physically existing files/folders to index.cfm in URL.original_url
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/cms/
RewriteRule ^(.*)$ /index.cfm?original_url=$1 [QSA,PT,L]
Everything is working fine except for one thing:
If I call http://www.example.com/test/?asdf my URL.original_url reads like this original_url=/test/index.php&asdf and I can't figure out why there is index.php in it.
I tried already leaving out the PT-flag but it doesn't work without it. All pages e.g. http://www.example.com/test/ return 403 - Forbidden and in title of the page says "JRun Servlet Error".
Thanks for any ideas on this one!
EDIT:
Ok, I missed something important: the folder /test/ actually exists in my documentroot! Other URLs like /test/does_not_exist/ are not affected by the described problem.
Summed up:
http://www.example.com/test/ -> URL.original_url gets /test/index.php
http://www.example.com/test/does_not_exist/ -> URL.original_url gets /test/does_not_exist/ which is my expected behaviour.