Problem in redirection through .htaccess - apache

I have a php generated file like:
http://www.domain.com/?mod=test&act=view
And I want to create a redirection from that address to something like:
http://www.domain.com/view-test
so that everytime a user (or bot) accesses the first uri it gets redirected to http://www.domain.com/view-test viewing the content of the first uri.
Right now I have the following rules under my .htaccess:
RewriteRule ^view-test$ /?mod=test&act=view [NC]
RewriteCond %{QUERY_STRING} mod=test&act=view
RewriteRule ^(.*)$ /view-test? [R,L]
The first rule creates a "page alias" and works if I delete the other two lines (but doesn't redirect my users as i want to)
After placing the last two rules I end up in a Loop or something and I get a broswer message saying "The page is not redirecting correctly"...
If I remove the first rule I get an 404 error saying /view-test could not be found
Any idea what I'm doing wrong?

I think that regex is better. Full .htaccess file for this situation if your php handler is index.php
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} mod=(\w+)&act=(\w+)
RewriteRule ^$ /%2-%1? [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(\w+)-(\w+)$ /index.php?mod=$2&act=$1 [L]

forget about .htaccess it's easier to do it in php,i use it in my site, i created an index.php file to redirect users from example.com to example.com/123
in my index.php i put this
<?php
header('Location: http://example.com/123');
?
>

Related

Folder is not visible in localhost

I have downloaded a web template and when i try to run that in my localhost the folder doesn't show up.that folder contains a .htaccess file.When i remove that file i can see the folder but when i open that it gives some errors.
This is the .htaccess file
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^$ index.php [L]
RewriteRule ^([a-zA-Z0-9]+)?$ user-profile.php?user_username=$1 [NC,L]
this is the first time i'm working with a .htaccess file...
Any help is appreciated.
Maybe problem in the index.php file PHP code? Rewrite rules looks fine.
Show us the Apache error log and a rewrite log, without that hard to say what is wrong.
It looks like the RewriteCond directive is in the wrong place...? I would have thought it should apply to the 2nd RewriteRule, not the first:
RewriteEngine On
RewriteRule ^$ index.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([a-zA-Z0-9]+)?$ user-profile.php?user_username=$1 [NC,L]
RewriteCond directives apply to the single RewriteRule that follows. That 2nd ruleset basically says that if the requested file does not exist then internally rewrite the request to the user-profile.php page passing the request (which is assumed to be a username) to the user_username parameter.

.htaccess get lost query string

I have limited .htaccess knowledge and i am requiring some help. I need to do some redirects to enable pretty urls.
In local all works fine but it is not working in another develpment server. apparently the query string get drop when redirect.
i need to redirect this http://mysite.local/info/permalink/1
to this one http://mysite.local/info?proxy=true&id=1
my .htaccess code:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
#remove /index.php from home url and redirect to root.
#http://mysite.local/index.php -> http://mysite.local/
RewriteCond %{THE_REQUEST} ^.*\/index\.php?\ HTTP/
RewriteRule ^(.*)index\.php?$ "/$1" [R=301,L,QSA]
#pretty url without index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [PT,QSA,L]
#rewrite to handle some permalink saved on my db.
#http://mysite.local/info/permalink/1
#http://mysite.local/info/proxy=true&id=1
RewriteRule ^([^/]+)/info/([a-zA-Z0-9\-]+)/([0-9]+) /info/?proxy=true&id=$3 [L]
</IfModule>
the redirect is working but the query string is not present. When I run var_dump($_GET) on info module i am getting an empty array array(0) {}
i have try it to solve changing
RewriteRule .* index.php [PT,QSA,L]
to RewriteRule ^(.*)$ /%{QUERY_STRING} [L]
and
RewriteRule ^([^/]+)/info/([a-zA-Z0-9\-]+)/([0-9]+) /info/?proxy=true&idobj=$3 [L]
to
RewriteRule ^([^/]+)/info/([a-zA-Z0-9\-]+)/([0-9]+) /info/?proxy=true&idobj=$3 [QSA,NE,L]
Server API is CGI/FastCGI
What should I change to ensure that my rewrite works as intended and $_GET variables still are accessible?
thx in advance
I have no idea how you've managed to get this to work with a regex pattern like: ^([^/]+)/info if the URL you are going to is /info/permalink/1.
The ^([^/]+)/info pattern means there's stuff before the /info part of the URI, which there isn't. Additionally, in an htaccess file, the URI's have the leading forward slash stripped off. So you probably want something like this:
RewriteRule ^info/([a-zA-Z0-9\-]+)/([0-9]+) /info/?proxy=true&id=$2 [L]

Can't get mod_rewrite to correctly (and invisibly) re-write my URLs?

I'm trying to make a URL shortening service for my website.
So instead of:
http://www.myfullwebsitename.com/page78/this-is-a-headline/
users will be able to visit:
http://abc.de/aBxf
which needs to redirect (invisibly!) to
http://abc.de/?shorturl=aBxf
which then 301 redirects via a database lookup to
http://www.myfullwebsitename.com/page78/this-is-a-headline/
I can do the DB lookup and the 301 redirect easily. It's the invisible intermediate redirect that I'm struggling with.
I've tried a LOT of different things, but none seems to work. This is what I currently feel should work:
RewriteCond %{HTTP_HOST} ^abc.de
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^/(.+) /?shorturl=$1
But instead of redirecting silently to
http://abc.de/?shorturl=aBxF
it redirects "noisily" (302) to
http://abc.de/aBxF/?shorturl=aBxF
What am I doing wrong?
Thank you!
There's a few things you can try.
I think your RewriteRule should look like this (without the forward /):
RewriteRule ^/(.+) ?shorturl=$1 [L]
This should at the very least stop it from redirecting to http://abc.de/aBxF/.
Your original rule may work if you add:
RewriteBase /
If it were me my rules would actually look like this:
RewriteBase /
RewriteCond %{HTTP_HOST} ^abc.de$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /redirect.php [L]
And then in PHP I would use $_SERVER['REQUEST_URI'] to get the URL (not sure what language you're using).
The rule can look like this:
RewriteRule ^(.*)$ /redirect.php?shorturl=$1 [L]
But I would make sure to mention the script by name. Part of what may be throwing your rules off is relying on Apache finding your index file after a rewrite.
The way Apache's rewrite rules work is as soon as the URL is rewritten, it actually will re-run the rules until no other rules will be found. The [L] flag for "last" says "stop here" - but it still starts over from the top. The RewriteCond with the !-f flag says "only if the file doesn't exist".
Use an absolute URL:
RewriteCond %{HTTP_HOST} ^abc.de
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^(.*)$ http://abc.de/?shorturl=$1 [R=301,L]

.htaccess rewrite to simultaneously change domain and remove path

My URL structure is currently as follows:
http://domain.com/folder/filename (CURRENT)
I want to change this so that I can use the following URL instead:
http://sub.domain.com/filename (NEW)
So accessing the CURRENT or the NEW url, should load the file located at the CURRENT url, but show the NEW url in the address bar. It should only apply to the "/folder/" path.
sub.domain.com is a mirror of domain.com, ie. they share the same file system and root directory.
This is what I have so far:
Options +FollowSymLinks
RewriteBase /
RewriteCond %{HTTP_HOST} ^(www.)?domain.com$ [NC]
RewriteCond %{REQUEST_URI} ^/folder/?(.*)$ [NC]
RewriteRule ^(.*)$ http://sub.domain.com/$1 [R=301,L]
This is working, but is missing the rule to remove the "/folder/" from the path. I've tried combining multiple RewriteRule's with no luck. Any ideas? Thanks.
UPDATE: Thanks again #Gerben - I understand what your rules are doing now, but the second one isn't working for me. I suspect because it's conflicting with some other rewrite rules, in particular those of WordPress, which are lower down in my .htaccess file:
# BEGIN WordPress
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
Because of this the page ends up in a redirect loop, ie (from Chrome):
"The webpage at http://sub.domain.com/folder/index.php has resulted in too many redirects." - while the url I was originally trying to access was, for example, http://sub.domain.com/page
Any ideas?
Try:
RewriteCond %{HTTP_HOST} ^(www.)?domain.com$ [NC]
RewriteRule ^(folder/)?(.*)$ http://sub.domain.com/$2 [R=301,L]
This will redirect everything to sub.domain.com, and remove the /folder part of the URI if it is there. If not, it redirects and leaves the URI untouched.
RewriteCond %{THE_REQUEST} /folder/
RewriteRule ^folder/(.*)$ http://sub.domain.com/$1 [R=301,L]
RewriteCond %{HTTP_HOST} ^sub\.domain\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/folder/
RewriteRule ^(.*)$ folder/$1 [L]
# WordPress rules here
edit the second R=301 should not have been there
But this won't work, as wordpress has no way of knowing you want folder. You could add the Proxy flag to the rewrite, but then you need to change the rule above to not redirect on this internal proxy request.

mod_rewrite: allow redirect but prevent direct access

I am currently using mod_rewrite to do an internal redirection
RewriteCond %{REQUEST_URI} ^/pattern$
RewriteRUle .* file.php
However I would like to prevent direct access to file.php by redirecting requests to that file to a page not found URL.
RewriteCond %{REQUEST_URI} /file.php
RewriteRule .* page-not-found.php
The problem is that the second rule also applies when I do the first redirect and therefore breaks my first internal redirect.
[Q] Is there a way to allow the first redirect but prevent direct access to the redirected file?
Using ENV:REDIRECT_STATUS variable (see mromaine's contribution to "Hidden features of mod_rewrite" community wiki:
RewriteCond %{REQUEST_URI} ^/pattern$
RewriteRule .* file.php
# Redirect direct access to file.php
RewriteCond %{REQUEST_URI} /file.php
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule .* page-not-found.php
Test cases:
http://example.com request gets server's index file (index.htm, index.php, etc.)
http://example.com/somefile.htm request gets somefile.htm
http://example.com/somedir request gets somedir's index file
http://example.com/pattern request gets file.php file
http://example.com/file.php request gets page-not-found.php file
Every HTTP responses are HTTP 200.
Edit: Inspired by #AndrewR's answer (which in its current form however didn't seem to work for me - it looks like the second rule gets applied anyway.) a .htaccess only solution that works with a secret key.
If you encounter a valid pattern, add a secret key to the query string.
Then test for that secret key when deciding upon the page redirect.
RewriteEngine on
Options +FollowSymlinks
RewriteCond %{REQUEST_URI} ^/pattern$
RewriteRule .* /file.php?SUPER_SEKRIT_KEY [QSA]
RewriteCond %{QUERY_STRING} !SUPER_SEKRIT_KEY
RewriteCond %{REQUEST_URI} /file.php
RewriteRule .* /test/page-not-found.php [L,F]
Use a more complex key of course, and for internal redirects only! Otherwise, the user will be able to grab the secret key.
You can add a [L] at the end of the rewrite rule, which signifies Last, or no more processing. This will only work inside the Apache config. It does not work in an .htaccess file.
RewriteEngine On
RewriteCond %{REQUEST_URI} pattern$
RewriteRule .* /file.php [L]
RewriteCond %{REQUEST_URI} file.php$
RewriteRule .* /page-not-found.php [L]
A simpler way to do this only using .htaccess.
Move your file.php into a new directory called securedir. In the root directory use this .htaccess file.
RewriteEngine On
RewriteRule ^pattern$ securedir/file.php
Prevent access to anything in securedir with this in an .htaccess file there. (Or direct them back to a different page if you prefer.)
deny from all